[libvirt] [PATCH v3] esx: Support VLAN tags in virtual network port groups

Matthias Bolte matthias.bolte at googlemail.com
Sun Sep 9 08:44:18 UTC 2012


---

v2: Use network level VLAN config if there is no portgroup specific VLAN
    config given.

v3: Add ESX_VLAN_TRUNK define for magic number 4095

 src/esx/esx_network_driver.c |   70 +++++++++++++++++++++++++++++++++++++++---
 1 files changed, 65 insertions(+), 5 deletions(-)

diff --git a/src/esx/esx_network_driver.c b/src/esx/esx_network_driver.c
index 09d46d3..21eabbe 100644
--- a/src/esx/esx_network_driver.c
+++ b/src/esx/esx_network_driver.c
@@ -45,6 +45,9 @@
  */
 verify(MD5_DIGEST_SIZE == VIR_UUID_BUFLEN);
 
+/* ESX utilizes the VLAN ID of 4095 to mean that this port is in trunk mode */
+#define ESX_VLAN_TRUNK 4095
+
 
 
 static virDrvOpenStatus
@@ -489,7 +492,42 @@ esxNetworkDefineXML(virConnectPtr conn, const char *xml)
             goto cleanup;
         }
 
-        hostPortGroupSpec->vlanId->value = 0;
+        if (def->portGroups[i].vlan.trunk) {
+            /* FIXME: Change this once tag-less trunk-mode is supported */
+            if (def->portGroups[i].vlan.nTags != 1 ||
+                *def->portGroups[i].vlan.tag != ESX_VLAN_TRUNK) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("VLAN tag has to be %d in trunk mode"),
+                               ESX_VLAN_TRUNK);
+                goto cleanup;
+            }
+
+            hostPortGroupSpec->vlanId->value = ESX_VLAN_TRUNK;
+        } else if (def->portGroups[i].vlan.nTags == 1) {
+            hostPortGroupSpec->vlanId->value = *def->portGroups[i].vlan.tag;
+        } else if (def->portGroups[i].vlan.nTags > 1) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("Can apply one VLAN tag per port group only"));
+            goto cleanup;
+        } else if (def->vlan.trunk) {
+            /* FIXME: Change this once tag-less trunk-mode is supported */
+            if (def->vlan.nTags != 1 || *def->vlan.tag != ESX_VLAN_TRUNK) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("VLAN tag has to be %d in trunk mode"),
+                               ESX_VLAN_TRUNK);
+                goto cleanup;
+            }
+
+            hostPortGroupSpec->vlanId->value = ESX_VLAN_TRUNK;
+        } else if (def->vlan.nTags == 1) {
+            hostPortGroupSpec->vlanId->value = *def->vlan.tag;
+        } else if (def->vlan.nTags > 1) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("Can apply one VLAN tag per port group only"));
+            goto cleanup;
+        } else {
+            hostPortGroupSpec->vlanId->value = 0;
+        }
 
         if (def->portGroups[i].bandwidth != NULL) {
             if (esxBandwidthToShapingPolicy
@@ -519,6 +557,8 @@ esxNetworkDefineXML(virConnectPtr conn, const char *xml)
     network = virGetNetwork(conn, hostVirtualSwitch->name, md5);
 
   cleanup:
+    /* FIXME: need to remove virtual switch if adding port groups failed */
+
     virNetworkDefFree(def);
     esxVI_HostVirtualSwitch_Free(&hostVirtualSwitch);
     esxVI_HostPortGroup_Free(&hostPortGroupList);
@@ -695,6 +735,7 @@ esxNetworkGetXMLDesc(virNetworkPtr network_, unsigned int flags)
     esxVI_String *hostPortGroupKey = NULL;
     esxVI_String *networkName = NULL;
     virNetworkDefPtr def;
+    virPortGroupDefPtr portGroup;
 
     if (esxVI_EnsureSession(priv->primary) < 0) {
         return NULL;
@@ -824,9 +865,12 @@ esxNetworkGetXMLDesc(virNetworkPtr network_, unsigned int flags)
                     for (networkName = networkNameList; networkName != NULL;
                          networkName = networkName->_next) {
                         if (STREQ(networkName->value, hostPortGroup->spec->name)) {
-                            def->portGroups[def->nPortGroups].name = strdup(networkName->value);
+                            portGroup = &def->portGroups[def->nPortGroups];
+                            ++def->nPortGroups;
+
+                            portGroup->name = strdup(networkName->value);
 
-                            if (def->portGroups[def->nPortGroups].name == NULL) {
+                            if (portGroup->name == NULL) {
                                 virReportOOMError();
                                 goto cleanup;
                             }
@@ -834,13 +878,29 @@ esxNetworkGetXMLDesc(virNetworkPtr network_, unsigned int flags)
                             if (hostPortGroup->spec->policy != NULL) {
                                 if (esxShapingPolicyToBandwidth
                                       (hostPortGroup->spec->policy->shapingPolicy,
-                                       &def->portGroups[def->nPortGroups].bandwidth) < 0) {
+                                       &portGroup->bandwidth) < 0) {
                                     ++def->nPortGroups;
                                     goto cleanup;
                                 }
                             }
 
-                            ++def->nPortGroups;
+                            if (hostPortGroup->spec->vlanId->value > 0) {
+                                if (hostPortGroup->spec->vlanId->value == ESX_VLAN_TRUNK) {
+                                    portGroup->vlan.trunk = true;
+                                }
+
+                                /* FIXME: Remove this once tag-less trunk-mode is supported */
+                                portGroup->vlan.nTags = 1;
+
+                                if (VIR_ALLOC_N(portGroup->vlan.tag, 1) < 0) {
+                                    virReportOOMError();
+                                    goto cleanup;
+                                }
+
+                                *portGroup->vlan.tag =
+                                  hostPortGroup->spec->vlanId->value;
+                            }
+
                             break;
                         }
                     }
-- 
1.7.4.1




More information about the libvir-list mailing list