]> git.proxmox.com Git - qemu.git/commitdiff
net: add a vnet_hdr=on|off parameter
authorMark McLoughlin <markmc@redhat.com>
Thu, 22 Oct 2009 16:43:37 +0000 (17:43 +0100)
committerAnthony Liguori <aliguori@us.ibm.com>
Tue, 27 Oct 2009 17:29:00 +0000 (12:29 -0500)
This allows people to disable the IFF_VNET_HDR flag, e.g. for debugging
purposes or if they know they may migrate the guest to a machine without
IFF_VNET_HDR support.

It also allows making the lack of IFF_VNET_HDR support an error
condition, e.g. in the case where a guest is being migrated from a host
which does support it.

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
net.c
qemu-options.hx

diff --git a/net.c b/net.c
index 8d35b91de52229111d7d45e91b31f44383ee15b5..3d9426016864a08608033242c51c6b238f5c97e0 100644 (file)
--- a/net.c
+++ b/net.c
@@ -1494,7 +1494,8 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
 }
 
 #if defined (CONFIG_BSD) || defined (__FreeBSD_kernel__)
-static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
+static int tap_open(char *ifname, int ifname_size,
+                    int *vnet_hdr, int vnet_hdr_required)
 {
     int fd;
     char *dev;
@@ -1636,7 +1637,8 @@ static int tap_alloc(char *dev, size_t dev_size)
     return tap_fd;
 }
 
-static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
+static int tap_open(char *ifname, int ifname_size,
+                    int *vnet_hdr, int vnet_hdr_required)
 {
     char  dev[10]="";
     int fd;
@@ -1649,13 +1651,15 @@ static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
     return fd;
 }
 #elif defined (_AIX)
-static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
+static int tap_open(char *ifname, int ifname_size,
+                    int *vnet_hdr, int vnet_hdr_required)
 {
     fprintf (stderr, "no tap on AIX\n");
     return -1;
 }
 #else
-static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
+static int tap_open(char *ifname, int ifname_size,
+                    int *vnet_hdr, int vnet_hdr_required)
 {
     struct ifreq ifr;
     int fd, ret;
@@ -1668,7 +1672,7 @@ static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
     memset(&ifr, 0, sizeof(ifr));
     ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
 
-    {
+    if (*vnet_hdr) {
         unsigned int features;
 
         if (ioctl(fd, TUNGETFEATURES, &features) == 0 &&
@@ -1676,6 +1680,13 @@ static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
             *vnet_hdr = 1;
             ifr.ifr_flags |= IFF_VNET_HDR;
         }
+
+        if (vnet_hdr_required && !*vnet_hdr) {
+            qemu_error("vnet_hdr=1 requested, but no kernel "
+                       "support for IFF_VNET_HDR available");
+            close(fd);
+            return -1;
+        }
     }
 
     if (ifname[0] != '\0')
@@ -1740,7 +1751,7 @@ static int launch_script(const char *setup_script, const char *ifname, int fd)
 
 static int net_tap_init(QemuOpts *opts, int *vnet_hdr)
 {
-    int fd;
+    int fd, vnet_hdr_required;
     char ifname[128] = {0,};
     const char *setup_script;
 
@@ -1748,8 +1759,14 @@ static int net_tap_init(QemuOpts *opts, int *vnet_hdr)
         pstrcpy(ifname, sizeof(ifname), qemu_opt_get(opts, "ifname"));
     }
 
-    *vnet_hdr = 0;
-    TFR(fd = tap_open(ifname, sizeof(ifname), vnet_hdr));
+    *vnet_hdr = qemu_opt_get_bool(opts, "vnet_hdr", 1);
+    if (qemu_opt_get(opts, "vnet_hdr")) {
+        vnet_hdr_required = *vnet_hdr;
+    } else {
+        vnet_hdr_required = 0;
+    }
+
+    TFR(fd = tap_open(ifname, sizeof(ifname), vnet_hdr, vnet_hdr_required));
     if (fd < 0) {
         return -1;
     }
@@ -2698,8 +2715,9 @@ static int net_init_tap(QemuOpts *opts,
     if (qemu_opt_get(opts, "fd")) {
         if (qemu_opt_get(opts, "ifname") ||
             qemu_opt_get(opts, "script") ||
-            qemu_opt_get(opts, "downscript")) {
-            qemu_error("ifname=, script= and downscript= is invalid with fd=\n");
+            qemu_opt_get(opts, "downscript") ||
+            qemu_opt_get(opts, "vnet_hdr")) {
+            qemu_error("ifname=, script=, downscript= and vnet_hdr= is invalid with fd=\n");
             return -1;
         }
 
@@ -3055,6 +3073,10 @@ static struct {
                 .name = "sndbuf",
                 .type = QEMU_OPT_SIZE,
                 .help = "send buffer limit"
+            }, {
+                .name = "vnet_hdr",
+                .type = QEMU_OPT_BOOL,
+                .help = "enable the IFF_VNET_HDR flag on the tap interface"
             },
             { /* end of list */ }
         },
index c745e0ca265181fcb53e35b05783ebd7d322e3d7..d78b738c77f4faed35deb7a73f9146450da15814 100644 (file)
@@ -810,7 +810,7 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
     "-net tap[,vlan=n][,name=str],ifname=name\n"
     "                connect the host TAP network interface to VLAN 'n'\n"
 #else
-    "-net tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile][,sndbuf=nbytes]\n"
+    "-net tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile][,sndbuf=nbytes][,vnet_hdr=on|off]\n"
     "                connect the host TAP network interface to VLAN 'n' and use the\n"
     "                network scripts 'file' (default=%s)\n"
     "                and 'dfile' (default=%s);\n"
@@ -818,6 +818,8 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
     "                use 'fd=h' to connect to an already opened TAP interface\n"
     "                use 'sndbuf=nbytes' to limit the size of the send buffer; the\n"
     "                default of 'sndbuf=1048576' can be disabled using 'sndbuf=0'\n"
+    "                use vnet_hdr=off to avoid enabling the IFF_VNET_HDR tap flag; use\n"
+    "                vnet_hdr=on to make the lack of IFF_VNET_HDR support an error condition\n"
 #endif
     "-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port]\n"
     "                connect the vlan 'n' to another VLAN using a socket connection\n"