qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCHv7 0/9] slirp: Adding IPv6 support to Qemu -net user mode
@ 2015-12-19 21:24 Samuel Thibault
  2015-12-19 21:24 ` [Qemu-devel] [PATCH 1/9] slirp: goto bad in udp_input if sosendto fails Samuel Thibault
                   ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Samuel Thibault @ 2015-12-19 21:24 UTC (permalink / raw)
  To: zhanghailiang
  Cc: Thomas Huth, Li Zhijian, Stefan Hajnoczi, Jason Wang, qemu-devel,
	Vasiliy Tolstov, peter.huangpeng, Gonglei (Arei),
	Stefan Hajnoczi, J. Kiszka, Yang Hongyang, Dave Gilbert

Hello,

This is another respin of IPv6 in Qemu -net user mode.

The following patches first make some refactoring to make current code ready
for IPv6, and do not change the behavior.  The actual IPv6 support will then be
submitted as a separate patch series.

Difference with version 6 is:
- Use error_report instead of printing to stderr
- Drop extra parentheses
- Use nicer-looking sockaddr casts.

All of this has been reviewed by Thomas Huth, thanks!

Here is a summary of the patches:

[PATCH 1/9] slirp: goto bad in udp_input if sosendto fails
[PATCH 2/9] slirp: Generalizing and neutralizing ARP code
[PATCH 3/9] slirp: Adding address family switch for incoming frames
[PATCH 4/9] slirp: Make Socket structure IPv6 compatible
[PATCH 5/9] slirp: Factorizing address translation
[PATCH 6/9] slirp: Factorizing and cleaning solookup()
[PATCH 7/9] slirp: Add sockaddr_equal, make solookup family-agnostic
[PATCH 8/9] slirp: Make udp_attach IPv6 compatible
[PATCH 9/9] slirp: Adding family argument to tcp_fconnect()

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 1/9] slirp: goto bad in udp_input if sosendto fails
  2015-12-19 21:24 [Qemu-devel] [PATCHv7 0/9] slirp: Adding IPv6 support to Qemu -net user mode Samuel Thibault
@ 2015-12-19 21:24 ` Samuel Thibault
  2015-12-19 21:24   ` [Qemu-devel] [PATCH 2/9] slirp: Generalizing and neutralizing ARP code Samuel Thibault
                     ` (7 more replies)
  2015-12-21 15:30 ` [Qemu-devel] [PATCHv7 0/9] slirp: Adding IPv6 support to Qemu -net user mode Eric Blake
  2016-01-11 15:04 ` Samuel Thibault
  2 siblings, 8 replies; 16+ messages in thread
From: Samuel Thibault @ 2015-12-19 21:24 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, zhanghailiang, Li Zhijian, Stefan Hajnoczi,
	Jason Wang, Dave Gilbert, Vasiliy Tolstov, Huangpeng, Gonglei,
	Jan Kiszka, Samuel Thibault, Yang Hongyang, Guillaume Subiron

From: Guillaume Subiron <maethor@subiron.org>

Before this patch, if sosendto fails, udp_input is executed as if the
packet was sent, recording the packet for icmp errors, which does not
makes sense since the packet was not actually sent, errors would be
related to a previous packet.

This patch adds a goto bad to cut the execution of this function.

Signed-off-by: Guillaume Subiron <maethor@subiron.org>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
---
 slirp/udp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/slirp/udp.c b/slirp/udp.c
index fee13b4..ce63414 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -218,6 +218,7 @@ udp_input(register struct mbuf *m, int iphlen)
 	  *ip=save_ip;
 	  DEBUG_MISC((dfd,"udp tx errno = %d-%s\n",errno,strerror(errno)));
 	  icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno));
+	  goto bad;
 	}
 
 	m_free(so->so_m);   /* used for ICMP if error on sorecvfrom */
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 2/9] slirp: Generalizing and neutralizing ARP code
  2015-12-19 21:24 ` [Qemu-devel] [PATCH 1/9] slirp: goto bad in udp_input if sosendto fails Samuel Thibault
@ 2015-12-19 21:24   ` Samuel Thibault
  2015-12-19 21:24   ` [Qemu-devel] [PATCH 3/9] slirp: Adding address family switch for produced frames Samuel Thibault
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Samuel Thibault @ 2015-12-19 21:24 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, zhanghailiang, Li Zhijian, Stefan Hajnoczi,
	Jason Wang, Dave Gilbert, Vasiliy Tolstov, Huangpeng, Gonglei,
	Jan Kiszka, Samuel Thibault, Yang Hongyang, Guillaume Subiron

From: Guillaume Subiron <maethor@subiron.org>

Basically, this patch replaces "arp" by "resolution" every time "arp"
means "mac resolution" and not specifically ARP.

This prepares for IPv6 support.

Signed-off-by: Guillaume Subiron <maethor@subiron.org>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
---
 slirp/mbuf.c  | 2 +-
 slirp/mbuf.h  | 2 +-
 slirp/slirp.c | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/slirp/mbuf.c b/slirp/mbuf.c
index 795fc29..bc942b6 100644
--- a/slirp/mbuf.c
+++ b/slirp/mbuf.c
@@ -91,7 +91,7 @@ m_get(Slirp *slirp)
 	m->m_len = 0;
         m->m_nextpkt = NULL;
         m->m_prevpkt = NULL;
-        m->arp_requested = false;
+        m->resolution_requested = false;
         m->expiration_date = (uint64_t)-1;
 end_error:
 	DEBUG_ARG("m = %p", m);
diff --git a/slirp/mbuf.h b/slirp/mbuf.h
index b144f1c..38fedf4 100644
--- a/slirp/mbuf.h
+++ b/slirp/mbuf.h
@@ -79,7 +79,7 @@ struct mbuf {
 	int	m_len;			/* Amount of data in this mbuf */
 
 	Slirp *slirp;
-	bool	arp_requested;
+	bool	resolution_requested;
 	uint64_t expiration_date;
 	/* start of dynamic buffer area, must be last element */
 	union {
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 35f819a..1d5d172 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -786,7 +786,7 @@ int if_encap(Slirp *slirp, struct mbuf *ifm)
         struct ethhdr *reh = (struct ethhdr *)arp_req;
         struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN);
 
-        if (!ifm->arp_requested) {
+        if (!ifm->resolution_requested) {
             /* If the client addr is not known, send an ARP request */
             memset(reh->h_dest, 0xff, ETH_ALEN);
             memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
@@ -812,7 +812,7 @@ int if_encap(Slirp *slirp, struct mbuf *ifm)
             rah->ar_tip = iph->ip_dst.s_addr;
             slirp->client_ipaddr = iph->ip_dst;
             slirp_output(slirp->opaque, arp_req, sizeof(arp_req));
-            ifm->arp_requested = true;
+            ifm->resolution_requested = true;
 
             /* Expire request and drop outgoing packet after 1 second */
             ifm->expiration_date = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + 1000000000ULL;
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 3/9] slirp: Adding address family switch for produced frames
  2015-12-19 21:24 ` [Qemu-devel] [PATCH 1/9] slirp: goto bad in udp_input if sosendto fails Samuel Thibault
  2015-12-19 21:24   ` [Qemu-devel] [PATCH 2/9] slirp: Generalizing and neutralizing ARP code Samuel Thibault
@ 2015-12-19 21:24   ` Samuel Thibault
  2015-12-19 21:24   ` [Qemu-devel] [PATCH 4/9] slirp: Make Socket structure IPv6 compatible Samuel Thibault
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Samuel Thibault @ 2015-12-19 21:24 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, zhanghailiang, Li Zhijian, Stefan Hajnoczi,
	Jason Wang, Dave Gilbert, Vasiliy Tolstov, Huangpeng, Gonglei,
	Jan Kiszka, Samuel Thibault, Yang Hongyang, Guillaume Subiron

From: Guillaume Subiron <maethor@subiron.org>

In if_encap, a switch is added to prepare for the IPv6 case. Some code
is factorized.

This prepares for IPv6 support.

Signed-off-by: Guillaume Subiron <maethor@subiron.org>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
---
 slirp/slirp.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 48 insertions(+), 13 deletions(-)

diff --git a/slirp/slirp.c b/slirp/slirp.c
index 1d5d172..f8dc505 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -762,20 +762,15 @@ void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
     }
 }
 
-/* Output the IP packet to the ethernet device. Returns 0 if the packet must be
- * re-queued.
+/* Prepare the IPv4 packet to be sent to the ethernet device. Returns 1 if no
+ * packet should be sent, 0 if the packet must be re-queued, 2 if the packet
+ * is ready to go.
  */
-int if_encap(Slirp *slirp, struct mbuf *ifm)
+static int if_encap4(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh,
+        uint8_t ethaddr[ETH_ALEN])
 {
-    uint8_t buf[1600];
-    struct ethhdr *eh = (struct ethhdr *)buf;
-    uint8_t ethaddr[ETH_ALEN];
     const struct ip *iph = (const struct ip *)ifm->m_data;
 
-    if (ifm->m_len + ETH_HLEN > sizeof(buf)) {
-        return 1;
-    }
-
     if (iph->ip_dst.s_addr == 0) {
         /* 0.0.0.0 can not be a destination address, something went wrong,
          * avoid making it worse */
@@ -819,15 +814,55 @@ int if_encap(Slirp *slirp, struct mbuf *ifm)
         }
         return 0;
     } else {
-        memcpy(eh->h_dest, ethaddr, ETH_ALEN);
         memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4);
         /* XXX: not correct */
         memcpy(&eh->h_source[2], &slirp->vhost_addr, 4);
         eh->h_proto = htons(ETH_P_IP);
-        memcpy(buf + sizeof(struct ethhdr), ifm->m_data, ifm->m_len);
-        slirp_output(slirp->opaque, buf, ifm->m_len + ETH_HLEN);
+
+        /* Send this */
+        return 2;
+    }
+}
+
+/* Output the IP packet to the ethernet device. Returns 0 if the packet must be
+ * re-queued.
+ */
+int if_encap(Slirp *slirp, struct mbuf *ifm)
+{
+    uint8_t buf[1600];
+    struct ethhdr *eh = (struct ethhdr *)buf;
+    uint8_t ethaddr[ETH_ALEN];
+    const struct ip *iph = (const struct ip *)ifm->m_data;
+    int ret;
+
+    if (ifm->m_len + ETH_HLEN > sizeof(buf)) {
         return 1;
     }
+
+    switch (iph->ip_v) {
+    case IPVERSION:
+        ret = if_encap4(slirp, ifm, eh, ethaddr);
+        if (ret < 2) {
+            return ret;
+        }
+        break;
+
+    default:
+        /* Do not assert while we don't manage IP6VERSION */
+        /* assert(0); */
+        break;
+    }
+
+    memcpy(eh->h_dest, ethaddr, ETH_ALEN);
+    DEBUG_ARGS((dfd, " src = %02x:%02x:%02x:%02x:%02x:%02x\n",
+                eh->h_source[0], eh->h_source[1], eh->h_source[2],
+                eh->h_source[3], eh->h_source[4], eh->h_source[5]));
+    DEBUG_ARGS((dfd, " dst = %02x:%02x:%02x:%02x:%02x:%02x\n",
+                eh->h_dest[0], eh->h_dest[1], eh->h_dest[2],
+                eh->h_dest[3], eh->h_dest[4], eh->h_dest[5]));
+    memcpy(buf + sizeof(struct ethhdr), ifm->m_data, ifm->m_len);
+    slirp_output(slirp->opaque, buf, ifm->m_len + ETH_HLEN);
+    return 1;
 }
 
 /* Drop host forwarding rule, return 0 if found. */
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 4/9] slirp: Make Socket structure IPv6 compatible
  2015-12-19 21:24 ` [Qemu-devel] [PATCH 1/9] slirp: goto bad in udp_input if sosendto fails Samuel Thibault
  2015-12-19 21:24   ` [Qemu-devel] [PATCH 2/9] slirp: Generalizing and neutralizing ARP code Samuel Thibault
  2015-12-19 21:24   ` [Qemu-devel] [PATCH 3/9] slirp: Adding address family switch for produced frames Samuel Thibault
