]> xenbits.xensource.com Git - libvirt.git/commitdiff
util: set vlan tag for macvtap passthrough mode on SRIOV VFs
authorLaine Stump <laine@laine.org>
Wed, 4 May 2016 17:18:16 +0000 (13:18 -0400)
committerLaine Stump <laine@laine.org>
Tue, 10 May 2016 18:04:19 +0000 (14:04 -0400)
SRIOV VFs used in macvtap passthrough mode can take advantage of the
SRIOV card's transparent vlan tagging. All the code was there to set
the vlan tag, and it has been used for SRIOV VFs used for hostdev
interfaces for several years, but for some reason, the vlan tag for
macvtap passthrough devices was stubbed out with a -1.

This patch moves a bit of common validation down to a lower level
(virNetDevReplaceNetConfig()) so it is shared by hostdev and macvtap
modes, and updates the macvtap caller to actually send the vlan config
instead of -1.

docs/formatdomain.html.in
docs/formatnetwork.html.in
src/lxc/lxc_process.c
src/network/bridge_driver.c
src/qemu/qemu_interface.c
src/util/virhostdev.c
src/util/virnetdev.c
src/util/virnetdev.h
src/util/virnetdevmacvlan.c
src/util/virnetdevmacvlan.h

index 97794b77eaa449239a376a24fa310502d357b716..72eb7d7190c74a23cf229ba2e876e5fdaa5e9faf 100644 (file)
     <p>
       On Linux systems, the bridge device is normally a standard Linux
       host bridge. On hosts that support Open vSwitch, it is also
-      possible to connect to an open vSwitch bridge device by adding
+      possible to connect to an Open vSwitch bridge device by adding
       a <code>&lt;virtualport type='openvswitch'/&gt;</code> to the
       interface definition.  (<span class="since">Since
       0.9.11</span>). The Open vSwitch type virtualport accepts two
@@ -4816,34 +4816,46 @@ qemu-kvm -net nic,model=? /dev/null
 
     <p>
       If (and only if) the network connection used by the guest
-      supports vlan tagging transparent to the guest, an
+      supports VLAN tagging transparent to the guest, an
       optional <code>&lt;vlan&gt;</code> element can specify one or
-      more vlan tags to apply to the guest's network
-      traffic <span class="since">Since 0.10.0</span>. (openvswitch
-      and type='hostdev' SR-IOV interfaces do support transparent vlan
-      tagging of guest traffic; everything else, including standard
+      more VLAN tags to apply to the guest's network
+      traffic <span class="since">Since 0.10.0</span>. Network
+      connections that support guest-transparent VLAN tagging include
+      1) type='bridge' interfaces connected to an Open vSwitch bridge
+      <span class="since">Since 0.10.0</span>, 2) SRIOV Virtual
+      Functions (VF) used via type='hostdev' (direct device
+      assignment) <span class="since">Since 0.10.0</span>, and 3)
+      SRIOV VFs used via type='direct' with mode='passthrough'
+      (macvtap "passthru" mode) <span class="since">Since
+      1.3.4</span>. All other connection types, including standard
       linux bridges and libvirt's own virtual networks, <b>do not</b>
       support it. 802.1Qbh (vn-link) and 802.1Qbg (VEPA) switches
       provide their own way (outside of libvirt) to tag guest traffic
