All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jason Wang <jasowang@redhat.com>
To: peter.maydell@linaro.org, qemu-devel@nongnu.org
Cc: Samuel Thibault <samuel.thibault@ens-lyon.org>,
	Jason Wang <jasowang@redhat.com>,
	Guillaume Subiron <maethor@subiron.org>
Subject: [Qemu-devel] [PULL 08/17] slirp: Make Socket structure IPv6 compatible
Date: Tue,  2 Feb 2016 10:36:12 +0800	[thread overview]
Message-ID: <1454380581-7881-9-git-send-email-jasowang@redhat.com> (raw)
In-Reply-To: <1454380581-7881-1-git-send-email-jasowang@redhat.com>

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>
Signed-off-by: Jason Wang <jasowang@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.5.0

  parent reply	other threads:[~2016-02-02  2:37 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-02  2:36 [Qemu-devel] [PULL 00/17] Net patches Jason Wang
2016-02-02  2:36 ` [Qemu-devel] [PULL 01/17] net/slirp: Tell the users when they are using deprecated options Jason Wang
2016-02-02  2:36 ` [Qemu-devel] [PULL 02/17] qemu-doc: Do not promote deprecated -smb and -redir options Jason Wang
2016-02-02  2:36 ` [Qemu-devel] [PULL 03/17] net: cadence_gem: check packet size in gem_recieve Jason Wang
2016-02-02  2:36 ` [Qemu-devel] [PULL 04/17] cadence_gem: fix buffer overflow Jason Wang
2016-02-02  2:36 ` [Qemu-devel] [PULL 05/17] slirp: goto bad in udp_input if sosendto fails Jason Wang
2016-02-02  2:36 ` [Qemu-devel] [PULL 06/17] slirp: Generalizing and neutralizing ARP code Jason Wang
2016-02-02  2:36 ` [Qemu-devel] [PULL 07/17] slirp: Adding address family switch for produced frames Jason Wang
2016-02-02  2:36 ` Jason Wang [this message]
2016-02-02  2:36 ` [Qemu-devel] [PULL 09/17] slirp: Factorizing address translation Jason Wang
2016-02-02  2:36 ` [Qemu-devel] [PULL 10/17] slirp: Factorizing and cleaning solookup() Jason Wang
2016-02-02  2:36 ` [Qemu-devel] [PULL 11/17] slirp: Add sockaddr_equal, make solookup family-agnostic Jason Wang
2016-02-02  2:36 ` [Qemu-devel] [PULL 12/17] slirp: Make udp_attach IPv6 compatible Jason Wang
2016-02-02  2:36 ` [Qemu-devel] [PULL 13/17] slirp: Adding family argument to tcp_fconnect() Jason Wang
2016-02-02  2:36 ` [Qemu-devel] [PULL 14/17] e1000: eliminate infinite loops on out-of-bounds transfer start Jason Wang
2016-02-02  2:36 ` [Qemu-devel] [PULL 15/17] net: netmap: use nm_open() to open netmap ports Jason Wang
2016-02-02  2:36 ` [Qemu-devel] [PULL 16/17] net: always walk through filters in reverse if traffic is egress Jason Wang
2016-02-02  2:36 ` [Qemu-devel] [PULL 17/17] net/filter: Fix the output information for command 'info network' Jason Wang
2016-02-02 11:05 ` [Qemu-devel] [PULL 00/17] Net patches Peter Maydell
2016-02-03  4:52   ` Jason Wang
2016-02-03  9:09     ` Samuel Thibault
2016-02-04  8:20       ` Jason Wang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1454380581-7881-9-git-send-email-jasowang@redhat.com \
    --to=jasowang@redhat.com \
    --cc=maethor@subiron.org \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=samuel.thibault@ens-lyon.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.