@ 2015-12-19 21:24   ` Samuel Thibault
  2015-12-19 21:24   ` [Qemu-devel] [PATCH 5/9] slirp: Factorizing address translation Samuel Thibault
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Samuel Thibault @ 2015-12-19 21:24 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, zhanghailiang, Li Zhijian, Stefan Hajnoczi,
	Jason Wang, Dave Gilbert, Vasiliy Tolstov, Huangpeng, Gonglei,
	Jan Kiszka, Samuel Thibault, Yang Hongyang, Guillaume Subiron

From: Guillaume Subiron <maethor@subiron.org>

This patch replaces foreign and local address/port couples in Socket
structure by 2 sockaddr_storage which can be casted in sockaddr_in.
Direct access to address and port is still possible thanks to some
\#define, so retrocompatibility of the existing code is assured.

The ss_family field of sockaddr_storage is declared after each socket
creation.

The whole structure is also saved/restored when a Qemu session is
saved/restored.

This prepares for IPv6 support.

Signed-off-by: Guillaume Subiron <maethor@subiron.org>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
---
 slirp/ip_icmp.c   |  2 ++
 slirp/slirp.c     | 51 ++++++++++++++++++++++++++++++++++++++++++---------
 slirp/socket.c    | 14 +++++++++++---
 slirp/socket.h    | 19 +++++++++++++++----
 slirp/tcp_input.c |  2 ++
 slirp/tcp_subr.c  |  2 ++
 slirp/udp.c       |  4 ++++
 7 files changed, 78 insertions(+), 16 deletions(-)

diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 23b9f0f..58b7ceb 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -170,8 +170,10 @@ icmp_input(struct mbuf *m, int hlen)
 	goto end_error;
       }
       so->so_m = m;
+      so->so_ffamily = AF_INET;
       so->so_faddr = ip->ip_dst;
       so->so_fport = htons(7);
+      so->so_lfamily = AF_INET;
       so->so_laddr = ip->ip_src;
       so->so_lport = htons(9);
       so->so_iptos = ip->ip_tos;
diff --git a/slirp/slirp.c b/slirp/slirp.c
index f8dc505..b900775 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -23,6 +23,7 @@
  */
 #include "qemu-common.h"
 #include "qemu/timer.h"
+#include "qemu/error-report.h"
 #include "sysemu/char.h"
 #include "slirp.h"
 #include "hw/hw.h"
@@ -234,7 +235,7 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork,
 
     slirp->opaque = opaque;
 
-    register_savevm(NULL, "slirp", 0, 3,
+    register_savevm(NULL, "slirp", 0, 4,
                     slirp_state_save, slirp_state_load, slirp);
 
     QTAILQ_INSERT_TAIL(&slirp_instances, slirp, entry);
@@ -1046,10 +1047,26 @@ static void slirp_sbuf_save(QEMUFile *f, struct sbuf *sbuf)
 static void slirp_socket_save(QEMUFile *f, struct socket *so)
 {
     qemu_put_be32(f, so->so_urgc);
-    qemu_put_be32(f, so->so_faddr.s_addr);
-    qemu_put_be32(f, so->so_laddr.s_addr);
-    qemu_put_be16(f, so->so_fport);
-    qemu_put_be16(f, so->so_lport);
+    qemu_put_be16(f, so->so_ffamily);
+    switch (so->so_ffamily) {
+    case AF_INET:
+        qemu_put_be32(f, so->so_faddr.s_addr);
+        qemu_put_be16(f, so->so_fport);
+        break;
+    default:
+        error_report(
+                "so_ffamily unknown, unable to save so_faddr and so_fport\n");
+    }
+    qemu_put_be16(f, so->so_lfamily);
+    switch (so->so_lfamily) {
+    case AF_INET:
+        qemu_put_be32(f, so->so_laddr.s_addr);
+        qemu_put_be16(f, so->so_lport);
+        break;
+    default:
+        error_report(
+                "so_ffamily unknown, unable to save so_laddr and so_lport\n");
+    }
     qemu_put_byte(f, so->so_iptos);
     qemu_put_byte(f, so->so_emu);
     qemu_put_byte(f, so->so_type);
@@ -1169,10 +1186,26 @@ static int slirp_socket_load(QEMUFile *f, struct socket *so)
         return -ENOMEM;
 
     so->so_urgc = qemu_get_be32(f);
-    so->so_faddr.s_addr = qemu_get_be32(f);
-    so->so_laddr.s_addr = qemu_get_be32(f);
-    so->so_fport = qemu_get_be16(f);
-    so->so_lport = qemu_get_be16(f);
+    so->so_ffamily = qemu_get_be16(f);
+    switch (so->so_ffamily) {
+    case AF_INET:
+        so->so_faddr.s_addr = qemu_get_be32(f);
+        so->so_fport = qemu_get_be16(f);
+        break;
+    default:
+        error_report(
+                "so_ffamily unknown, unable to restore so_faddr and so_lport\n");
+    }
+    so->so_lfamily = qemu_get_be16(f);
+    switch (so->so_lfamily) {
+    case AF_INET:
+        so->so_laddr.s_addr = qemu_get_be32(f);
+        so->so_lport = qemu_get_be16(f);
+        break;
+    default:
+        error_report(
+                "so_ffamily unknown, unable to restore so_laddr and so_lport\n");
+    }
     so->so_iptos = qemu_get_byte(f);
     so->so_emu = qemu_get_byte(f);
     so->so_type = qemu_get_byte(f);
diff --git a/slirp/socket.c b/slirp/socket.c
index 1673e3a..bf603c9 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -437,8 +437,8 @@ sowrite(struct socket *so)
 void
 sorecvfrom(struct socket *so)
 {
-	struct sockaddr_in addr;
-	socklen_t addrlen = sizeof(struct sockaddr_in);
+	struct sockaddr_storage addr;
+	socklen_t addrlen = sizeof(struct sockaddr_storage);
 
 	DEBUG_CALL("sorecvfrom");
 	DEBUG_ARG("so = %p", so);
@@ -527,7 +527,13 @@ sorecvfrom(struct socket *so)
 	     * If this packet was destined for CTL_ADDR,
 	     * make it look like that's where it came from, done by udp_output
 	     */
-	    udp_output(so, m, &addr);
+	    switch (so->so_ffamily) {
+	    case AF_INET:
+	        udp_output(so, m, (struct sockaddr_in *) &addr);
+	        break;
+	    default:
+	        break;
+	    }
 	  } /* rx error */
 	} /* if ping packet */
 }
@@ -619,6 +625,7 @@ tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
 
 	so->so_state &= SS_PERSISTENT_MASK;
 	so->so_state |= (SS_FACCEPTCONN | flags);
+	so->so_lfamily = AF_INET;
 	so->so_lport = lport; /* Kept in network format */
 	so->so_laddr.s_addr = laddr; /* Ditto */
 
@@ -645,6 +652,7 @@ tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
 	qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
 
 	getsockname(s,(struct sockaddr *)&addr,&addrlen);
+	so->so_ffamily = AF_INET;
 	so->so_fport = addr.sin_port;
 	if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
 	   so->so_faddr = slirp->vhost_addr;
