qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 17/18] slirp: Adding IPv6 address for DNS relay


From: Samuel Thibault
Subject: [Qemu-devel] [PATCH 17/18] slirp: Adding IPv6 address for DNS relay
Date: Fri, 11 Dec 2015 01:15:29 +0100

From: Guillaume Subiron <address@hidden>

This patch adds an IPv6 address to the DNS relay. in6_equal_dns() is
developed using this Slirp attribute.
sotranslate_in/out/accept() are also updated to manage the IPv6 case so the
guest can be able to join the host using one of the Slirp addresses.

Signed-off-by: Guillaume Subiron <address@hidden>
Signed-off-by: Samuel Thibault <address@hidden>
---
 slirp/ip6.h    |  5 ++++-
 slirp/slirp.c  |  2 ++
 slirp/slirp.h  |  1 +
 slirp/socket.c | 35 ++++++++++++++++++++++++++++++++---
 4 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/slirp/ip6.h b/slirp/ip6.h
index 9e65acd..c799421 100644
--- a/slirp/ip6.h
+++ b/slirp/ip6.h
@@ -74,7 +74,10 @@ static inline int in6_equal_mach(struct in6_addr a, struct 
in6_addr b,
   || (in6_equal_net(a, (struct in6_addr)LINKLOCAL_ADDR, 64)\
       && in6_equal_mach(a, slirp->vhost_addr6, 64)))
 
-#define in6_equal_dns(a) 0
+#define in6_equal_dns(a)\
+    ((in6_equal_net(a, slirp->vprefix_addr6, slirp->vprefix_len)\
+     || in6_equal_net(a, (struct in6_addr)LINKLOCAL_ADDR, 64))\
+     && in6_equal_mach(a, slirp->vnameserver_addr6, slirp->vprefix_len))
 
 #define in6_equal_host(a)\
     (in6_equal_router(a) || in6_equal_dns(a))
diff --git a/slirp/slirp.c b/slirp/slirp.c
index d8a4de0..b7c5f2c 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -234,6 +234,8 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork,
     slirp->bootp_filename = g_strdup(bootfile);
     slirp->vdhcp_startaddr = vdhcp_start;
     slirp->vnameserver_addr = vnameserver;
+    /* :TODO:maethor:130311: Use a parameter passed to the function */
+    inet_pton(AF_INET6, "fec0::3", &slirp->vnameserver_addr6);
 
     if (vdnssearch) {
         translate_dnssearch(slirp, vdnssearch);
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 1c3acb5..3400712 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -236,6 +236,7 @@ struct Slirp {
     struct in6_addr vhost_addr6;
     struct in_addr vdhcp_startaddr;
     struct in_addr vnameserver_addr;
+    struct in6_addr vnameserver_addr6;
 
     struct in_addr client_ipaddr;
     char client_hostname[33];
diff --git a/slirp/socket.c b/slirp/socket.c
index 6960b47..3244ea9 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -741,12 +741,12 @@ sofwdrain(struct socket *so)
 
 /*
  * Translate addr in host addr when it is a virtual address
- * :TODO:maethor:130314: Manage IPv6
  */
 void sotranslate_out(struct socket *so, struct sockaddr_storage *addr)
 {
     Slirp *slirp = so->slirp;
     struct sockaddr_in *sin = (struct sockaddr_in *)addr;
+    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
 
     switch (addr->ss_family) {
     case AF_INET:
@@ -767,16 +767,29 @@ void sotranslate_out(struct socket *so, struct 
sockaddr_storage *addr)
             ntohs(sin->sin_port), inet_ntoa(sin->sin_addr)));
         break;
 
+    case AF_INET6:
+        if (in6_equal_net(so->so_faddr6, slirp->vprefix_addr6,
+                    slirp->vprefix_len)) {
+            if (in6_equal(so->so_faddr6, slirp->vnameserver_addr6)) {
+                /*if (get_dns_addr(&addr) < 0) {*/ /* TODO */
+                    sin6->sin6_addr = in6addr_loopback;
+                /*}*/
+            } else {
+                sin6->sin6_addr = in6addr_loopback;
+            }
+        }
+        break;
+
     default:
         break;
     }
 }
 
-/* :TODO:maethor:130314: IPv6 */
 void sotranslate_in(struct socket *so, struct sockaddr_storage *addr)
 {
     Slirp *slirp = so->slirp;
     struct sockaddr_in *sin = (struct sockaddr_in *)addr;
+    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
 
     switch (addr->ss_family) {
     case AF_INET:
@@ -793,6 +806,16 @@ void sotranslate_in(struct socket *so, struct 
sockaddr_storage *addr)
         }
         break;
 
+    case AF_INET6:
+        if (in6_equal_net(so->so_faddr6, slirp->vprefix_addr6,
+                    slirp->vprefix_len)) {
+            if (in6_equal(sin6->sin6_addr, in6addr_loopback)
+                    || !in6_equal(so->so_faddr6, slirp->vhost_addr6)) {
+                sin6->sin6_addr = so->so_faddr6;
+            }
+        }
+        break;
+
     default:
         break;
     }
@@ -800,7 +823,6 @@ void sotranslate_in(struct socket *so, struct 
sockaddr_storage *addr)
 
 /*
  * Translate connections from localhost to the real hostname
- * :TODO: IPv6
  */
 void sotranslate_accept(struct socket *so)
 {
@@ -815,6 +837,13 @@ void sotranslate_accept(struct socket *so)
         }
         break;
 
+   case AF_INET6:
+        if (in6_equal(so->so_faddr6, in6addr_any) ||
+                in6_equal(so->so_faddr6, in6addr_loopback)) {
+           so->so_faddr6 = slirp->vhost_addr6;
+        }
+        break;
+
     default:
         break;
     }
-- 
2.6.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]