From patchwork Tue Mar 15 16:11:54 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Thibault X-Patchwork-Id: 8590291 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D31E09F6E1 for ; Tue, 15 Mar 2016 16:14:21 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1CF47202E6 for ; Tue, 15 Mar 2016 16:14:21 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2BAF120251 for ; Tue, 15 Mar 2016 16:14:20 +0000 (UTC) Received: from localhost ([::1]:49800 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1afrbv-0001xJ-Ey for patchwork-qemu-devel@patchwork.kernel.org; Tue, 15 Mar 2016 12:14:19 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58479) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1afrZq-0006oX-Dd for qemu-devel@nongnu.org; Tue, 15 Mar 2016 12:12:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1afrZk-0005De-4J for qemu-devel@nongnu.org; Tue, 15 Mar 2016 12:12:10 -0400 Received: from mail3-relais-sop.national.inria.fr ([192.134.164.104]:36246) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1afrZj-0005Ag-U8 for qemu-devel@nongnu.org; Tue, 15 Mar 2016 12:12:04 -0400 X-IronPort-AV: E=Sophos;i="5.24,340,1454972400"; d="scan'208";a="168774068" Received: from unknown (HELO var.youpi.perso.aquilenet.fr) ([193.50.110.180]) by mail3-relais-sop.national.inria.fr with ESMTP/TLS/AES128-GCM-SHA256; 15 Mar 2016 17:12:00 +0100 Received: from samy by var.youpi.perso.aquilenet.fr with local (Exim 4.86_2) (envelope-from ) id 1afrZg-0004WK-0R; Tue, 15 Mar 2016 17:12:00 +0100 From: Samuel Thibault To: qemu-devel@nongnu.org, Peter Maydell Date: Tue, 15 Mar 2016 17:11:54 +0100 Message-Id: <05061d8548598c92bda94de0c6159732e75da719.1458058240.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: Genre and OS details not recognized. X-Received-From: 192.134.164.104 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] [PULL 09/11] 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+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 Reviewed-by: Thomas Huth --- slirp/ip6.h | 6 +++++- slirp/slirp.c | 3 +++ slirp/slirp.h | 1 + slirp/socket.c | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/slirp/ip6.h b/slirp/ip6.h index 731ee72..8ddfa24 100644 --- a/slirp/ip6.h +++ b/slirp/ip6.h @@ -72,7 +72,11 @@ 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_mach(a, &slirp->vnameserver_addr6, slirp->vprefix_len))\ + || (in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64)\ + && in6_equal_mach(a, &slirp->vnameserver_addr6, 64))) #define in6_equal_host(a)\ (in6_equal_router(a) || in6_equal_dns(a)) diff --git a/slirp/slirp.c b/slirp/slirp.c index 50b36f4..7a47bb6 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -231,10 +231,13 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork, slirp->vprefix_len = 64; slirp->vhost_addr6 = slirp->vprefix_addr6; slirp->vhost_addr6.s6_addr[15] = 0x2; + slirp->vnameserver_addr6 = slirp->vprefix_addr6; + slirp->vnameserver_addr6.s6_addr[15] = 0x3; #else inet_pton(AF_INET6, "fec0::0", &slirp->vprefix_addr6); slirp->vprefix_len = 64; inet_pton(AF_INET6, "fec0::2", &slirp->vhost_addr6); + inet_pton(AF_INET6, "fec0::3", &slirp->vnameserver_addr6); #endif if (vhostname) { pstrcpy(slirp->client_hostname, sizeof(slirp->client_hostname), diff --git a/slirp/slirp.h b/slirp/slirp.h index 2850ef1..71f2439 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -212,6 +212,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 8df9252..b836c42 100644 --- a/slirp/socket.c +++ b/slirp/socket.c @@ -771,6 +771,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: @@ -791,6 +792,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; } @@ -800,6 +814,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: @@ -816,6 +831,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; } @@ -837,6 +862,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; }