[PATCH 5/5] vmx: Add support for VDS interface

Martin Kletzander mkletzan at redhat.com
Wed Aug 17 12:50:40 UTC 2022


Since we cannot properly plug a new VM into the distributed switch, we can at
least report the provided pieces of information, so that XML editing still works
even for VMs with such interfaces.

https://bugzilla.redhat.com/show_bug.cgi?id=1988211

Signed-off-by: Martin Kletzander <mkletzan at redhat.com>
---
 src/vmx/vmx.c                              | 76 ++++++++++++++++++----
 tests/vmx2xmldata/ethernet-vds.vmx         | 11 ++++
 tests/vmx2xmldata/ethernet-vds.xml         | 24 +++++++
 tests/vmx2xmltest.c                        |  1 +
 tests/xml2vmxdata/xml2vmx-ethernet-vds.vmx | 18 +++++
 tests/xml2vmxdata/xml2vmx-ethernet-vds.xml | 15 +++++
 tests/xml2vmxtest.c                        |  1 +
 7 files changed, 133 insertions(+), 13 deletions(-)
 create mode 100644 tests/vmx2xmldata/ethernet-vds.vmx
 create mode 100644 tests/vmx2xmldata/ethernet-vds.xml
 create mode 100644 tests/xml2vmxdata/xml2vmx-ethernet-vds.vmx
 create mode 100644 tests/xml2vmxdata/xml2vmx-ethernet-vds.xml

diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index b7b997e83540..9ad463658aa8 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -2700,6 +2700,13 @@ virVMXParseEthernet(virConf *conf, int controller, virDomainNetDef **def)
     char networkName_name[48] = "";
     char *networkName = NULL;
 
+    char switchId_name[48] = "";
+    char *switchId = NULL;
+
+    char portId_name[48] = "";
+    char portgroupId_name[48] = "";
+    char connectionId_name[48] = "";
+
     int netmodel = VIR_DOMAIN_NET_MODEL_UNKNOWN;
 
     if (def == NULL || *def != NULL) {
@@ -2721,6 +2728,13 @@ virVMXParseEthernet(virConf *conf, int controller, virDomainNetDef **def)
     VMX_BUILD_NAME(networkName);
     VMX_BUILD_NAME(vnet);
 
+    g_snprintf(prefix, sizeof(prefix), "ethernet%d.dvs", controller);
+
+    VMX_BUILD_NAME(switchId);
+    VMX_BUILD_NAME(portId);
+    VMX_BUILD_NAME(portgroupId);
+    VMX_BUILD_NAME(connectionId);
+
     /* vmx:present */
     if (virVMXGetConfigBoolean(conf, present_name, &present, false, true) < 0)
         return -1;
@@ -2836,19 +2850,36 @@ virVMXParseEthernet(virConf *conf, int controller, virDomainNetDef **def)
         goto cleanup;
     }
 
+    if (virVMXGetConfigString(conf, switchId_name, &switchId, true) < 0)
+        goto cleanup;
+
     /* Setup virDomainNetDef */
