From patchwork Sun Feb 14 17:47:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Thibault X-Patchwork-Id: 582520 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id E4BE014031F for ; Mon, 15 Feb 2016 04:50:11 +1100 (AEDT) Received: from localhost ([::1]:52429 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aV0oD-00079J-V9 for incoming@patchwork.ozlabs.org; Sun, 14 Feb 2016 12:50:09 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39871) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aV0m1-0002jo-61 for qemu-devel@nongnu.org; Sun, 14 Feb 2016 12:47:54 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aV0ly-0000uk-LA for qemu-devel@nongnu.org; Sun, 14 Feb 2016 12:47:53 -0500 Received: from domu-toccata.ens-lyon.fr ([140.77.166.138]:42667 helo=sonata.ens-lyon.org) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aV0ly-0000uC-99 for qemu-devel@nongnu.org; Sun, 14 Feb 2016 12:47:50 -0500 Received: from localhost (localhost [127.0.0.1]) by sonata.ens-lyon.org (Postfix) with ESMTP id 21BD5200B9; Sun, 14 Feb 2016 18:47:48 +0100 (CET) X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References" Received: from sonata.ens-lyon.org ([127.0.0.1]) by localhost (sonata.ens-lyon.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id XaUme31n0X9m; Sun, 14 Feb 2016 18:47:47 +0100 (CET) Received: from var.youpi.perso.aquilenet.fr (LFbn-1-6757-94.w90-120.abo.wanadoo.fr [90.120.189.94]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by sonata.ens-lyon.org (Postfix) with ESMTPSA id 0F243200C5; Sun, 14 Feb 2016 18:47:45 +0100 (CET) Received: from samy by var.youpi.perso.aquilenet.fr with local (Exim 4.86) (envelope-from ) id 1aV0ls-0007nd-Hb; Sun, 14 Feb 2016 18:47:44 +0100 From: Samuel Thibault To: qemu-devel@nongnu.org Date: Sun, 14 Feb 2016 18:47:42 +0100 Message-Id: <043b3b699753317c270087536c8d239aae2432eb.1455471945.git.samuel.thibault@ens-lyon.org> X-Mailer: git-send-email 2.7.0 In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 140.77.166.138 Cc: Thomas Huth , zhanghailiang , Li Zhijian , Stefan Hajnoczi , Jason Wang , Dave Gilbert , Vasiliy Tolstov , Huangpeng , Gonglei , Jan Kiszka , Samuel Thibault , Guillaume Subiron Subject: [Qemu-devel] [PATCHv7 8/9] slirp: Adding IPv6 address for DNS relay X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Guillaume Subiron 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 Signed-off-by: Samuel Thibault --- slirp/ip6.h | 5 ++++- slirp/slirp.c | 1 + slirp/slirp.h | 1 + slirp/socket.c | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/slirp/ip6.h b/slirp/ip6.h index 9f7623f..ded6d78 100644 --- a/slirp/ip6.h +++ b/slirp/ip6.h @@ -70,7 +70,10 @@ static inline bool in6_equal_mach(const struct in6_addr *a, || (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 2321c41..9e7e3a6 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -234,6 +234,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 967d93e..a830353 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -232,6 +232,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..0661fa9 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; }