diff --git a/slirp/socket.h b/slirp/socket.h
index 57e0407..e854903 100644
--- a/slirp/socket.h
+++ b/slirp/socket.h
@@ -31,10 +31,21 @@ struct socket {
   struct tcpiphdr *so_ti;	   /* Pointer to the original ti within
 				    * so_mconn, for non-blocking connections */
   int so_urgc;
-  struct in_addr so_faddr;	   /* foreign host table entry */
-  struct in_addr so_laddr;	   /* local host table entry */
-  uint16_t so_fport;		   /* foreign port */
-  uint16_t so_lport;		   /* local port */
+  union {   /* foreign host */
+      struct sockaddr_storage ss;
+      struct sockaddr_in sin;
+  } fhost;
+#define so_faddr fhost.sin.sin_addr
+#define so_fport fhost.sin.sin_port
+#define so_ffamily fhost.ss.ss_family
+
+  union {   /* local host */
+      struct sockaddr_storage ss;
+      struct sockaddr_in sin;
+  } lhost;
+#define so_laddr lhost.sin.sin_addr
+#define so_lport lhost.sin.sin_port
+#define so_lfamily lhost.ss.ss_family
 
   uint8_t	so_iptos;	/* Type of service */
   uint8_t	so_emu;		/* Is the socket emulated? */
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index 6b096ec..4c3191d 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -374,8 +374,10 @@ findso:
 	  sbreserve(&so->so_snd, TCP_SNDSPACE);
 	  sbreserve(&so->so_rcv, TCP_RCVSPACE);
 
+	  so->so_lfamily = AF_INET;
 	  so->so_laddr = ti->ti_src;
 	  so->so_lport = ti->ti_sport;
+	  so->so_ffamily = AF_INET;
 	  so->so_faddr = ti->ti_dst;
 	  so->so_fport = ti->ti_dport;
 
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index e161ed2..47262db 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -413,6 +413,7 @@ void tcp_connect(struct socket *inso)
             free(so); /* NOT sofree */
             return;
         }
+        so->so_lfamily = AF_INET;
         so->so_laddr = inso->so_laddr;
         so->so_lport = inso->so_lport;
     }
@@ -430,6 +431,7 @@ void tcp_connect(struct socket *inso)
     qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
     socket_set_nodelay(s);
 
+    so->so_ffamily = AF_INET;
     so->so_fport = addr.sin_port;
     so->so_faddr = addr.sin_addr;
     /* Translate connections from localhost to the real hostname */
diff --git a/slirp/udp.c b/slirp/udp.c
index ce63414..7a5c95b 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -190,6 +190,7 @@ udp_input(register struct mbuf *m, int iphlen)
 	  /*
 	   * Setup fields
 	   */
+	  so->so_lfamily = AF_INET;
 	  so->so_laddr = ip->ip_src;
 	  so->so_lport = uh->uh_sport;
 
@@ -202,6 +203,7 @@ udp_input(register struct mbuf *m, int iphlen)
 	   */
 	}
 
+        so->so_ffamily = AF_INET;
         so->so_faddr = ip->ip_dst; /* XXX */
         so->so_fport = uh->uh_dport; /* XXX */
 
@@ -376,6 +378,7 @@ udp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
 	socket_set_fast_reuse(so->s);
 
 	getsockname(so->s,(struct sockaddr *)&addr,&addrlen);
+	so->so_ffamily = AF_INET;
 	so->so_fport = addr.sin_port;
 	if (addr.sin_addr.s_addr == 0 ||
 	    addr.sin_addr.s_addr == loopback_addr.s_addr) {
@@ -383,6 +386,7 @@ udp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
 	} else {
 	   so->so_faddr = addr.sin_addr;
 	}
