From patchwork Mon Feb 8 10:28:58 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Thibault X-Patchwork-Id: 8247641 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 7F5A39F6DA for ; Mon, 8 Feb 2016 10:34:32 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 621F820396 for ; Mon, 8 Feb 2016 10:34:31 +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 1BC76201C8 for ; Mon, 8 Feb 2016 10:34:30 +0000 (UTC) Received: from localhost ([::1]:43277 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aSj9J-0003Y0-Gw for patchwork-qemu-devel@patchwork.kernel.org; Mon, 08 Feb 2016 05:34:29 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55205) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aSj48-0003X4-CA for qemu-devel@nongnu.org; Mon, 08 Feb 2016 05:29:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aSj45-0006HT-N0 for qemu-devel@nongnu.org; Mon, 08 Feb 2016 05:29:08 -0500 Received: from mail3-relais-sop.national.inria.fr ([192.134.164.104]:48423) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aSj44-0006Gp-Uc for qemu-devel@nongnu.org; Mon, 08 Feb 2016 05:29:05 -0500 X-IronPort-AV: E=Sophos;i="5.22,415,1449529200"; d="scan'208";a="163814478" Received: from unknown (HELO var.youpi.perso.aquilenet.fr) ([193.50.110.192]) by mail3-relais-sop.national.inria.fr with ESMTP/TLS/AES128-GCM-SHA256; 08 Feb 2016 11:29:01 +0100 Received: from samy by var.youpi.perso.aquilenet.fr with local (Exim 4.86) (envelope-from ) id 1aSj40-0007qk-J8; Mon, 08 Feb 2016 11:29:00 +0100 From: Samuel Thibault To: qemu-devel@nongnu.org Date: Mon, 8 Feb 2016 11:28:58 +0100 Message-Id: <84232dbd5f99c4d811f64a2451df894220efe6a2.1454927009.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 , Yann Bordenave , Gonglei , Jan Kiszka , Samuel Thibault , Yang Hongyang , Guillaume Subiron Subject: [Qemu-devel] [PATCHv7 9/9] qapi-schema, qemu-options & slirp: Adding Qemu options for IPv6 addresses 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: Yann Bordenave This patch adds parameters to manage some new options in the qemu -net command. Slirp IPv6 address, network prefix, and DNS IPv6 address can be given in argument to the qemu command. Defaults parameters are respectively fec0::2, fec0::, /64 and fec0::3. Signed-off-by: Yann Bordenave Signed-off-by: Samuel Thibault --- net/net.c | 31 +++++++++++++++++++++++++++++++ net/slirp.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------ qapi-schema.json | 40 ++++++++++++++++++++++++++-------------- qemu-options.hx | 18 ++++++++++++++++-- slirp/libslirp.h | 8 +++++--- slirp/slirp.c | 16 +++++++++------- 6 files changed, 131 insertions(+), 32 deletions(-) diff --git a/net/net.c b/net/net.c index c5e414f..0ececcb 100644 --- a/net/net.c +++ b/net/net.c @@ -1060,6 +1060,37 @@ int net_client_init(QemuOpts *opts, int is_netdev, Error **errp) int ret = -1; { + /* Parse convenience option format ip6-net=fec0::0[/64] */ + const char *ip6_net = qemu_opt_get(opts, "ip6-net"); + + if (ip6_net) { + char buf[strlen(ip6_net)+1]; + + if (get_str_sep(buf, sizeof(buf), &ip6_net, '/') < 0) { + /* Default 64bit prefix length. */ + qemu_opt_set(opts, "ip6-prefix", ip6_net, &error_abort); + qemu_opt_set_number(opts, "ip6-prefixlen", 64, &error_abort); + } else { + /* User-specified prefix length. */ + int len; + char *end; + + qemu_opt_set(opts, "ip6-prefix", buf, &error_abort); + len = strtol(ip6_net, &end, 10); + + if (*end != '\0') { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + "ip6-prefix", "a number"); + } else { + qemu_opt_set_number(opts, "ip6-prefixlen", len, + &error_abort); + } + } + qemu_opt_unset(opts, "ip6-net"); + } + } + + { OptsVisitor *ov = opts_visitor_new(opts); net_visit(opts_get_visitor(ov), is_netdev, &object, &err); diff --git a/net/slirp.c b/net/slirp.c index 6b51fbc..076dd27 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -135,17 +135,23 @@ static NetClientInfo net_slirp_info = { static int net_slirp_init(NetClientState *peer, const char *model, const char *name, int restricted, const char *vnetwork, const char *vhost, + const char *vprefix6, int vprefix6_len, + const char *vhost6, const char *vhostname, const char *tftp_export, const char *bootfile, const char *vdhcp_start, - const char *vnameserver, const char *smb_export, - const char *vsmbserver, const char **dnssearch) + const char *vnameserver, const char *vnameserver6, + const char *smb_export, const char *vsmbserver, + const char **dnssearch) { /* default settings according to historic slirp */ struct in_addr net = { .s_addr = htonl(0x0a000200) }; /* 10.0.2.0 */ struct in_addr mask = { .s_addr = htonl(0xffffff00) }; /* 255.255.255.0 */ struct in_addr host = { .s_addr = htonl(0x0a000202) }; /* 10.0.2.2 */ + struct in6_addr ip6_prefix; + struct in6_addr ip6_host; struct in_addr dhcp = { .s_addr = htonl(0x0a00020f) }; /* 10.0.2.15 */ struct in_addr dns = { .s_addr = htonl(0x0a000203) }; /* 10.0.2.3 */ + struct in6_addr ip6_dns; #ifndef _WIN32 struct in_addr smbsrv = { .s_addr = 0 }; #endif @@ -213,6 +219,27 @@ static int net_slirp_init(NetClientState *peer, const char *model, return -1; } + if (!vprefix6) { + vprefix6 = "fec0::"; + } + if (!inet_pton(AF_INET6, vprefix6, &ip6_prefix)) { + return -1; + } + + if (!vprefix6_len) { + vprefix6_len = 64; + } + if (vprefix6_len < 0 || vprefix6_len > 128) { + return -1; + } + + if (!vhost6) { + vhost6 = "fec0::2"; + } + if (!inet_pton(AF_INET6, vhost6, &ip6_host)) { + return -1; + } + if (vnameserver && !inet_aton(vnameserver, &dns)) { return -1; } @@ -221,6 +248,13 @@ static int net_slirp_init(NetClientState *peer, const char *model, return -1; } + if (!vnameserver6) { + vnameserver6 = "fec0::3"; + } + if (!inet_pton(AF_INET6, vnameserver6, &ip6_dns)) { + return -1; + } + if (vdhcp_start && !inet_aton(vdhcp_start, &dhcp)) { return -1; } @@ -243,8 +277,10 @@ static int net_slirp_init(NetClientState *peer, const char *model, s = DO_UPCAST(SlirpState, nc, nc); - s->slirp = slirp_init(restricted, net, mask, host, vhostname, - tftp_export, bootfile, dhcp, dns, dnssearch, s); + s->slirp = slirp_init(restricted, net, mask, host, + ip6_prefix, vprefix6_len, ip6_host, + vhostname, tftp_export, bootfile, dhcp, + dns, ip6_dns, dnssearch, s); QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry); for (config = slirp_configs; config; config = config->next) { @@ -761,8 +797,10 @@ int net_init_slirp(const NetClientOptions *opts, const char *name, net_init_slirp_configs(user->guestfwd, 0); ret = net_slirp_init(peer, "user", name, user->q_restrict, vnet, - user->host, user->hostname, user->tftp, - user->bootfile, user->dhcpstart, user->dns, user->smb, + user->host, user->ip6_prefix, user->ip6_prefixlen, + user->ip6_host, user->hostname, user->tftp, + user->bootfile, user->dhcpstart, + user->dns, user->ip6_dns, user->smb, user->smbserver, dnssearch); while (slirp_configs) { diff --git a/qapi-schema.json b/qapi-schema.json index 8d04897..cba041e 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -2399,6 +2399,14 @@ # @dnssearch: #optional list of DNS suffixes to search, passed as DHCP option # to the guest # +# @ip6-prefix: #optional IPv6 network prefix (since 2.6) +# +# @ip6-prefixlen: #optional IPv6 network prefix length (since 2.6) +# +# @ip6-host: #optional guest-visible IPv6 address of the host (since 2.6) +# +# @ip6-dns: #optional guest-visible IPv6 address of the virtual nameserver (since 2.6) +# # @smb: #optional root directory of the built-in SMB server # # @smbserver: #optional IP address of the built-in SMB server @@ -2412,20 +2420,24 @@ ## { 'struct': 'NetdevUserOptions', 'data': { - '*hostname': 'str', - '*restrict': 'bool', - '*ip': 'str', - '*net': 'str', - '*host': 'str', - '*tftp': 'str', - '*bootfile': 'str', - '*dhcpstart': 'str', - '*dns': 'str', - '*dnssearch': ['String'], - '*smb': 'str', - '*smbserver': 'str', - '*hostfwd': ['String'], - '*guestfwd': ['String'] } } + '*hostname': 'str', + '*restrict': 'bool', + '*ip': 'str', + '*net': 'str', + '*host': 'str', + '*tftp': 'str', + '*bootfile': 'str', + '*dhcpstart': 'str', + '*dns': 'str', + '*dnssearch': ['String'], + '*ip6-prefix': 'str', + '*ip6-prefixlen': 'int', + '*ip6-host': 'str', + '*ip6-dns': 'str', + '*smb': 'str', + '*smbserver': 'str', + '*hostfwd': ['String'], + '*guestfwd': ['String'] } } ## # @NetdevTapOptions diff --git a/qemu-options.hx b/qemu-options.hx index 733a194..de9e314 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1542,8 +1542,9 @@ DEF("smb", HAS_ARG, QEMU_OPTION_smb, "", QEMU_ARCH_ALL) DEF("netdev", HAS_ARG, QEMU_OPTION_netdev, #ifdef CONFIG_SLIRP - "-netdev user,id=str[,net=addr[/mask]][,host=addr][,restrict=on|off]\n" - " [,hostname=host][,dhcpstart=addr][,dns=addr][,dnssearch=domain][,tftp=dir]\n" + "-netdev user,id=str[,net=addr[/mask]][,host=addr][,ip6-net=addr[/int]]\n" + " [,ip6-host=addr][,restrict=on|off][,hostname=host][,dhcpstart=addr]\n" + " [,dns=addr][,ip6-dns=addr][,dnssearch=domain][,tftp=dir]\n" " [,bootfile=f][,hostfwd=rule][,guestfwd=rule]" #ifndef _WIN32 "[,smb=dir[,smbserver=addr]]\n" @@ -1700,6 +1701,14 @@ either in the form a.b.c.d or as number of valid top-most bits. Default is Specify the guest-visible address of the host. Default is the 2nd IP in the guest network, i.e. x.x.x.2. +@item ip6-net=@var{addr}[/@var{int}] +Set IPv6 network address the guest will see. Optionally specify the prefix +size, as number of valid top-most bits. Default is fec0::/64. + +@item ip6-host=@var{addr} +Specify the guest-visible IPv6 address of the host. Default is the 2nd IPv6 in +the guest network, i.e. xxxx::2. + @item restrict=on|off If this option is enabled, the guest will be isolated, i.e. it will not be able to contact the host and no guest IP packets will be routed over the host @@ -1717,6 +1726,11 @@ Specify the guest-visible address of the virtual nameserver. The address must be different from the host address. Default is the 3rd IP in the guest network, i.e. x.x.x.3. +@item ip6-dns=@var{addr} +Specify the guest-visible address of the IPv6 virtual nameserver. The address +must be different from the host address. Default is the 3rd IP in the guest +network, i.e. xxxx::3. + @item dnssearch=@var{domain} Provides an entry for the domain-search list sent by the built-in DHCP server. More than one domain suffix can be transmitted by specifying diff --git a/slirp/libslirp.h b/slirp/libslirp.h index 5bdcbd5..c4b25c9 100644 --- a/slirp/libslirp.h +++ b/slirp/libslirp.h @@ -10,9 +10,11 @@ int get_dns_addr(struct in_addr *pdns_addr); Slirp *slirp_init(int restricted, struct in_addr vnetwork, struct in_addr vnetmask, struct in_addr vhost, - const char *vhostname, const char *tftp_path, - const char *bootfile, struct in_addr vdhcp_start, - struct in_addr vnameserver, const char **vdnssearch, + struct in6_addr vprefix_addr6, uint8_t vprefix_len, + struct in6_addr vhost6, const char *vhostname, + const char *tftp_path, const char *bootfile, + struct in_addr vdhcp_start, struct in_addr vnameserver, + struct in6_addr vnameserver6, const char **vdnssearch, void *opaque); void slirp_cleanup(Slirp *slirp); diff --git a/slirp/slirp.c b/slirp/slirp.c index 4d6203a..c09c7cc 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -201,9 +201,11 @@ static int slirp_state_load(QEMUFile *f, void *opaque, int version_id); Slirp *slirp_init(int restricted, struct in_addr vnetwork, struct in_addr vnetmask, struct in_addr vhost, - const char *vhostname, const char *tftp_path, - const char *bootfile, struct in_addr vdhcp_start, - struct in_addr vnameserver, const char **vdnssearch, + struct in6_addr vprefix_addr6, uint8_t vprefix_len, + struct in6_addr vhost6, const char *vhostname, + const char *tftp_path, const char *bootfile, + struct in_addr vdhcp_start, struct in_addr vnameserver, + struct in6_addr vnameserver6, const char **vdnssearch, void *opaque) { Slirp *slirp = g_malloc0(sizeof(Slirp)); @@ -222,9 +224,9 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork, slirp->vnetwork_addr = vnetwork; slirp->vnetwork_mask = vnetmask; slirp->vhost_addr = vhost; - inet_pton(AF_INET6, "fec0::0", &slirp->vprefix_addr6); - slirp->vprefix_len = 64; - inet_pton(AF_INET6, "fec0::2", &slirp->vhost_addr6); + slirp->vprefix_addr6 = vprefix_addr6; + slirp->vprefix_len = vprefix_len; + slirp->vhost_addr6 = vhost6; if (vhostname) { pstrcpy(slirp->client_hostname, sizeof(slirp->client_hostname), vhostname); @@ -233,7 +235,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); + slirp->vnameserver_addr6 = vnameserver6; if (vdnssearch) { translate_dnssearch(slirp, vdnssearch);