-      onto specific vlans.) To allow for specification of multiple
-      tags (in the case of vlan trunking), a
-      subelement, <code>&lt;tag&gt;</code>, specifies which vlan tag
-      to use (for example: <code>&lt;tag id='42'/&gt;</code>. If an
-      interface has more than one <code>&lt;vlan&gt;</code> element
-      defined, it is assumed that the user wants to do VLAN trunking
-      using all the specified tags. In the case that vlan trunking
-      with a single tag is desired, the optional
+      onto a specific VLAN. Each tag is given in a
+      separate <code>&lt;tag&gt;</code> subelement
+      of <code>&lt;vlan&gt;</code> (for example: <code>&lt;tag
+      id='42'/&gt;</code>). For VLAN trunking of multiple tags (which
+      is supported only on Open vSwitch connections),
+      multiple <code>&lt;tag&gt;</code> subelements can be specified,
+      which implies that the user wants to do VLAN trunking on the
+      interface for all the specified tags. In the case that VLAN
+      trunking of a single tag is desired, the optional
       attribute <code>trunk='yes'</code> can be added to the toplevel
-      vlan element.
-    </p>
-
-    <p>
-      For network connections using openvswitch it is possible to
-      configure the 'native-tagged' and 'native-untagged' vlan modes
-      <span class="since">Since 1.1.0.</span> This uses the optional
-      <code>nativeMode</code> attribute on the <code>&lt;tag&gt;</code>
-      element: <code>nativeMode</code> may be set to 'tagged' or
-      'untagged'. The id attribute of the element sets the native vlan.
+      <code>&lt;vlan&gt;</code> element to differentiate trunking of a
+      single tag from normal tagging.
+    </p>
+    <p>
+      For network connections using Open vSwitch it is also possible
+      to configure 'native-tagged' and 'native-untagged' VLAN modes
+      <span class="since">Since 1.1.0.</span> This is done with the
+      optional <code>nativeMode</code> attribute on
+      the <code>&lt;tag&gt;</code> subelement: <code>nativeMode</code>
+      may be set to 'tagged' or 'untagged'. The <code>id</code>
+      attribute of the <code>&lt;tag&gt;</code> subelement
+      containing <code>nativeMode</code> sets which VLAN is considered
+      to be the "native" VLAN for this interface, and
+      the <code>nativeMode</code> attribute determines whether or not
+      traffic for that VLAN will be tagged.
     </p>
 
     <h5><a name="elementLink">Modifying virtual link state</a></h5>
index 50dc751a0ecf7e77654a5269794247aac7a57485..ff060bbfff8ba4ebe9a30375c4a58ec01942183b 100644 (file)
 </pre>
 
     <p>
-      If (and only if) the network type supports vlan tagging
-      transparent to the guest, an optional <code>&lt;vlan&gt;</code>
-      element can specify one or more vlan tags to apply to the
-      traffic of all guests using this
-      network <span class="since">Since 0.10.0</span>. (openvswitch
-      and type='hostdev' SR-IOV networks do support transparent vlan
-      tagging of guest traffic; everything else, including standard
+      If (and only if) the network connection used by the guest
+      supports VLAN tagging transparent to the guest, an
+      optional <code>&lt;vlan&gt;</code> element can specify one or
+      more VLAN tags to apply to the guest's network
+      traffic <span class="since">Since 0.10.0</span>. Network
+      connections that support guest-transparent VLAN tagging include
+      1) type='bridge' interfaces connected to an Open vSwitch bridge
+      <span class="since">Since 0.10.0</span>, 2) SRIOV Virtual
+      Functions (VF) used via type='hostdev' (direct device
+      assignment) <span class="since">Since 0.10.0</span>, and 3)
+      SRIOV VFs used via type='direct' with mode='passthrough'
+      (macvtap "passthru" mode) <span class="since">Since
+      1.3.4</span>. All other connection types, including standard
       linux bridges and libvirt's own virtual networks, <b>do not</b>
       support it. 802.1Qbh (vn-link) and 802.1Qbg (VEPA) switches
       provide their own way (outside of libvirt) to tag guest traffic
-      onto specific vlans.) As expected, the <code>tag</code>
-      attribute specifies which vlan tag to use. If a network has more
-      than one <code>&lt;vlan&gt;</code> element defined, it is
-      assumed that the user wants to do VLAN trunking using all the
-      specified tags. In the case that vlan trunking with a single tag
-      is desired, the optional attribute <code>trunk='yes'</code> can
-      be added to the vlan element.
+      onto a specific VLAN. Each tag is given in a
+      separate <code>&lt;tag&gt;</code> subelement
+      of <code>&lt;vlan&gt;</code> (for example: <code>&lt;tag
+      id='42'/&gt;</code>). For VLAN trunking of multiple tags (which
+      is supported only on Open vSwitch connections),
+      multiple <code>&lt;tag&gt;</code> subelements can be specified,
+      which implies that the user wants to do VLAN trunking on the
+      interface for all the specified tags. In the case that VLAN
+      trunking of a single tag is desired, the optional
+      attribute <code>trunk='yes'</code> can be added to the toplevel
+      <code>&lt;vlan&gt;</code> element to differentiate trunking of a
+      single tag from normal tagging.
     </p>
     <p>