-    if (connectionType == NULL && networkName == NULL) {
-        /*
-         * Having neither a connectionType nor a network name can mean two
-         * things:
-         *
-         * 1) there is no connection of that nic
-         * 2) the nic is connected to VMWare Distributed Switch
-         *
-         * But we do not see any difference between these and hence we report
-         * the closest thing to at least make virt-v2v and others work when they
-         * read the domain XML.
-         */
+    if (switchId) {
+        (*def)->type = VIR_DOMAIN_NET_TYPE_VDS;
+
+        if (virUUIDParse(switchId, (*def)->data.vds.switch_id) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Could not parse UUID from string '%s'"),
+                           switchId);
+            goto cleanup;
+        }
+
+        if (virVMXGetConfigString(conf,
+                                  portgroupId_name,
+                                  &(*def)->data.vds.portgroup_id,
+                                  false) < 0 ||
+            virVMXGetConfigLong(conf,
+                                portId_name,
+                                &(*def)->data.vds.port_id,
+                                0,
+                                false) < 0 ||
+            virVMXGetConfigLong(conf,
+                                connectionId_name,
+                                &(*def)->data.vds.connection_id,
+                                0,
+                                false) < 0)
+            goto cleanup;
+    } else if (connectionType == NULL && networkName == NULL) {
         (*def)->type = VIR_DOMAIN_NET_TYPE_DUMMY;
     } else if (connectionType == NULL || STRCASEEQ(connectionType, "bridged")) {
         (*def)->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
@@ -3962,6 +3993,26 @@ virVMXFormatEthernet(virDomainNetDef *def, int controller,
     case VIR_DOMAIN_NET_TYPE_DUMMY:
         break;
 
+    case VIR_DOMAIN_NET_TYPE_VDS: {
+        unsigned char *uuid = def->data.vds.switch_id;
+
+        virBufferAsprintf(buffer, "ethernet%d.dvs.switchId = \"%02x %02x %02x %02x %02x "
+                          "%02x %02x %02x-%02x %02x %02x %02x %02x %02x %02x %02x\"\n",
+                          controller, uuid[0], uuid[1], uuid[2], uuid[3], uuid[4],
+                          uuid[5], uuid[6], uuid[7], uuid[8], uuid[9], uuid[10],
+                          uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
+
+        virBufferAsprintf(buffer, "ethernet%d.dvs.portId = \"%lld\"\n",
+                          controller, def->data.vds.port_id);
+
+        virBufferAsprintf(buffer, "ethernet%d.dvs.", controller);
+        virBufferEscapeString(buffer, "portgroupId = \"%s\"\n", def->data.vds.portgroup_id);
+
+        virBufferAsprintf(buffer, "ethernet%d.dvs.connectionId = \"%lld\"\n",
+                          controller, def->data.vds.connection_id);
+        break;
+    }
+
     case VIR_DOMAIN_NET_TYPE_ETHERNET:
     case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
     case VIR_DOMAIN_NET_TYPE_SERVER:
@@ -3973,7 +4024,6 @@ virVMXFormatEthernet(virDomainNetDef *def, int controller,
     case VIR_DOMAIN_NET_TYPE_HOSTDEV:
     case VIR_DOMAIN_NET_TYPE_UDP:
     case VIR_DOMAIN_NET_TYPE_VDPA:
-    case VIR_DOMAIN_NET_TYPE_VDS:
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unsupported net type '%s'"),
                        virDomainNetTypeToString(def->type));
         return -1;
diff --git a/tests/vmx2xmldata/ethernet-vds.vmx b/tests/vmx2xmldata/ethernet-vds.vmx
new file mode 100644
index 000000000000..f68587bcf181
--- /dev/null
+++ b/tests/vmx2xmldata/ethernet-vds.vmx
@@ -0,0 +1,11 @@
+config.version = "8"
+virtualHW.version = "4"
+ethernet0.present = "true"
+ethernet0.virtualDev = "e1000e"
+ethernet0.addressType = "vpx"
+ethernet0.generatedAddress = "00:50:56:87:65:43"
+ethernet0.dvs.switchId = "50 34 26 b2 94 e9 3b 16-1d 68 87 bf ff 4a 54 40"
+ethernet0.dvs.portId = "5"
+ethernet0.dvs.portgroupId = "dvportgroup-1285"
+ethernet0.dvs.connectionId = "408217997"
+displayName = "test"
diff --git a/tests/vmx2xmldata/ethernet-vds.xml b/tests/vmx2xmldata/ethernet-vds.xml
new file mode 100644
index 000000000000..ab842b168c9b
--- /dev/null
+++ b/tests/vmx2xmldata/ethernet-vds.xml
@@ -0,0 +1,24 @@
+<domain type='vmware'>
+  <name>test</name>
+  <uuid>00000000-0000-0000-0000-000000000000</uuid>
+  <memory unit='KiB'>32768</memory>
+  <currentMemory unit='KiB'>32768</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='i686'>hvm</type>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <interface type='vds'>
+      <mac address='00:50:56:87:65:43' type='generated'/>
+      <source switchid='503426b2-94e9-3b16-1d68-87bfff4a5440' portid='5' portgroupid='dvportgroup-1285' connectionid='408217997'/>
+      <model type='e1000e'/>
+    </interface>
+    <video>
+      <model type='vmvga' vram='4096' primary='yes'/>
+    </video>
+  </devices>
+</domain>
diff --git a/tests/vmx2xmltest.c b/tests/vmx2xmltest.c
index 3ab39148e0a4..07d7bf24c2b3 100644
--- a/tests/vmx2xmltest.c
+++ b/tests/vmx2xmltest.c
@@ -237,6 +237,7 @@ mymain(void)
     DO_TEST("ethernet-vpx");
     DO_TEST("ethernet-other");
     DO_TEST("ethernet-dummy");
+    DO_TEST("ethernet-vds");
 
     DO_TEST("serial-file");
     DO_TEST("serial-device");
diff --git a/tests/xml2vmxdata/xml2vmx-ethernet-vds.vmx b/tests/xml2vmxdata/xml2vmx-ethernet-vds.vmx
new file mode 100644
index 000000000000..bcc04bc21a6e
--- /dev/null
+++ b/tests/xml2vmxdata/xml2vmx-ethernet-vds.vmx
@@ -0,0 +1,18 @@
+.encoding = "UTF-8"
+config.version = "8"
+virtualHW.version = "4"
+guestOS = "other"
+uuid.bios = "56 4d 9b ef ac d9 b4 e0-c8 f0 ae a8 b9 10 35 15"
+displayName = "ethernet-vpx"
+memsize = "4"
+numvcpus = "1"
+floppy0.present = "false"
+floppy1.present = "false"
+ethernet0.present = "true"
+ethernet0.virtualDev = "e1000e"
+ethernet0.dvs.switchId = "50 34 26 b2 94 e9 3b 16-1d 68 87 bf ff 4a 54 40"
+ethernet0.dvs.portId = "5"
+ethernet0.dvs.portgroupId = "dvportgroup-1285"
+ethernet0.dvs.connectionId = "408217997"
+ethernet0.addressType = "vpx"
+ethernet0.generatedAddress = "00:50:56:87:65:43"
diff --git a/tests/xml2vmxdata/xml2vmx-ethernet-vds.xml b/tests/xml2vmxdata/xml2vmx-ethernet-vds.xml
new file mode 100644
index 000000000000..69d44a62da1c
--- /dev/null
+++ b/tests/xml2vmxdata/xml2vmx-ethernet-vds.xml
@@ -0,0 +1,15 @@
+<domain type='vmware'>
+  <name>ethernet-vpx</name>
+  <uuid>564d9bef-acd9-b4e0-c8f0-aea8b9103515</uuid>
+  <memory unit='KiB'>4096</memory>
+  <os>
+    <type>hvm</type>
+  </os>
+  <devices>
+    <interface type='vds'>
+      <mac address='00:50:56:87:65:43' type='generated'/>
+      <source switchid='503426b2-94e9-3b16-1d68-87bfff4a5440' portid='5' portgroupid='dvportgroup-1285' connectionid='408217997'/>
+      <model type='e1000e'/>
+    </interface>
+  </devices>
+</domain>
diff --git a/tests/xml2vmxtest.c b/tests/xml2vmxtest.c
index 7723c1efabdd..c921c8a3b0eb 100644
--- a/tests/xml2vmxtest.c
+++ b/tests/xml2vmxtest.c
@@ -226,6 +226,7 @@ mymain(void)
     DO_TEST("ethernet-mac-type", "ethernet-mac-type", 4);
 
     DO_TEST("ethernet-dummy", "ethernet-dummy", 4);
+    DO_TEST("ethernet-vds", "ethernet-vds", 4);
 
     DO_TEST("serial-file", "serial-file", 4);
     DO_TEST("serial-device", "serial-device", 4);
-- 
2.37.2



More information about the libvir-list mailing list