From patchwork Thu Mar 24 21:00:45 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Thibault X-Patchwork-Id: 8664841 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id B7EA1C0553 for ; Thu, 24 Mar 2016 21:01:06 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id AB43C202E5 for ; Thu, 24 Mar 2016 21:01:05 +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 54FD3202BE for ; Thu, 24 Mar 2016 21:01:04 +0000 (UTC) Received: from localhost ([::1]:52739 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ajCNL-0002JT-RY for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Mar 2016 17:01:03 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33508) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ajCNA-0002Hh-K9 for qemu-devel@nongnu.org; Thu, 24 Mar 2016 17:00:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ajCN7-00031v-Bc for qemu-devel@nongnu.org; Thu, 24 Mar 2016 17:00:52 -0400 Received: from domu-toccata.ens-lyon.fr ([140.77.166.138]:57204 helo=sonata.ens-lyon.org) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ajCN7-00031a-0o for qemu-devel@nongnu.org; Thu, 24 Mar 2016 17:00:49 -0400 Received: from localhost (localhost [127.0.0.1]) by sonata.ens-lyon.org (Postfix) with ESMTP id 0F6A120116; Thu, 24 Mar 2016 22:00:47 +0100 (CET) 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 Kxy-8akqDeIh; Thu, 24 Mar 2016 22:00:46 +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 CDCED20114; Thu, 24 Mar 2016 22:00:46 +0100 (CET) Received: from samy by var.youpi.perso.aquilenet.fr with local (Exim 4.86_2) (envelope-from ) id 1ajCN4-0001vP-5w; Thu, 24 Mar 2016 22:00:46 +0100 From: Samuel Thibault To: qemu-devel@nongnu.org Date: Thu, 24 Mar 2016 22:00:45 +0100 Message-Id: <1458853245-7363-1-git-send-email-samuel.thibault@ens-lyon.org> X-Mailer: git-send-email 2.8.0.rc3 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 140.77.166.138 Cc: thuth@redhat.com, jan.kiszka@siemens.com, jasowang@redhat.com, armbru@redhat.com, Samuel Thibault Subject: [Qemu-devel] [PATCHv2] slirp: Allow to disable IPv4 or IPv6 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 Make net=none disable IPv4 and ip6-net=none disable IPv6, so the user can setup IPv4-only and IPv6-only network environments. Signed-off-by: Samuel Thibault --- net/slirp.c | 19 +++++++++++++------ qapi-schema.json | 15 +++++++++++++-- qemu-options.hx | 19 ++++++++++++------- slirp/ip6_icmp.c | 8 ++++++++ slirp/ip6_input.c | 5 +++++ slirp/ip_input.c | 4 ++++ slirp/libslirp.h | 3 ++- slirp/slirp.c | 10 +++++++++- slirp/slirp.h | 2 ++ 9 files changed, 68 insertions(+), 17 deletions(-) diff --git a/net/slirp.c b/net/slirp.c index 95239bc..4c9319e 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -135,8 +135,8 @@ 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, + bool ip4, const char *vnetwork, const char *vhost, + bool ip6, const char *vprefix6, int vprefix6_len, const char *vhost6, const char *vhostname, const char *tftp_export, const char *bootfile, const char *vdhcp_start, @@ -164,6 +164,12 @@ static int net_slirp_init(NetClientState *peer, const char *model, char *end; struct slirp_config_str *config; + if (!ip4 && !ip6) { + /* Enable both by default */ + ip4 = 1; + ip6 = 1; + } + if (!tftp_export) { tftp_export = legacy_tftp_prefix; } @@ -308,8 +314,8 @@ static int net_slirp_init(NetClientState *peer, const char *model, s = DO_UPCAST(SlirpState, nc, nc); - s->slirp = slirp_init(restricted, net, mask, host, - ip6_prefix, vprefix6_len, ip6_host, + s->slirp = slirp_init(restricted, ip4, net, mask, host, + ip6, ip6_prefix, vprefix6_len, ip6_host, vhostname, tftp_export, bootfile, dhcp, dns, ip6_dns, dnssearch, s); QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry); @@ -827,8 +833,9 @@ int net_init_slirp(const NetClientOptions *opts, const char *name, net_init_slirp_configs(user->hostfwd, SLIRP_CFG_HOSTFWD); net_init_slirp_configs(user->guestfwd, 0); - ret = net_slirp_init(peer, "user", name, user->q_restrict, vnet, - user->host, user->ip6_prefix, user->ip6_prefixlen, + ret = net_slirp_init(peer, "user", name, user->q_restrict, + user->ip4, vnet, user->host, + user->ip6, user->ip6_prefix, user->ip6_prefixlen, user->ip6_host, user->hostname, user->tftp, user->bootfile, user->dhcpstart, user->dns, user->ip6_dns, user->smb, diff --git a/qapi-schema.json b/qapi-schema.json index 88f9b81..0b693ec 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -2425,9 +2425,16 @@ # # @restrict: #optional isolate the guest from the host # +# @ip4: #optional whether to support IPv4, default is to support both IPv4 and IPv6. +# +# @ip6: #optional whether to support IPv6, default is to support both IPv4 and IPv6. +# # @ip: #optional legacy parameter, use net= instead # -# @net: #optional IP address and optional netmask +# @net: #optional IP network address that the guest will see, in the +# form addr[/netmask] (default is 10.0.2.0/24). The netmask is optional, +# and can be either in the form a.b.c.d or as a number of valid top-most +# bits. # # @host: #optional guest-visible address of the host # @@ -2443,7 +2450,9 @@ # @dnssearch: #optional list of DNS suffixes to search, passed as DHCP option # to the guest # -# @ip6-prefix: #optional IPv6 network prefix (default is fec0::) (since 2.6) +# @ip6-prefix: #optional IPv6 network prefix (default is fec0::) (since +# 2.6). The network prefix is given in the usual hexadecimal IPv6 +# address notation. # # @ip6-prefixlen: #optional IPv6 network prefix length (default is 64) (since 2.6) # @@ -2466,6 +2475,8 @@ 'data': { '*hostname': 'str', '*restrict': 'bool', + '*ip4': 'bool', + '*ip6': 'bool', '*ip': 'str', '*net': 'str', '*host': 'str', diff --git a/qemu-options.hx b/qemu-options.hx index 732ed8c..cc43c32 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1560,8 +1560,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][,ip6-net=addr[/int]]\n" - " [,ip6-host=addr][,restrict=on|off][,hostname=host][,dhcpstart=addr]\n" + "-netdev user,id=str[,ip4][,net=addr[/mask]][,host=addr]\n" + " [,ip6][,ip6-net=addr[/int]][,ip6-host=addr]\n" + " [,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 @@ -1711,17 +1712,21 @@ Connect user mode stack to VLAN @var{n} (@var{n} = 0 is the default). Assign symbolic name for use in monitor commands. @item net=@var{addr}[/@var{mask}] -Set IP network address the guest will see. Optionally specify the netmask, -either in the form a.b.c.d or as number of valid top-most bits. Default is -10.0.2.0/24. +Set IP network address the guest will see or 'none'. Default is +10.0.2.0/24. The netmask is optional, and can be either in the form +a.b.c.d or as number of valid top-most bits. 'none' disables IPv4 +completely. @item host=@var{addr} 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. +Set IPv6 network address the guest will see or 'none' (default is +fec0::/64). The network prefix is given in the usual hexadecimal IPv6 +address notation. The prefix size is optional, and is given as the +number of valid top-most bits (default is 64). 'none' disables IPv6 +completely. @item ip6-host=@var{addr} Specify the guest-visible IPv6 address of the host. Default is the 2nd IPv6 in diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c index 9d61349..09571bc 100644 --- a/slirp/ip6_icmp.c +++ b/slirp/ip6_icmp.c @@ -24,6 +24,10 @@ static void ra_timer_handler(void *opaque) void icmp6_init(Slirp *slirp) { + if (!slirp->in6_enabled) { + return; + } + slirp->ra_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, ra_timer_handler, slirp); timer_mod(slirp->ra_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + NDP_Interval); @@ -31,6 +35,10 @@ void icmp6_init(Slirp *slirp) void icmp6_cleanup(Slirp *slirp) { + if (!slirp->in6_enabled) { + return; + } + timer_del(slirp->ra_timer); timer_free(slirp->ra_timer); } diff --git a/slirp/ip6_input.c b/slirp/ip6_input.c index c0b11e7..ac2e3ea 100644 --- a/slirp/ip6_input.c +++ b/slirp/ip6_input.c @@ -24,6 +24,11 @@ void ip6_cleanup(Slirp *slirp) void ip6_input(struct mbuf *m) { struct ip6 *ip6; + Slirp *slirp = m->slirp; + + if (!slirp->in6_enabled) { + goto bad; + } DEBUG_CALL("ip6_input"); DEBUG_ARG("m = %lx", (long)m); diff --git a/slirp/ip_input.c b/slirp/ip_input.c index b464f6b..cdd5483 100644 --- a/slirp/ip_input.c +++ b/slirp/ip_input.c @@ -80,6 +80,10 @@ ip_input(struct mbuf *m) register struct ip *ip; int hlen; + if (!slirp->in_enabled) { + goto bad; + } + DEBUG_CALL("ip_input"); DEBUG_ARG("m = %p", m); DEBUG_ARG("m_len = %d", m->m_len); diff --git a/slirp/libslirp.h b/slirp/libslirp.h index c4b25c9..127aa41 100644 --- a/slirp/libslirp.h +++ b/slirp/libslirp.h @@ -8,8 +8,9 @@ typedef struct Slirp Slirp; int get_dns_addr(struct in_addr *pdns_addr); -Slirp *slirp_init(int restricted, struct in_addr vnetwork, +Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork, struct in_addr vnetmask, struct in_addr vhost, + bool in6_enabled, struct in6_addr vprefix_addr6, uint8_t vprefix_len, struct in6_addr vhost6, const char *vhostname, const char *tftp_path, const char *bootfile, diff --git a/slirp/slirp.c b/slirp/slirp.c index 9ccf415..6256c89 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -199,8 +199,9 @@ static void slirp_init_once(void) static void slirp_state_save(QEMUFile *f, void *opaque); static int slirp_state_load(QEMUFile *f, void *opaque, int version_id); -Slirp *slirp_init(int restricted, struct in_addr vnetwork, +Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork, struct in_addr vnetmask, struct in_addr vhost, + bool in6_enabled, struct in6_addr vprefix_addr6, uint8_t vprefix_len, struct in6_addr vhost6, const char *vhostname, const char *tftp_path, const char *bootfile, @@ -215,6 +216,9 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork, slirp->grand = g_rand_new(); slirp->restricted = restricted; + slirp->in_enabled = in_enabled; + slirp->in6_enabled = in6_enabled; + if_init(slirp); ip_init(slirp); ip6_init(slirp); @@ -693,6 +697,10 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len) int ar_op; struct ex_list *ex_ptr; + if (!slirp->in_enabled) { + return; + } + ar_op = ntohs(ah->ar_op); switch(ar_op) { case ARPOP_REQUEST: diff --git a/slirp/slirp.h b/slirp/slirp.h index 9ad88e7..0b84027 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -179,6 +179,8 @@ struct Slirp { u_int last_slowtimo; bool do_slowtimo; + bool in_enabled, in6_enabled; + /* virtual network configuration */ struct in_addr vnetwork_addr; struct in_addr vnetwork_mask;