-      For network connections using openvswitch it is possible to
-      configure the 'native-tagged' and 'native-untagged' vlan modes
-      <span class="since">Since 1.1.0</span>. This uses the optional
-      <code>nativeMode</code> attribute on the <code>&lt;tag&gt;</code>
-      element: <code>nativeMode</code> may be set to 'tagged' or
-      'untagged'. The id attribute of the element sets the native vlan.
+      For network connections using Open vSwitch it is also possible
+      to configure 'native-tagged' and 'native-untagged' VLAN modes
+      <span class="since">Since 1.1.0.</span> This is done with the
+      optional <code>nativeMode</code> attribute on
+      the <code>&lt;tag&gt;</code> subelement: <code>nativeMode</code>
+      may be set to 'tagged' or 'untagged'. The <code>id</code>
+      attribute of the <code>&lt;tag&gt;</code> subelement
+      containing <code>nativeMode</code> sets which VLAN is considered
+      to be the "native" VLAN for this interface, and
+      the <code>nativeMode</code> attribute determines whether or not
+      traffic for that VLAN will be tagged.
     </p>
     <p>
       <code>&lt;vlan&gt;</code> elements can also be specified in
index 0044ee53ba8e03ef68f6b93b2660d3cf73dfe7bb..8981d9a0a1ac75de5448e43419966709f7c7e048 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2015 Red Hat, Inc.
+ * Copyright (C) 2010-2016 Red Hat, Inc.
  * Copyright IBM Corp. 2008
  *
  * lxc_process.c: LXC process lifecycle management
