All of lore.kernel.org
 help / color / mirror / Atom feed
From: Samuel Thibault <samuel.thibault@ens-lyon.org>
To: qemu-devel@nongnu.org, peter.maydell@linaro.org
Cc: Samuel Thibault <samuel.thibault@ens-lyon.org>, jan.kiszka@siemens.com
Subject: [Qemu-devel] [PULL] slirp: Allow disabling IPv4 or IPv6
Date: Fri,  1 Apr 2016 17:53:57 +0200	[thread overview]
Message-ID: <1459526037-3089-2-git-send-email-samuel.thibault@ens-lyon.org> (raw)
In-Reply-To: <1459526037-3089-1-git-send-email-samuel.thibault@ens-lyon.org>

Add ipv4 and ipv6 boolean options, so the user can setup IPv4-only and
IPv6-only network environments.

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
---
 net/slirp.c       | 36 ++++++++++++++++++++++++++++++------
 qapi-schema.json  |  8 ++++++++
 qemu-options.hx   |  8 ++++++--
 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, 74 insertions(+), 10 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index 791a8f7..31630f0 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -136,8 +136,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 ipv4, const char *vnetwork, const char *vhost,
+                          bool ipv6, const char *vprefix6, int vprefix6_len,
                           const char *vhost6,
                           const char *vhostname, const char *tftp_export,
                           const char *bootfile, const char *vdhcp_start,
@@ -165,6 +165,19 @@ static int net_slirp_init(NetClientState *peer, const char *model,
     char *end;
     struct slirp_config_str *config;
 
+    if (!ipv4 && (vnetwork || vhost || vnameserver)) {
+        return -1;
+    }
+
+    if (!ipv6 && (vprefix6 || vhost6 || vnameserver6)) {
+        return -1;
+    }
+
+    if (!ipv4 && !ipv6) {
+        /* It doesn't make sense to disable both */
+        return -1;
+    }
+
     if (!tftp_export) {
         tftp_export = legacy_tftp_prefix;
     }
@@ -309,8 +322,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, ipv4, net, mask, host,
+                          ipv6, ip6_prefix, vprefix6_len, ip6_host,
                           vhostname, tftp_export, bootfile, dhcp,
                           dns, ip6_dns, dnssearch, s);
     QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);
@@ -813,10 +826,20 @@ int net_init_slirp(const NetClientOptions *opts, const char *name,
     int ret;
     const NetdevUserOptions *user;
     const char **dnssearch;
+    bool ipv4 = true, ipv6 = true;
 
     assert(opts->type == NET_CLIENT_OPTIONS_KIND_USER);
     user = opts->u.user.data;
 
+    if ((user->has_ipv6 && user->ipv6 && !user->has_ipv4) ||
+        (user->has_ipv4 && !user->ipv4)) {
+        ipv4 = 0;
+    }
+    if ((user->has_ipv4 && user->ipv4 && !user->has_ipv6) ||
+        (user->has_ipv6 && !user->ipv6)) {
+        ipv6 = 0;
+    }
+
     vnet = user->has_net ? g_strdup(user->net) :
            user->has_ip  ? g_strdup_printf("%s/24", user->ip) :
            NULL;
@@ -828,8 +851,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->ipv6_prefix, user->ipv6_prefixlen,
+    ret = net_slirp_init(peer, "user", name, user->q_restrict,
+                         ipv4, vnet, user->host,
+                         ipv6, user->ipv6_prefix, user->ipv6_prefixlen,
                          user->ipv6_host, user->hostname, user->tftp,
                          user->bootfile, user->dhcpstart,
                          user->dns, user->ipv6_dns, user->smb,
diff --git a/qapi-schema.json b/qapi-schema.json
index e58f6a9..54634c4 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2425,6 +2425,12 @@
 #
 # @restrict: #optional isolate the guest from the host
 #
+# @ipv4: #optional whether to support IPv4, default true for enabled
+#        (since 2.6)
+#
+# @ipv6: #optional whether to support IPv6, default true for enabled
+#        (since 2.6)
+#
 # @ip: #optional legacy parameter, use net= instead
 #
 # @net: #optional IP network address that the guest will see, in the
@@ -2473,6 +2479,8 @@
   'data': {
     '*hostname':  'str',
     '*restrict':  'bool',
+    '*ipv4':      'bool',
+    '*ipv6':      'bool',
     '*ip':        'str',
     '*net':       'str',
     '*host':      'str',
diff --git a/qemu-options.hx b/qemu-options.hx
index a770086..789d9f6 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1551,8 +1551,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][,ipv6-net=addr[/int]]\n"
-    "         [,ipv6-host=addr][,restrict=on|off][,hostname=host][,dhcpstart=addr]\n"
+    "-netdev user,id=str[,ipv4[=on|off]][,net=addr[/mask]][,host=addr]\n"
+    "         [,ipv6[=on|off]][,ipv6-net=addr[/int]][,ipv6-host=addr]\n"
+    "         [,restrict=on|off][,hostname=host][,dhcpstart=addr]\n"
     "         [,dns=addr][,ipv6-dns=addr][,dnssearch=domain][,tftp=dir]\n"
     "         [,bootfile=f][,hostfwd=rule][,guestfwd=rule]"
 #ifndef _WIN32
@@ -1701,6 +1702,9 @@ Connect user mode stack to VLAN @var{n} (@var{n} = 0 is the default).
 @itemx name=@var{name}
 Assign symbolic name for use in monitor commands.
 
+@option{ipv4} and @option{ipv6} specify that either IPv4 or IPv6 must
+be enabled.  If neither is specified both protocols are enabled.
+
 @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
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 998f278..fef526c 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -200,8 +200,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,
@@ -216,6 +217,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);
@@ -694,6 +698,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 1abbcc6..c99ebb9 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -180,6 +180,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;
-- 
2.8.0.rc3

  reply	other threads:[~2016-04-01 15:54 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-01 15:53 [Qemu-devel] [PULL] slirp updates Samuel Thibault
2016-04-01 15:53 ` Samuel Thibault [this message]
2016-04-04 12:29 ` Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1459526037-3089-2-git-send-email-samuel.thibault@ens-lyon.org \
    --to=samuel.thibault@ens-lyon.org \
    --cc=jan.kiszka@siemens.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.