+	so->so_lfamily = AF_INET;
 	so->so_lport = lport;
 	so->so_laddr.s_addr = laddr;
 	if (flags != SS_FACCEPTONCE)
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 5/9] slirp: Factorizing address translation
  2015-12-19 21:24 ` [Qemu-devel] [PATCH 1/9] slirp: goto bad in udp_input if sosendto fails Samuel Thibault
                     ` (2 preceding siblings ...)
  2015-12-19 21:24   ` [Qemu-devel] [PATCH 4/9] slirp: Make Socket structure IPv6 compatible Samuel Thibault
@ 2015-12-19 21:24   ` Samuel Thibault
  2015-12-19 21:25   ` [Qemu-devel] [PATCH 6/9] slirp: Factorizing and cleaning solookup() Samuel Thibault
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Samuel Thibault @ 2015-12-19 21:24 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, zhanghailiang, Li Zhijian, Stefan Hajnoczi,
	Jason Wang, Dave Gilbert, Vasiliy Tolstov, Huangpeng, Gonglei,
	Jan Kiszka, Samuel Thibault, Yang Hongyang, Guillaume Subiron

From: Guillaume Subiron <maethor@subiron.org>

This patch factorizes some duplicate code into a new function,
sotranslate_out(). This function perform the address translation when a
packet is transmitted to the host network. If the packet is destinated
to the host, the loopback address is used, and if the packet is
destinated to the virtual DNS, the real DNS address is used. This code
is just a copy of the existent, but factorized and ready to manage the
IPv6 case.

On the same model, the major part of udp_output() code is moved into a
new sotranslate_in(). This function is directly used in sorecvfrom(),
like sotranslate_out() in sosendto().
udp_output() becoming useless, it is removed and udp_output2() is
renamed into udp_output(). This adds consistency with the udp6_output()
function introduced by further patches.

Lastly, this factorizes some duplicate code into sotranslate_accept(), which
performs the address translation when a connection is established on the host
for port forwarding: if it comes from localhost, the host virtual address is
used instead.

This prepares for IPv6 support.

Signed-off-by: Guillaume Subiron <maethor@subiron.org>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
---
 slirp/bootp.c    |   2 +-
 slirp/ip_icmp.c  |  19 ++--------
 slirp/socket.c   | 112 +++++++++++++++++++++++++++++++++++++++++++++----------
 slirp/socket.h   |   5 +++
 slirp/tcp_subr.c |  35 ++++-------------
 slirp/tftp.c     |   6 +--
 slirp/udp.c      |  37 ++----------------
 slirp/udp.h      |   3 +-
 8 files changed, 116 insertions(+), 103 deletions(-)

diff --git a/slirp/bootp.c b/slirp/bootp.c
index 1baaab1..0027279 100644
--- a/slirp/bootp.c
+++ b/slirp/bootp.c
@@ -325,7 +325,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp)
 
     m->m_len = sizeof(struct bootp_t) -
         sizeof(struct ip) - sizeof(struct udphdr);
-    udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
+    udp_output(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
 }
 
 void bootp_input(struct mbuf *m)
diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 58b7ceb..3a29847 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -157,7 +157,7 @@ icmp_input(struct mbuf *m, int hlen)
         goto freeit;
     } else {
       struct socket *so;
-      struct sockaddr_in addr;
+      struct sockaddr_storage addr;
       if ((so = socreate(slirp)) == NULL) goto freeit;
       if (icmp_send(so, m, hlen) == 0) {
         return;
@@ -181,20 +181,9 @@ icmp_input(struct mbuf *m, int hlen)
       so->so_state = SS_ISFCONNECTED;
 
       /* Send the packet */
-      addr.sin_family = AF_INET;
-      if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
-          slirp->vnetwork_addr.s_addr) {
-	/* It's an alias */
-	if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
-	  if (get_dns_addr(&addr.sin_addr) < 0)
-	    addr.sin_addr = loopback_addr;
-	} else {
-	  addr.sin_addr = loopback_addr;
-	}
-      } else {
-	addr.sin_addr = so->so_faddr;
-      }
-      addr.sin_port = so->so_fport;
+      addr = so->fhost.ss;
+      sotranslate_out(so, &addr);
+
       if(sendto(so->s, icmp_ping_msg, strlen(icmp_ping_msg), 0,
 		(struct sockaddr *)&addr, sizeof(addr)) == -1) {
 	DEBUG_MISC((dfd,"icmp_input udp sendto tx errno = %d-%s\n",
diff --git a/slirp/socket.c b/slirp/socket.c
index bf603c9..d1034fb 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -438,6 +438,7 @@ void
 sorecvfrom(struct socket *so)
 {
 	struct sockaddr_storage addr;
+	struct sockaddr_storage saddr, daddr;
 	socklen_t addrlen = sizeof(struct sockaddr_storage);
 
 	DEBUG_CALL("sorecvfrom");
@@ -525,11 +526,17 @@ sorecvfrom(struct socket *so)
 
 	    /*
 	     * If this packet was destined for CTL_ADDR,
-	     * make it look like that's where it came from, done by udp_output
+	     * make it look like that's where it came from
 	     */
+	    saddr = addr;
+	    sotranslate_in(so, &saddr);
+	    daddr = so->lhost.ss;
+
 	    switch (so->so_ffamily) {
 	    case AF_INET:
-	        udp_output(so, m, (struct sockaddr_in *) &addr);
+	        udp_output(so, m, (struct sockaddr_in *) &saddr,
+	                   (struct sockaddr_in *) &daddr,
+	                   so->so_iptos);
 	        break;
 	    default:
 	        break;
@@ -544,33 +551,20 @@ sorecvfrom(struct socket *so)
 int
 sosendto(struct socket *so, struct mbuf *m)
 {
-	Slirp *slirp = so->slirp;
 	int ret;
-	struct sockaddr_in addr;
+	struct sockaddr_storage addr;
 
 	DEBUG_CALL("sosendto");
 	DEBUG_ARG("so = %p", so);
 	DEBUG_ARG("m = %p", m);
 
-        addr.sin_family = AF_INET;
-	if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
-	    slirp->vnetwork_addr.s_addr) {
-	  /* It's an alias */
-	  if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
-	    if (get_dns_addr(&addr.sin_addr) < 0)
-	      addr.sin_addr = loopback_addr;
-	  } else {
-	    addr.sin_addr = loopback_addr;
-	  }
-	} else
-	  addr.sin_addr = so->so_faddr;
-	addr.sin_port = so->so_fport;
-
-	DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n", ntohs(addr.sin_port), inet_ntoa(addr.sin_addr)));
+	addr = so->fhost.ss;
+	DEBUG_CALL(" sendto()ing)");
+	sotranslate_out(so, &addr);
 
 	/* Don't care what port we get */
 	ret = sendto(so->s, m->m_data, m->m_len, 0,
-		     (struct sockaddr *)&addr, sizeof (struct sockaddr));
+		     (struct sockaddr *)&addr, sizeof(addr));
 	if (ret < 0)
 		return -1;
 
@@ -726,3 +720,81 @@ sofwdrain(struct socket *so)
 	else
 		sofcantsendmore(so);
 }
+
+/*
+ * Translate addr in host addr when it is a virtual address
+ */
+void sotranslate_out(struct socket *so, struct sockaddr_storage *addr)
+{
+    Slirp *slirp = so->slirp;
+    struct sockaddr_in *sin = (struct sockaddr_in *)addr;
+
+    switch (addr->ss_family) {
+    case AF_INET:
+        if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
+                slirp->vnetwork_addr.s_addr) {
+            /* It's an alias */
+            if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
+                if (get_dns_addr(&sin->sin_addr) < 0) {
+                    sin->sin_addr = loopback_addr;
+                }
+            } else {
+                sin->sin_addr = loopback_addr;
+            }
+        }
+
+        DEBUG_MISC((dfd, " addr.sin_port=%d, "
+            "addr.sin_addr.s_addr=%.16s\n",
+            ntohs(sin->sin_port), inet_ntoa(sin->sin_addr)));
+        break;
+
+    default:
+        break;
+    }
+}
+
+void sotranslate_in(struct socket *so, struct sockaddr_storage *addr)
+{
+    Slirp *slirp = so->slirp;
+    struct sockaddr_in *sin = (struct sockaddr_in *)addr;
+
+    switch (addr->ss_family) {
+    case AF_INET:
+        if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
+            slirp->vnetwork_addr.s_addr) {
+            uint32_t inv_mask = ~slirp->vnetwork_mask.s_addr;
+
+            if ((so->so_faddr.s_addr & inv_mask) == inv_mask) {
+                sin->sin_addr = slirp->vhost_addr;
+            } else if (sin->sin_addr.s_addr == loopback_addr.s_addr ||
+                       so->so_faddr.s_addr != slirp->vhost_addr.s_addr) {
+                sin->sin_addr = so->so_faddr;
+            }
+        }
+        break;
+
+    default:
+        break;
+    }
+}
+
+/*
+ * Translate connections from localhost to the real hostname
+ */
+void sotranslate_accept(struct socket *so)
+{
+    Slirp *slirp = so->slirp;
+
+    switch (so->so_ffamily) {
+    case AF_INET:
+        if (so->so_faddr.s_addr == INADDR_ANY ||
+            (so->so_faddr.s_addr & loopback_mask) ==
+            (loopback_addr.s_addr & loopback_mask)) {
+           so->so_faddr = slirp->vhost_addr;
+        }
+        break;
+
+    default:
+        break;
+    }
+}
diff --git a/slirp/socket.h b/slirp/socket.h
index e854903..b27bbb2 100644
--- a/slirp/socket.h
+++ b/slirp/socket.h
@@ -105,4 +105,9 @@ struct iovec; /* For win32 */
 size_t sopreprbuf(struct socket *so, struct iovec *iov, int *np);
 int soreadbuf(struct socket *so, const char *buf, int size);
 
+void sotranslate_out(struct socket *, struct sockaddr_storage *);
+void sotranslate_in(struct socket *, struct sockaddr_storage *);
+void sotranslate_accept(struct socket *);
+
+
 #endif /* _SOCKET_H_ */
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 47262db..76c716f 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -326,7 +326,6 @@ tcp_sockclosed(struct tcpcb *tp)
  */
 int tcp_fconnect(struct socket *so)
 {
-  Slirp *slirp = so->slirp;
   int ret=0;
 
   DEBUG_CALL("tcp_fconnect");
@@ -334,30 +333,17 @@ int tcp_fconnect(struct socket *so)
 
   if( (ret = so->s = qemu_socket(AF_INET,SOCK_STREAM,0)) >= 0) {
     int opt, s=so->s;
-    struct sockaddr_in addr;
+    struct sockaddr_storage addr;
 
     qemu_set_nonblock(s);
     socket_set_fast_reuse(s);
     opt = 1;
     qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt));
 
-    addr.sin_family = AF_INET;
-    if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
-        slirp->vnetwork_addr.s_addr) {
-      /* It's an alias */
-      if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
-	if (get_dns_addr(&addr.sin_addr) < 0)
-	  addr.sin_addr = loopback_addr;
-      } else {
-	addr.sin_addr = loopback_addr;
-      }
-    } else
-      addr.sin_addr = so->so_faddr;
-    addr.sin_port = so->so_fport;
-
-    DEBUG_MISC((dfd, " connect()ing, addr.sin_port=%d, "
-		"addr.sin_addr.s_addr=%.16s\n",
-		ntohs(addr.sin_port), inet_ntoa(addr.sin_addr)));
+    addr = so->fhost.ss;
+    DEBUG_CALL(" connect()ing")
+    sotranslate_out(so, &addr);
+
     /* We don't care what port we get */
     ret = connect(s,(struct sockaddr *)&addr,sizeof (addr));
 
@@ -431,15 +417,8 @@ void tcp_connect(struct socket *inso)
     qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
     socket_set_nodelay(s);
 
-    so->so_ffamily = AF_INET;
-    so->so_fport = addr.sin_port;
-    so->so_faddr = addr.sin_addr;
-    /* Translate connections from localhost to the real hostname */
-    if (so->so_faddr.s_addr == 0 ||
-        (so->so_faddr.s_addr & loopback_mask) ==
-        (loopback_addr.s_addr & loopback_mask)) {
-        so->so_faddr = slirp->vhost_addr;
-    }
+    so->fhost.sin = addr;
+    sotranslate_accept(so);
 
     /* Close the accept() socket, set right state */
     if (inso->so_state & SS_FACCEPTONCE) {
diff --git a/slirp/tftp.c b/slirp/tftp.c
index a329fb2..ccb6130 100644
--- a/slirp/tftp.c
+++ b/slirp/tftp.c
@@ -155,7 +155,7 @@ static int tftp_send_oack(struct tftp_session *spt,
 
     m->m_len = sizeof(struct tftp_t) - 514 + n -
         sizeof(struct ip) - sizeof(struct udphdr);
-    udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
+    udp_output(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
 
     return 0;
 }
@@ -193,7 +193,7 @@ static void tftp_send_error(struct tftp_session *spt,
   m->m_len = sizeof(struct tftp_t) - 514 + 3 + strlen(msg) -
         sizeof(struct ip) - sizeof(struct udphdr);
 
-  udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
+  udp_output(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
 
 out:
   tftp_session_terminate(spt);
@@ -243,7 +243,7 @@ static void tftp_send_next_block(struct tftp_session *spt,
   m->m_len = sizeof(struct tftp_t) - (512 - nobytes) -
         sizeof(struct ip) - sizeof(struct udphdr);
 
-  udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
+  udp_output(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
 
   if (nobytes == 512) {
     tftp_session_update(spt);
diff --git a/slirp/udp.c b/slirp/udp.c
index 7a5c95b..8203eb1 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -236,7 +236,7 @@ bad:
 	m_free(m);
 }
 
-int udp_output2(struct socket *so, struct mbuf *m,
+int udp_output(struct socket *so, struct mbuf *m,
                 struct sockaddr_in *saddr, struct sockaddr_in *daddr,
                 int iptos)
 {
@@ -287,31 +287,6 @@ int udp_output2(struct socket *so, struct mbuf *m,
 	return (error);
 }
 
-int udp_output(struct socket *so, struct mbuf *m,
-               struct sockaddr_in *addr)
-
-{
-    Slirp *slirp = so->slirp;
-    struct sockaddr_in saddr, daddr;
-
-    saddr = *addr;
-    if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
-        slirp->vnetwork_addr.s_addr) {
-        uint32_t inv_mask = ~slirp->vnetwork_mask.s_addr;
-
-        if ((so->so_faddr.s_addr & inv_mask) == inv_mask) {
-            saddr.sin_addr = slirp->vhost_addr;
-        } else if (addr->sin_addr.s_addr == loopback_addr.s_addr ||
-                   so->so_faddr.s_addr != slirp->vhost_addr.s_addr) {
-            saddr.sin_addr = so->so_faddr;
-        }
-    }
-    daddr.sin_addr = so->so_laddr;
-    daddr.sin_port = so->so_lport;
-
-    return udp_output2(so, m, &saddr, &daddr, so->so_iptos);
-}
-
 int
 udp_attach(struct socket *so)
 {
@@ -378,14 +353,8 @@ udp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
 	socket_set_fast_reuse(so->s);
 
 	getsockname(so->s,(struct sockaddr *)&addr,&addrlen);
-	so->so_ffamily = AF_INET;
-	so->so_fport = addr.sin_port;
-	if (addr.sin_addr.s_addr == 0 ||
-	    addr.sin_addr.s_addr == loopback_addr.s_addr) {
-	   so->so_faddr = slirp->vhost_addr;
-	} else {
-	   so->so_faddr = addr.sin_addr;
-	}
+	so->fhost.sin = addr;
+	sotranslate_accept(so);
 	so->so_lfamily = AF_INET;
 	so->so_lport = lport;
 	so->so_laddr.s_addr = laddr;
diff --git a/slirp/udp.h b/slirp/udp.h
index 9bf31fe..a04b8ce 100644
--- a/slirp/udp.h
+++ b/slirp/udp.h
@@ -76,12 +76,11 @@ struct mbuf;
 void udp_init(Slirp *);
 void udp_cleanup(Slirp *);
 void udp_input(register struct mbuf *, int);
-int udp_output(struct socket *, struct mbuf *, struct sockaddr_in *);
 int udp_attach(struct socket *);
 void udp_detach(struct socket *);
 struct socket * udp_listen(Slirp *, uint32_t, u_int, uint32_t, u_int,
                            int);
-int udp_output2(struct socket *so, struct mbuf *m,
+int udp_output(struct socket *so, struct mbuf *m,
                 struct sockaddr_in *saddr, struct sockaddr_in *daddr,
                 int iptos);
 #endif
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 6/9] slirp: Factorizing and cleaning solookup()
  2015-12-19 21:24 ` [Qemu-devel] [PATCH 1/9] slirp: goto bad in udp_input if sosendto fails Samuel Thibault
                     ` (3 preceding siblings ...)
  2015-12-19 21:24   ` [Qemu-devel] [PATCH 5/9] slirp: Factorizing address translation Samuel Thibault