@@ -343,6 +343,7 @@ char *virLXCProcessSetupInterfaceDirect(virConnectPtr conn,
             net->ifname, &net->mac,
             linkdev,
             virDomainNetGetActualDirectMode(net),
+            virDomainNetGetActualVlan(net),
             def->uuid,
             prof,
             &res_ifname,
index f406f0431fd98e3bd683bc19bcde9b21658adcae..bef8a7848b256c3d82b08b28c88e5d67365f28df 100644 (file)
@@ -3057,11 +3057,12 @@ networkValidate(virNetworkDriverStatePtr driver,
      * a pool, and those using an Open vSwitch bridge.
      */
 
-    vlanAllowed = ((def->forward.type == VIR_NETWORK_FORWARD_BRIDGE &&
+    vlanAllowed = (def->forward.type == VIR_NETWORK_FORWARD_HOSTDEV ||
+                   def->forward.type == VIR_NETWORK_FORWARD_PASSTHROUGH ||
+                   (def->forward.type == VIR_NETWORK_FORWARD_BRIDGE &&
                     def->virtPortProfile &&
                     def->virtPortProfile->virtPortType
-                    == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH) ||
-                   def->forward.type == VIR_NETWORK_FORWARD_HOSTDEV);
+                    == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH));
 
     vlanUsed = def->vlan.nTags > 0;
     for (i = 0; i < def->nPortGroups; i++) {
@@ -4276,11 +4277,15 @@ networkAllocateActualDevice(virDomainDefPtr dom,
      */
 
     if (virDomainNetGetActualVlan(iface)) {
-        /* vlan configuration via libvirt is only supported for
-         * PCI Passthrough SR-IOV devices and openvswitch bridges.
-         * otherwise log an error and fail
+        /* vlan configuration via libvirt is only supported for PCI
+         * Passthrough SR-IOV devices (hostdev or macvtap passthru
+         * mode) and openvswitch bridges. Otherwise log an error and
+         * fail
          */
         if (!(actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV ||
+              (actualType == VIR_DOMAIN_NET_TYPE_DIRECT &&
+               virDomainNetGetActualDirectMode(iface)
+               == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) ||
               (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE &&
                virtport && virtport->virtPortType
                == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH))) {
index ef789fab101c3ada00077c258b371a8f34a451d0..b48ae504643a1c9621e5e5499d7113d3dcd2aaf7 100644 (file)
@@ -266,6 +266,7 @@ qemuInterfaceDirectConnect(virDomainDefPtr def,
                                                &net->mac,
                                                virDomainNetGetActualDirectDev(net),
                                                virDomainNetGetActualDirectMode(net),
+                                               virDomainNetGetActualVlan(net),
                                                def->uuid,
                                                virDomainNetGetActualVirtPortProfile(net),
                                                &res_ifname,
index 933c94263c58a5653196524a7833ed11c8e7c580..980e590ce6d5b74fd65b715ba75cedb6ddafa851 100644 (file)
@@ -1,6 +1,6 @@
 /* virhostdev.c: hostdev management
  *
- * Copyright (C) 2006-2007, 2009-2015 Red Hat, Inc.
+ * Copyright (C) 2006-2007, 2009-2016 Red Hat, Inc.
  * Copyright (C) 2006 Daniel P. Berrange
  * Copyright (C) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
  *
@@ -387,7 +387,6 @@ virHostdevNetConfigReplace(virDomainHostdevDefPtr hostdev,
     virNetDevVPortProfilePtr virtPort;
     int ret = -1;
     int vf = -1;
-    int vlanid = -1;
     bool port_profile_associate = true;
 
     if (virHostdevIsVirtualFunction(hostdev) != 1) {
@@ -416,27 +415,9 @@ virHostdevNetConfigReplace(virDomainHostdevDefPtr hostdev,
                             port_profile_associate);
     } else {
         /* Set only mac and vlan */
-        if (vlan) {
-            if (vlan->nTags != 1 || vlan->trunk) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                               _("vlan trunking is not supported "
-                                 "by SR-IOV network devices"));
-                goto cleanup;
-            }
-            if (vf == -1) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                               _("vlan can only be set for SR-IOV VFs, but "
-                                 "%s is not a VF"), linkdev);
-                goto cleanup;
-            }
-            vlanid = vlan->tag[0];
-        } else  if (vf >= 0) {
-            vlanid = 0; /* assure any current vlan tag is reset */
-        }
-
         ret = virNetDevReplaceNetConfig(linkdev, vf,
                                         &hostdev->parent.data.net->mac,
-                                        vlanid, stateDir);
+                                        vlan, stateDir);
     }
  cleanup:
     VIR_FREE(linkdev);
index bb17b84a48740f0afd4df59bfbf3d99274dc6113..7db4497cd5ea05abcd844e4f34814deae95c5207 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2015 Red Hat, Inc.
+ * Copyright (C) 2007-2016 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -2547,7 +2547,8 @@ virNetDevRestoreVfConfig(const char *pflinkdev,
  */
 int
 virNetDevReplaceNetConfig(const char *linkdev, int vf,
-                          const virMacAddr *macaddress, int vlanid,
+                          const virMacAddr *macaddress,
+                          virNetDevVlanPtr vlan,
                           const char *stateDir)
 {
     int ret = -1;
@@ -2566,11 +2567,29 @@ virNetDevReplaceNetConfig(const char *linkdev, int vf,
         linkdev = pfdevname;
     }
 
-    if (vf == -1)
+    if (vf == -1) {
+        if (vlan) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("vlan can only be set for SR-IOV VFs, but "
+                             "%s is not a VF"), linkdev);
+            goto cleanup;
+        }
         ret = virNetDevReplaceMacAddress(linkdev, macaddress, stateDir);
-    else
+    } else {
+        int vlanid = 0; /* assure any current vlan tag is reset */
+
+        if (vlan) {
+            if (vlan->nTags != 1 || vlan->trunk) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("vlan trunking is not supported "
+                                 "by SR-IOV network devices"));
+                goto cleanup;
+            }
+            vlanid = vlan->tag[0];
+        }
         ret = virNetDevReplaceVfConfig(linkdev, vf, macaddress, vlanid,
                                        stateDir);
+    }
 
  cleanup:
     VIR_FREE(pfdevname);
