diff mbox

[PATCHv7,8/9] slirp: Adding IPv6 address for DNS relay

Message ID 7921dd1416882a2ebee89a18a3f966fcbe2c5b49.1454927009.git.samuel.thibault@ens-lyon.org (mailing list archive)
State New, archived
Headers show

Commit Message

Samuel Thibault Feb. 8, 2016, 10:28 a.m. UTC
From: Guillaume Subiron <maethor@subiron.org>

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.

For now this only points to localhost. Further development will be needed to
automatically fetch the IPv6 address from resolv.conf, and announce this via
RDNSS.

Signed-off-by: Guillaume Subiron <maethor@subiron.org>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 slirp/ip6.h    |  5 ++++-
 slirp/slirp.c  |  1 +
 slirp/slirp.h  |  1 +
 slirp/socket.c | 32 ++++++++++++++++++++++++++++++++
 4 files changed, 38 insertions(+), 1 deletion(-)
diff mbox

Patch

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 cca5a80..4d6203a 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -233,6 +233,7 @@  Slirp *slirp_init(int restricted, struct in_addr vnetwork,
     slirp->bootp_filename = g_strdup(bootfile);
     slirp->vdhcp_startaddr = vdhcp_start;
     slirp->vnameserver_addr = vnameserver;
+    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 3261815..88d9be1 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -230,6 +230,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 d4b02c8..5d4930a 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -747,6 +747,7 @@  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,6 +768,19 @@  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;
     }
@@ -776,6 +790,7 @@  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:
@@ -792,6 +807,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;
     }
@@ -813,6 +838,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;
     }