@ 2015-12-19 21:25   ` Samuel Thibault
  2015-12-19 21:25   ` [Qemu-devel] [PATCH 7/9] slirp: Add sockaddr_equal, make solookup family-agnostic Samuel Thibault
                     ` (2 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Samuel Thibault @ 2015-12-19 21:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, zhanghailiang, Li Zhijian, Stefan Hajnoczi,
	Jason Wang, Dave Gilbert, Vasiliy Tolstov, Huangpeng, Gonglei,
	Jan Kiszka, Samuel Thibault, Yang Hongyang, Guillaume Subiron

From: Guillaume Subiron <maethor@subiron.org>

solookup() was only compatible with TCP. Having the socket list in
argument, it is now compatible with UDP too.

Some optimization code is factorized inside the function (the function
look at the last returned result before browsing the complete socket
list).

This prepares for IPv6 support.

Signed-off-by: Guillaume Subiron <maethor@subiron.org>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
---
 slirp/socket.c    | 37 ++++++++++++++++++++++++-------------
 slirp/socket.h    |  5 +++--
 slirp/tcp_input.c | 13 +++----------
 slirp/udp.c       | 21 ++-------------------
 4 files changed, 32 insertions(+), 44 deletions(-)

diff --git a/slirp/socket.c b/slirp/socket.c
index d1034fb..8f73e90 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -16,23 +16,34 @@ static void sofcantrcvmore(struct socket *so);
 static void sofcantsendmore(struct socket *so);
 
 struct socket *
-solookup(struct socket *head, struct in_addr laddr, u_int lport,
+solookup(struct socket **last, struct socket *head,
+         struct in_addr laddr, u_int lport,
          struct in_addr faddr, u_int fport)
 {
-	struct socket *so;
-
-	for (so = head->so_next; so != head; so = so->so_next) {
-		if (so->so_lport == lport &&
-		    so->so_laddr.s_addr == laddr.s_addr &&
-		    so->so_faddr.s_addr == faddr.s_addr &&
-		    so->so_fport == fport)
-		   break;
-	}
+    struct socket *so = *last;
+
+    /* Optimisation */
+    if (so != head &&
+            so->so_lport == lport &&
+            so->so_laddr.s_addr == laddr.s_addr &&
+            (!faddr.s_addr ||
+                (so->so_faddr.s_addr == faddr.s_addr &&
+                 so->so_fport == fport))) {
+        return so;
+    }
 
-	if (so == head)
-	   return (struct socket *)NULL;
-	return so;
+    for (so = head->so_next; so != head; so = so->so_next) {
+        if (so->so_lport == lport &&
+            so->so_laddr.s_addr == laddr.s_addr &&
+            (!faddr.s_addr ||
+                (so->so_faddr.s_addr == faddr.s_addr &&
+                 so->so_fport == fport))) {
+            *last = so;
+            return so;
+        }
+    }
 
+    return (struct socket *)NULL;
 }
 
 /*
diff --git a/slirp/socket.h b/slirp/socket.h
index b27bbb2..1c8c24c 100644
--- a/slirp/socket.h
+++ b/slirp/socket.h
@@ -87,8 +87,9 @@ struct socket {
 #define SS_HOSTFWD		0x1000	/* Socket describes host->guest forwarding */
 #define SS_INCOMING		0x2000	/* Connection was initiated by a host on the internet */
 
-struct socket * solookup(struct socket *, struct in_addr, u_int, struct in_addr, u_int);
-struct socket * socreate(Slirp *);
+struct socket *solookup(struct socket **, struct socket *,
+        struct in_addr, u_int, struct in_addr, u_int);
+struct socket *socreate(Slirp *);
 void sofree(struct socket *);
 int soread(struct socket *);
 void sorecvoob(struct socket *);
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index 4c3191d..5492061 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -320,16 +320,9 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
 	 * Locate pcb for segment.
 	 */
 findso:
-	so = slirp->tcp_last_so;
-	if (so->so_fport != ti->ti_dport ||
-	    so->so_lport != ti->ti_sport ||
-	    so->so_laddr.s_addr != ti->ti_src.s_addr ||
-	    so->so_faddr.s_addr != ti->ti_dst.s_addr) {
-		so = solookup(&slirp->tcb, ti->ti_src, ti->ti_sport,
-			       ti->ti_dst, ti->ti_dport);
-		if (so)
-			slirp->tcp_last_so = so;
-	}
+	so = solookup(&slirp->tcp_last_so, &slirp->tcb,
+		      ti->ti_src, ti->ti_sport,
+		      ti->ti_dst, ti->ti_dport);
 
 	/*
 	 * If the state is CLOSED (i.e., TCB does not exist) then
diff --git a/slirp/udp.c b/slirp/udp.c
index 8203eb1..126ef82 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -151,25 +151,8 @@ udp_input(register struct mbuf *m, int iphlen)
 	/*
 	 * Locate pcb for datagram.
 	 */
-	so = slirp->udp_last_so;
-	if (so == &slirp->udb || so->so_lport != uh->uh_sport ||
-	    so->so_laddr.s_addr != ip->ip_src.s_addr) {
-		struct socket *tmp;
-
-		for (tmp = slirp->udb.so_next; tmp != &slirp->udb;
-		     tmp = tmp->so_next) {
-			if (tmp->so_lport == uh->uh_sport &&
-			    tmp->so_laddr.s_addr == ip->ip_src.s_addr) {
-				so = tmp;
-				break;
-			}
-		}
-		if (tmp == &slirp->udb) {
-		  so = NULL;
-		} else {
-		  slirp->udp_last_so = so;
-		}
-	}
+	so = solookup(&slirp->udp_last_so, &slirp->udb,
+		      ip->ip_src, uh->uh_sport, (struct in_addr) {0}, 0);
 
 	if (so == NULL) {
 	  /*
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 7/9] slirp: Add sockaddr_equal, make solookup family-agnostic
  2015-12-19 21:24 ` [Qemu-devel] [PATCH 1/9] slirp: goto bad in udp_input if sosendto fails Samuel Thibault
                     ` (4 preceding siblings ...)
  2015-12-19 21:25   ` [Qemu-devel] [PATCH 6/9] slirp: Factorizing and cleaning solookup() Samuel Thibault