@@ -2636,7 +2655,7 @@ int
 virNetDevReplaceNetConfig(const char *linkdev ATTRIBUTE_UNUSED,
                           int vf ATTRIBUTE_UNUSED,
                           const virMacAddr *macaddress ATTRIBUTE_UNUSED,
-                          int vlanid ATTRIBUTE_UNUSED,
+                          virNetDevVlanPtr vlan ATTRIBUTE_UNUSED,
                           const char *stateDir ATTRIBUTE_UNUSED)
 {
     virReportSystemError(ENOSYS, "%s",
index dcc81a6d9f5920a304c1bc25640bab34e7dcd658..cbe79380a3c64d58ca1702328b4494ae931a803b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2015 Red Hat, Inc.
+ * Copyright (C) 2007-2016 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -30,6 +30,7 @@
 # include "virnetlink.h"
 # include "virmacaddr.h"
 # include "virpci.h"
+# include "virnetdevvlan.h"
 # include "device_conf.h"
 
 # ifdef HAVE_STRUCT_IFREQ
@@ -175,7 +176,8 @@ int virNetDevLinkDump(const char *ifname, int ifindex,
     ATTRIBUTE_RETURN_CHECK;
 
 int virNetDevReplaceNetConfig(const char *linkdev, int vf,
-                              const virMacAddr *macaddress, int vlanid,
+                              const virMacAddr *macaddress,
+                              virNetDevVlanPtr vlan,
                               const char *stateDir)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(5);
 
index d755b93a368d9fecaa255279d4aa22bcea79bf24..c05c67f34873b005b2934eb79ba9b4303496801d 100644 (file)
@@ -975,6 +975,7 @@ virNetDevMacVLanCreateWithVPortProfile(const char *ifnameRequested,
                                        const virMacAddr *macaddress,
                                        const char *linkdev,
                                        virNetDevMacVLanMode mode,
+                                       virNetDevVlanPtr vlan,
                                        const unsigned char *vmuuid,
                                        virNetDevVPortProfilePtr virtPortProfile,
                                        char **ifnameResult,
@@ -1021,7 +1022,7 @@ virNetDevMacVLanCreateWithVPortProfile(const char *ifnameRequested,
             if (virNetDevReplaceMacAddress(linkdev, macaddress, stateDir) < 0)
                 return -1;
         } else {
-            if (virNetDevReplaceNetConfig(linkdev, -1, macaddress, -1, stateDir) < 0)
+            if (virNetDevReplaceNetConfig(linkdev, -1, macaddress, vlan, stateDir) < 0)
                 return -1;
         }
     }
@@ -1281,6 +1282,7 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *ifname ATTRIBUTE_UNUSED,
                                            const virMacAddr *macaddress ATTRIBUTE_UNUSED,
                                            const char *linkdev ATTRIBUTE_UNUSED,
                                            virNetDevMacVLanMode mode ATTRIBUTE_UNUSED,
+                                           virNetDevVlanPtr vlan ATTRIBUTE_UNUSED,
                                            const unsigned char *vmuuid ATTRIBUTE_UNUSED,
                                            virNetDevVPortProfilePtr virtPortProfile ATTRIBUTE_UNUSED,
                                            char **res_ifname ATTRIBUTE_UNUSED,
index 560593ea05ab89116e40ed60170944a20b2cbbc4..8e0a3527b055502cc6c84da947611810e718febc 100644 (file)
@@ -28,6 +28,7 @@
 # include "virsocketaddr.h"
 # include "virnetdevbandwidth.h"
 # include "virnetdevvportprofile.h"
+# include "virnetdevvlan.h"
 
 /* the mode type for macvtap devices */
 typedef enum {
@@ -69,6 +70,7 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *ifname,
                                            const virMacAddr *macaddress,
                                            const char *linkdev,
                                            virNetDevMacVLanMode mode,
+                                           virNetDevVlanPtr vlan,
                                            const unsigned char *vmuuid,
                                            virNetDevVPortProfilePtr virtPortProfile,
                                            char **res_ifname,
@@ -77,8 +79,8 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *ifname,
                                            int *tapfd,
                                            size_t tapfdSize,
                                            unsigned int flags)
-    ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(5)
-    ATTRIBUTE_NONNULL(7) ATTRIBUTE_NONNULL(9) ATTRIBUTE_RETURN_CHECK;
+    ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(6)
+    ATTRIBUTE_NONNULL(8) ATTRIBUTE_NONNULL(10) ATTRIBUTE_RETURN_CHECK;
 
 int virNetDevMacVLanDeleteWithVPortProfile(const char *ifname,
                                            const virMacAddr *macaddress,