@ 2015-12-19 21:25   ` Samuel Thibault
  2015-12-19 21:25   ` [Qemu-devel] [PATCH 8/9] slirp: Make udp_attach IPv6 compatible Samuel Thibault
  2015-12-19 21:25   ` [Qemu-devel] [PATCH 9/9] slirp: Adding family argument to tcp_fconnect() Samuel Thibault
  7 siblings, 0 replies; 16+ messages in thread
From: Samuel Thibault @ 2015-12-19 21:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, zhanghailiang, Li Zhijian, Stefan Hajnoczi,
	Jason Wang, Dave Gilbert, Vasiliy Tolstov, Huangpeng, Gonglei,
	Jan Kiszka, Samuel Thibault, Yang Hongyang, Guillaume Subiron

From: Guillaume Subiron <maethor@subiron.org>

This patch makes solookup() compatible with varying address
families, by using a new sockaddr_equal() function that compares
two sockaddr_storage.

This prepares for IPv6 support.

Signed-off-by: Guillaume Subiron <maethor@subiron.org>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
---
 slirp/socket.c    | 21 ++++++---------------
 slirp/socket.h    | 22 +++++++++++++++++++++-
 slirp/tcp_input.c | 23 ++++++++++++++---------
 slirp/udp.c       | 10 ++++++++--
 4 files changed, 49 insertions(+), 27 deletions(-)

diff --git a/slirp/socket.c b/slirp/socket.c
index 8f73e90..f7e5968 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -15,29 +15,20 @@
 static void sofcantrcvmore(struct socket *so);
 static void sofcantsendmore(struct socket *so);
 
-struct socket *
-solookup(struct socket **last, struct socket *head,
-         struct in_addr laddr, u_int lport,
-         struct in_addr faddr, u_int fport)
+struct socket *solookup(struct socket **last, struct socket *head,
+        struct sockaddr_storage *lhost, struct sockaddr_storage *fhost)
 {
     struct socket *so = *last;
 
     /* Optimisation */
-    if (so != head &&
-            so->so_lport == lport &&
-            so->so_laddr.s_addr == laddr.s_addr &&
-            (!faddr.s_addr ||
-                (so->so_faddr.s_addr == faddr.s_addr &&
-                 so->so_fport == fport))) {
+    if (so != head && sockaddr_equal(&(so->lhost.ss), lhost)
+            && (!fhost || sockaddr_equal(&so->fhost.ss, fhost))) {
         return so;
     }
 
     for (so = head->so_next; so != head; so = so->so_next) {
-        if (so->so_lport == lport &&
-            so->so_laddr.s_addr == laddr.s_addr &&
-            (!faddr.s_addr ||
-                (so->so_faddr.s_addr == faddr.s_addr &&
-                 so->so_fport == fport))) {
+        if (sockaddr_equal(&(so->lhost.ss), lhost)
+                && (!fhost || sockaddr_equal(&so->fhost.ss, fhost))) {
             *last = so;
             return so;
         }
diff --git a/slirp/socket.h b/slirp/socket.h
index 1c8c24c..929af0a 100644
--- a/slirp/socket.h
+++ b/slirp/socket.h
@@ -87,8 +87,28 @@ struct socket {
 #define SS_HOSTFWD		0x1000	/* Socket describes host->guest forwarding */
 #define SS_INCOMING		0x2000	/* Connection was initiated by a host on the internet */
 
+static inline int sockaddr_equal(struct sockaddr_storage *a,
+        struct sockaddr_storage *b)
+{
+    if (a->ss_family != b->ss_family) {
+        return 0;
+    }
+
+    switch (a->ss_family) {
+    case AF_INET:
+    {
+        struct sockaddr_in *a4 = (struct sockaddr_in *) a;
+        struct sockaddr_in *b4 = (struct sockaddr_in *) b;
+        return a4->sin_addr.s_addr == b4->sin_addr.s_addr
+               && a4->sin_port == b4->sin_port;
+    }
+    default:
+        assert(0);
+    }
+}
+
 struct socket *solookup(struct socket **, struct socket *,
-        struct in_addr, u_int, struct in_addr, u_int);
+        struct sockaddr_storage *, struct sockaddr_storage *);
 struct socket *socreate(Slirp *);
 void sofree(struct socket *);
 int soread(struct socket *);
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index 5492061..5e2773c 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -227,6 +227,8 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
 	int iss = 0;
 	u_long tiwin;
 	int ret;
+	struct sockaddr_storage lhost, fhost;
+	struct sockaddr_in *lhost4, *fhost4;
     struct ex_list *ex_ptr;
     Slirp *slirp;
 
@@ -320,9 +322,16 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
 	 * Locate pcb for segment.
 	 */
 findso:
-	so = solookup(&slirp->tcp_last_so, &slirp->tcb,
-		      ti->ti_src, ti->ti_sport,
-		      ti->ti_dst, ti->ti_dport);
+	lhost.ss_family = AF_INET;
+	lhost4 = (struct sockaddr_in *) &lhost;
+	lhost4->sin_addr = ti->ti_src;
+	lhost4->sin_port = ti->ti_sport;
+	fhost.ss_family = AF_INET;
+	fhost4 = (struct sockaddr_in *) &fhost;
+	fhost4->sin_addr = ti->ti_dst;
+	fhost4->sin_port = ti->ti_dport;
+
+	so = solookup(&slirp->tcp_last_so, &slirp->tcb, &lhost, &fhost);
 
 	/*
 	 * If the state is CLOSED (i.e., TCB does not exist) then
@@ -367,12 +376,8 @@ findso:
 	  sbreserve(&so->so_snd, TCP_SNDSPACE);
 	  sbreserve(&so->so_rcv, TCP_RCVSPACE);
 
-	  so->so_lfamily = AF_INET;
-	  so->so_laddr = ti->ti_src;
-	  so->so_lport = ti->ti_sport;
-	  so->so_ffamily = AF_INET;
-	  so->so_faddr = ti->ti_dst;
-	  so->so_fport = ti->ti_dport;
+	  so->lhost.ss = lhost;
+	  so->fhost.ss = fhost;
 
 	  if ((so->so_iptos = tcp_tos(so)) == 0)
 	    so->so_iptos = ((struct ip *)ti)->ip_tos;
diff --git a/slirp/udp.c b/slirp/udp.c
index 126ef82..63776c0 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -70,6 +70,8 @@ udp_input(register struct mbuf *m, int iphlen)
 	int len;
 	struct ip save_ip;
 	struct socket *so;
+	struct sockaddr_storage lhost;
+	struct sockaddr_in *lhost4;
 
 	DEBUG_CALL("udp_input");
 	DEBUG_ARG("m = %p", m);
@@ -151,8 +153,12 @@ udp_input(register struct mbuf *m, int iphlen)
 	/*
 	 * Locate pcb for datagram.
 	 */
-	so = solookup(&slirp->udp_last_so, &slirp->udb,
-		      ip->ip_src, uh->uh_sport, (struct in_addr) {0}, 0);
+	lhost.ss_family = AF_INET;
+	lhost4 = (struct sockaddr_in *) &lhost;
+	lhost4->sin_addr = ip->ip_src;
+	lhost4->sin_port = uh->uh_sport;
+
+	so = solookup(&slirp->udp_last_so, &slirp->udb, &lhost, NULL);
 
 	if (so == NULL) {
 	  /*
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 8/9] slirp: Make udp_attach IPv6 compatible
  2015-12-19 21:24 ` [Qemu-devel] [PATCH 1/9] slirp: goto bad in udp_input if sosendto fails Samuel Thibault
                     ` (5 preceding siblings ...)
  2015-12-19 21:25   ` [Qemu-devel] [PATCH 7/9] slirp: Add sockaddr_equal, make solookup family-agnostic Samuel Thibault
@ 2015-12-19 21:25   ` Samuel Thibault
  2015-12-19 21:25   ` [Qemu-devel] [PATCH 9/9] slirp: Adding family argument to tcp_fconnect() Samuel Thibault
  7 siblings, 0 replies; 16+ messages in thread
From: Samuel Thibault @ 2015-12-19 21:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, zhanghailiang, Li Zhijian, Stefan Hajnoczi,
	Jason Wang, Dave Gilbert, Vasiliy Tolstov, Huangpeng, Gonglei,
	Jan Kiszka, Samuel Thibault, Yang Hongyang, Guillaume Subiron

From: Guillaume Subiron <maethor@subiron.org>

A sa_family_t is now passed in argument to udp_attach instead of using a
hardcoded "AF_INET" to call qemu_socket().

This prepares for IPv6 support.

Signed-off-by: Guillaume Subiron <maethor@subiron.org>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
---
 slirp/ip_icmp.c | 2 +-
 slirp/udp.c     | 7 ++++---
 slirp/udp.h     | 2 +-
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 3a29847..592f33a 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -162,7 +162,7 @@ icmp_input(struct mbuf *m, int hlen)
       if (icmp_send(so, m, hlen) == 0) {
         return;
       }
-      if(udp_attach(so) == -1) {
+      if (udp_attach(so, AF_INET) == -1) {
 	DEBUG_MISC((dfd,"icmp_input udp_attach errno = %d-%s\n",
 		    errno,strerror(errno)));
 	sofree(so);
diff --git a/slirp/udp.c b/slirp/udp.c
index 63776c0..94e19b7 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -169,7 +169,7 @@ udp_input(register struct mbuf *m, int iphlen)
 	  if (!so) {
 	      goto bad;
 	  }
-	  if(udp_attach(so) == -1) {
+	  if (udp_attach(so, AF_INET) == -1) {
 	    DEBUG_MISC((dfd," udp_attach errno = %d-%s\n",
 			errno,strerror(errno)));
 	    sofree(so);
@@ -277,9 +277,10 @@ int udp_output(struct socket *so, struct mbuf *m,
 }
 
 int
-udp_attach(struct socket *so)
+udp_attach(struct socket *so, sa_family_t af)
 {
-  if((so->s = qemu_socket(AF_INET,SOCK_DGRAM,0)) != -1) {
+  so->s = qemu_socket(af, SOCK_DGRAM, 0);
+  if (so->s != -1) {
     so->so_expire = curtime + SO_EXPIRE;
     insque(so, &so->slirp->udb);
   }
diff --git a/slirp/udp.h b/slirp/udp.h
index a04b8ce..15e73c1 100644
--- a/slirp/udp.h
+++ b/slirp/udp.h
@@ -76,7 +76,7 @@ struct mbuf;
 void udp_init(Slirp *);
 void udp_cleanup(Slirp *);
 void udp_input(register struct mbuf *, int);
-int udp_attach(struct socket *);
+int udp_attach(struct socket *, sa_family_t af);
 void udp_detach(struct socket *);
 struct socket * udp_listen(Slirp *, uint32_t, u_int, uint32_t, u_int,
                            int);
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 9/9] slirp: Adding family argument to tcp_fconnect()
  2015-12-19 21:24 ` [Qemu-devel] [PATCH 1/9] slirp: goto bad in udp_input if sosendto fails Samuel Thibault
                     ` (6 preceding siblings ...)
  2015-12-19 21:25   ` [Qemu-devel] [PATCH 8/9] slirp: Make udp_attach IPv6 compatible Samuel Thibault
@ 2015-12-19 21:25   ` Samuel Thibault
  7 siblings, 0 replies; 16+ messages in thread
From: Samuel Thibault @ 2015-12-19 21:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, zhanghailiang, Li Zhijian, Stefan Hajnoczi,
	Jason Wang, Dave Gilbert, Vasiliy Tolstov, Huangpeng, Gonglei,
	Jan Kiszka, Samuel Thibault, Yang Hongyang, Guillaume Subiron

From: Guillaume Subiron <maethor@subiron.org>

This patch simply adds a sa_family_t argument to remove the hardcoded
"AF_INET" in the call of qemu_socket().

This prepares for IPv6 support.

Signed-off-by: Guillaume Subiron <maethor@subiron.org>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
---
 slirp/slirp.h     | 2 +-
 slirp/tcp_input.c | 2 +-
 slirp/tcp_subr.c  | 5 +++--
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/slirp/slirp.h b/slirp/slirp.h
index 6589d7e..5b810e5 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -332,7 +332,7 @@ void tcp_respond(struct tcpcb *, register struct tcpiphdr *, register struct mbu
 struct tcpcb * tcp_newtcpcb(struct socket *);
 struct tcpcb * tcp_close(register struct tcpcb *);
 void tcp_sockclosed(struct tcpcb *);
-int tcp_fconnect(struct socket *);
+int tcp_fconnect(struct socket *, sa_family_t af);
 void tcp_connect(struct socket *);
 int tcp_attach(struct socket *);
 uint8_t tcp_tos(struct socket *);
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index 5e2773c..f24e706 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -584,7 +584,7 @@ findso:
 	    goto cont_input;
 	  }
 
-          if ((tcp_fconnect(so) == -1) &&
+	  if ((tcp_fconnect(so, so->so_ffamily) == -1) &&
 #if defined(_WIN32)
               socket_error() != WSAEWOULDBLOCK
 #else
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 76c716f..8ec2729 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -324,14 +324,15 @@ tcp_sockclosed(struct tcpcb *tp)
  * nonblocking.  Connect returns after the SYN is sent, and does
  * not wait for ACK+SYN.
  */
-int tcp_fconnect(struct socket *so)
+int tcp_fconnect(struct socket *so, sa_family_t af)
 {
   int ret=0;
 
   DEBUG_CALL("tcp_fconnect");
   DEBUG_ARG("so = %p", so);
 
-  if( (ret = so->s = qemu_socket(AF_INET,SOCK_STREAM,0)) >= 0) {
+  ret = so->s = qemu_socket(af, SOCK_STREAM, 0);
+  if (ret >= 0) {
     int opt, s=so->s;
     struct sockaddr_storage addr;
 
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCHv7 0/9] slirp: Adding IPv6 support to Qemu -net user mode
  2015-12-19 21:24 [Qemu-devel] [PATCHv7 0/9] slirp: Adding IPv6 support to Qemu -net user mode Samuel Thibault
  2015-12-19 21:24 ` [Qemu-devel] [PATCH 1/9] slirp: goto bad in udp_input if sosendto fails Samuel Thibault
@ 2015-12-21 15:30 ` Eric Blake
  2016-01-11 15:04 ` Samuel Thibault
  2 siblings, 0 replies; 16+ messages in thread
From: Eric Blake @ 2015-12-21 15:30 UTC (permalink / raw)
  To: Samuel Thibault, zhanghailiang
  Cc: Thomas Huth, Li Zhijian, Stefan Hajnoczi, Jason Wang, qemu-devel,
	Vasiliy Tolstov, peter.huangpeng, Gonglei (Arei),
	Stefan Hajnoczi, J. Kiszka, Yang Hongyang, Dave Gilbert

[-- Attachment #1: Type: text/plain, Size: 2685 bytes --]

On 12/19/2015 02:24 PM, Samuel Thibault wrote:
> Hello,

meta-reply

> 
> This is another respin of IPv6 in Qemu -net user mode.
> 
> The following patches first make some refactoring to make current code ready
> for IPv6, and do not change the behavior.  The actual IPv6 support will then be
> submitted as a separate patch series.
> 
> Difference with version 6 is:
> - Use error_report instead of printing to stderr
> - Drop extra parentheses
> - Use nicer-looking sockaddr casts.
> 
> All of this has been reviewed by Thomas Huth, thanks!

It looks like you wrote your own cover letter, then supplied the git
series in reply to your cover letter but with the git series still
internally threaded.  This resulted in the unusual reply tree of:

0/9
+ 1/9
  + 2/9
  + 3/9
  + ...
  + 9/9

and where clients that display trees based both on reply relationships
and age would show:

0/9
+ 1/9
  + 2/9
  | + Re: 2/9
  + ...
  + 9/9
  | + Re: 9/9
  + Re: 1/9

That is, in your series, all of 2 through 9 were marked as children of
1, rather than a sibling of 1.  The more typical flat threading looks like:

0/9
+ 1/9
+ 2/9
+ ...
+ 9/9

where replies to 1 are then threaded closer to the original:

0/9
+ 1/9
| + Re: 1/9
+ 2/9
| + Re: 2/9
+ ...
+ 9/9
  + Re: 9/9

You may want to look into using 'git format-patch --cover-letter';
easily done with 'git config format.coverLetter auto'.  The git cover
letter would include a diffstat that includes the names of all files
touched by the series as well as relative sizing of the patch, which is
helpful to users.  Also, using git to produce the cover letter
(producing all of 0 through 9 in one shot, with 1-9 all threaded as
siblings to each other and children of 0), instead of producing the body
with git (just 1 through 9, with 2-9 replying to 1) and then chaining
that series to a hand-written cover letter, would solve the unusual
threading.

> 
> Here is a summary of the patches:
> 
> [PATCH 1/9] slirp: goto bad in udp_input if sosendto fails
> [PATCH 2/9] slirp: Generalizing and neutralizing ARP code
> [PATCH 3/9] slirp: Adding address family switch for incoming frames
> [PATCH 4/9] slirp: Make Socket structure IPv6 compatible
> [PATCH 5/9] slirp: Factorizing address translation
> [PATCH 6/9] slirp: Factorizing and cleaning solookup()
> [PATCH 7/9] slirp: Add sockaddr_equal, make solookup family-agnostic
> [PATCH 8/9] slirp: Make udp_attach IPv6 compatible
> [PATCH 9/9] slirp: Adding family argument to tcp_fconnect()
> 
> 

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCHv7 0/9] slirp: Adding IPv6 support to Qemu -net user mode
  2015-12-19 21:24 [Qemu-devel] [PATCHv7 0/9] slirp: Adding IPv6 support to Qemu -net user mode Samuel Thibault
  2015-12-19 21:24 ` [Qemu-devel] [PATCH 1/9] slirp: goto bad in udp_input if sosendto fails Samuel Thibault
  2015-12-21 15:30 ` [Qemu-devel] [PATCHv7 0/9] slirp: Adding IPv6 support to Qemu -net user mode Eric Blake
@ 2016-01-11 15:04 ` Samuel Thibault
  2016-01-12  2:22   ` Hailiang Zhang
  2 siblings, 1 reply; 16+ messages in thread
From: Samuel Thibault @ 2016-01-11 15:04 UTC (permalink / raw)
  To: zhanghailiang
  Cc: Thomas Huth, Li Zhijian, Stefan Hajnoczi, Jason Wang, qemu-devel,
	Vasiliy Tolstov, peter.huangpeng, Gonglei (Arei),
	Stefan Hajnoczi, J. Kiszka, Yang Hongyang, Dave Gilbert

Hello,

Samuel Thibault, on Sat 19 Dec 2015 22:24:40 +0100, wrote:
> This is another respin of IPv6 in Qemu -net user mode.
> 
> The following patches first make some refactoring to make current code ready
> for IPv6, and do not change the behavior.  The actual IPv6 support will then be
> submitted as a separate patch series.

Ping?

The whole series has been reviewed, it just needs a commit (for which I
don't have access).

Samuel

> Difference with version 6 is:
> - Use error_report instead of printing to stderr
> - Drop extra parentheses
> - Use nicer-looking sockaddr casts.
> 
> All of this has been reviewed by Thomas Huth, thanks!
> 
> Here is a summary of the patches:
> 
> [PATCH 1/9] slirp: goto bad in udp_input if sosendto fails
> [PATCH 2/9] slirp: Generalizing and neutralizing ARP code
> [PATCH 3/9] slirp: Adding address family switch for incoming frames
> [PATCH 4/9] slirp: Make Socket structure IPv6 compatible
> [PATCH 5/9] slirp: Factorizing address translation
> [PATCH 6/9] slirp: Factorizing and cleaning solookup()
> [PATCH 7/9] slirp: Add sockaddr_equal, make solookup family-agnostic
> [PATCH 8/9] slirp: Make udp_attach IPv6 compatible
> [PATCH 9/9] slirp: Adding family argument to tcp_fconnect()

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCHv7 0/9] slirp: Adding IPv6 support to Qemu -net user mode
  2016-01-11 15:04 ` Samuel Thibault
@ 2016-01-12  2:22   ` Hailiang Zhang
  2016-01-12  4:04     ` Jason Wang
  0 siblings, 1 reply; 16+ messages in thread
From: Hailiang Zhang @ 2016-01-12  2:22 UTC (permalink / raw)
  To: Samuel Thibault, J. Kiszka
  Cc: Thomas Huth, Li Zhijian, Stefan Hajnoczi, Jason Wang,
	peter.huangpeng, Vasiliy Tolstov, qemu-devel, Gonglei (Arei),
	Stefan Hajnoczi, Yang Hongyang, Dave Gilbert

Hi,

It seems that, Jan Kiszka is maintaining SLIRP (From MAINTAINERS file),
Maybe he could make a help to merge this series.

TO: J. Kiszka <jan.kiszka@siemens.com>

Thanks,
Hailiang

On 2016/1/11 23:04, Samuel Thibault wrote:
> Hello,
>
> Samuel Thibault, on Sat 19 Dec 2015 22:24:40 +0100, wrote:
>> This is another respin of IPv6 in Qemu -net user mode.
>>
>> The following patches first make some refactoring to make current code ready
>> for IPv6, and do not change the behavior.  The actual IPv6 support will then be
>> submitted as a separate patch series.
>
> Ping?
>
> The whole series has been reviewed, it just needs a commit (for which I
> don't have access).
>
> Samuel
>
>> Difference with version 6 is:
>> - Use error_report instead of printing to stderr
>> - Drop extra parentheses
>> - Use nicer-looking sockaddr casts.
>>
>> All of this has been reviewed by Thomas Huth, thanks!
>>
>> Here is a summary of the patches:
>>
>> [PATCH 1/9] slirp: goto bad in udp_input if sosendto fails
>> [PATCH 2/9] slirp: Generalizing and neutralizing ARP code
>> [PATCH 3/9] slirp: Adding address family switch for incoming frames
>> [PATCH 4/9] slirp: Make Socket structure IPv6 compatible
>> [PATCH 5/9] slirp: Factorizing address translation
>> [PATCH 6/9] slirp: Factorizing and cleaning solookup()
>> [PATCH 7/9] slirp: Add sockaddr_equal, make solookup family-agnostic
>> [PATCH 8/9] slirp: Make udp_attach IPv6 compatible
>> [PATCH 9/9] slirp: Adding family argument to tcp_fconnect()
>
> .
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCHv7 0/9] slirp: Adding IPv6 support to Qemu -net user mode
  2016-01-12  2:22   ` Hailiang Zhang
@ 2016-01-12  4:04     ` Jason Wang
  2016-01-18  8:14       ` Jason Wang
  0 siblings, 1 reply; 16+ messages in thread
From: Jason Wang @ 2016-01-12  4:04 UTC (permalink / raw)
  To: Hailiang Zhang, Samuel Thibault, J. Kiszka
  Cc: Thomas Huth, Li Zhijian, Stefan Hajnoczi, peter.huangpeng,
	Vasiliy Tolstov, qemu-devel, Gonglei (Arei),
	Stefan Hajnoczi, Yang Hongyang, Dave Gilbert



On 01/12/2016 10:22 AM, Hailiang Zhang wrote:
> Hi,
>
> It seems that, Jan Kiszka is maintaining SLIRP (From MAINTAINERS file),
> Maybe he could make a help to merge this series.
>
> TO: J. Kiszka <jan.kiszka@siemens.com>
>
> Thanks,
> Hailiang

Right, and I can take this series in my tree if Jan doesn't have time to
do this.

>
> On 2016/1/11 23:04, Samuel Thibault wrote:
>> Hello,
>>
>> Samuel Thibault, on Sat 19 Dec 2015 22:24:40 +0100, wrote:
>>> This is another respin of IPv6 in Qemu -net user mode.
>>>
>>> The following patches first make some refactoring to make current
>>> code ready
>>> for IPv6, and do not change the behavior.  The actual IPv6 support
>>> will then be
>>> submitted as a separate patch series.
>>
>> Ping?
>>
>> The whole series has been reviewed, it just needs a commit (for which I
>> don't have access).
>>
>> Samuel
>>
>>> Difference with version 6 is:
>>> - Use error_report instead of printing to stderr
>>> - Drop extra parentheses
>>> - Use nicer-looking sockaddr casts.
>>>
>>> All of this has been reviewed by Thomas Huth, thanks!
>>>
>>> Here is a summary of the patches:
>>>
>>> [PATCH 1/9] slirp: goto bad in udp_input if sosendto fails
>>> [PATCH 2/9] slirp: Generalizing and neutralizing ARP code
>>> [PATCH 3/9] slirp: Adding address family switch for incoming frames
>>> [PATCH 4/9] slirp: Make Socket structure IPv6 compatible
>>> [PATCH 5/9] slirp: Factorizing address translation
>>> [PATCH 6/9] slirp: Factorizing and cleaning solookup()
>>> [PATCH 7/9] slirp: Add sockaddr_equal, make solookup family-agnostic
>>> [PATCH 8/9] slirp: Make udp_attach IPv6 compatible
>>> [PATCH 9/9] slirp: Adding family argument to tcp_fconnect()
>>
>> .
>>
>
>
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCHv7 0/9] slirp: Adding IPv6 support to Qemu -net user mode
  2016-01-12  4:04     ` Jason Wang
@ 2016-01-18  8:14       ` Jason Wang
  0 siblings, 0 replies; 16+ messages in thread
From: Jason Wang @ 2016-01-18  8:14 UTC (permalink / raw)
  To: Hailiang Zhang, Samuel Thibault, J. Kiszka
  Cc: Thomas Huth, Li Zhijian, Stefan Hajnoczi, peter.huangpeng,
	Vasiliy Tolstov, qemu-devel, Gonglei (Arei),
	Stefan Hajnoczi, Yang Hongyang, Dave Gilbert



On 01/12/2016 12:04 PM, Jason Wang wrote:
> On 01/12/2016 10:22 AM, Hailiang Zhang wrote:
>> > Hi,
>> >
>> > It seems that, Jan Kiszka is maintaining SLIRP (From MAINTAINERS file),
>> > Maybe he could make a help to merge this series.
>> >
>> > TO: J. Kiszka <jan.kiszka@siemens.com>
>> >
>> > Thanks,
>> > Hailiang
> Right, and I can take this series in my tree if Jan doesn't have time to
> do this.
>

Ok, apply to my -net.

Thanks

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCHv7 0/9] slirp: Adding IPv6 support to Qemu -net user mode
@ 2016-02-08 10:28 Samuel Thibault
  0 siblings, 0 replies; 16+ messages in thread
From: Samuel Thibault @ 2016-02-08 10:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, zhanghailiang, Li Zhijian, Stefan Hajnoczi,
	Jason Wang, Dave Gilbert, Vasiliy Tolstov, Huangpeng, Gonglei,
	Jan Kiszka, Samuel Thibault, Yang Hongyang, Guillaume Subiron

Hello,

This is another respin of IPv6 in Qemu -net user mode.


These patches add ICMPv6, NDP, and make UDP and TCP compatible with
IPv6.


Difference with version 6 is:
- drop second-precision timer addition
- use ms precision for RA timer
- Use unsigned short instead of sa_family_t
- Use error_report instead of printing to stderr
- Use g_assert_not_reached instead of assert(0)

Here is a summary of the patches:

Guillaume Subiron (7):
  slirp: Adding IPv6, ICMPv6 Echo and NDP autoconfiguration
  slirp: Adding IPv6 UDP support
  slirp: Factorizing tcpiphdr structure with an union
  slirp: Generalizing and neutralizing various TCP functions before
    adding IPv6 stuff
  slirp: Reindent after refactoring
  slirp: Handle IPv6 in TCP functions
  slirp: Adding IPv6 address for DNS relay

Yann Bordenave (2):
  slirp: Adding ICMPv6 error sending
  qapi-schema, qemu-options & slirp: Adding Qemu options for IPv6
    addresses

 net/net.c           |  31 ++++
 net/slirp.c         |  50 ++++++-
 qapi-schema.json    |  40 +++--
 qemu-options.hx     |  18 ++-
 slirp/Makefile.objs |   4 +-
 slirp/cksum.c       |  23 +++
 slirp/if.c          |   2 +-
 slirp/if.h          |   4 +-
 slirp/ip6.h         | 142 ++++++++++++++++++
 slirp/ip6_icmp.c    | 410 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 slirp/ip6_icmp.h    | 254 ++++++++++++++++++++++++++++++++
 slirp/ip6_input.c   |  76 ++++++++++
 slirp/ip6_output.c  |  41 ++++++
 slirp/ip_icmp.c     |  12 +-
 slirp/ip_icmp.h     |   4 +-
 slirp/ip_input.c    |  10 +-
 slirp/libslirp.h    |   8 +-
 slirp/mbuf.c        |   3 +-
 slirp/ndp_table.c   |  87 +++++++++++
 slirp/slirp.c       |  78 ++++++++--
 slirp/slirp.h       |  40 ++++-
 slirp/socket.c      |  54 ++++++-
 slirp/socket.h      |  13 ++
 slirp/tcp.h         |   2 +
 slirp/tcp_input.c   | 176 ++++++++++++++++------
 slirp/tcp_output.c  |  51 +++++--
 slirp/tcp_subr.c    | 117 +++++++++++----
 slirp/tcp_timer.c   |   3 +-
 slirp/tcpip.h       |  40 ++++-
 slirp/udp.c         |   3 +-
 slirp/udp.h         |   5 +
 slirp/udp6.c        | 150 +++++++++++++++++++
 32 files changed, 1793 insertions(+), 158 deletions(-)
 create mode 100644 slirp/ip6.h
 create mode 100644 slirp/ip6_icmp.c
 create mode 100644 slirp/ip6_icmp.h
 create mode 100644 slirp/ip6_input.c
 create mode 100644 slirp/ip6_output.c
 create mode 100644 slirp/ndp_table.c
 create mode 100644 slirp/udp6.c

-- 
2.7.0

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2016-02-08 10:29 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-19 21:24 [Qemu-devel] [PATCHv7 0/9] slirp: Adding IPv6 support to Qemu -net user mode Samuel Thibault
2015-12-19 21:24 ` [Qemu-devel] [PATCH 1/9] slirp: goto bad in udp_input if sosendto fails Samuel Thibault
2015-12-19 21:24   ` [Qemu-devel] [PATCH 2/9] slirp: Generalizing and neutralizing ARP code Samuel Thibault
2015-12-19 21:24   ` [Qemu-devel] [PATCH 3/9] slirp: Adding address family switch for produced frames Samuel Thibault
2015-12-19 21:24   ` [Qemu-devel] [PATCH 4/9] slirp: Make Socket structure IPv6 compatible Samuel Thibault
2015-12-19 21:24   ` [Qemu-devel] [PATCH 5/9] slirp: Factorizing address translation Samuel Thibault
2015-12-19 21:25   ` [Qemu-devel] [PATCH 6/9] slirp: Factorizing and cleaning solookup() Samuel Thibault
2015-12-19 21:25   ` [Qemu-devel] [PATCH 7/9] slirp: Add sockaddr_equal, make solookup family-agnostic Samuel Thibault
2015-12-19 21:25   ` [Qemu-devel] [PATCH 8/9] slirp: Make udp_attach IPv6 compatible Samuel Thibault
2015-12-19 21:25   ` [Qemu-devel] [PATCH 9/9] slirp: Adding family argument to tcp_fconnect() Samuel Thibault
2015-12-21 15:30 ` [Qemu-devel] [PATCHv7 0/9] slirp: Adding IPv6 support to Qemu -net user mode Eric Blake
2016-01-11 15:04 ` Samuel Thibault
2016-01-12  2:22   ` Hailiang Zhang
2016-01-12  4:04     ` Jason Wang
2016-01-18  8:14       ` Jason Wang
2016-02-08 10:28 Samuel Thibault

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).