]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Add a check attribute on the mac address element
authorBastien Orivel <bastien.orivel@diateam.net>
Mon, 13 Jul 2020 09:44:13 +0000 (11:44 +0200)
committerDaniel P. Berrangé <berrange@redhat.com>
Thu, 23 Jul 2020 15:11:39 +0000 (16:11 +0100)
This is only used in the ESX driver where, when set to "no", it will
ignore all the checks libvirt does about the origin of the MAC address
(whether or not it's in a VMWare OUI) and forward the original one to
the ESX server telling it not to check it either.

This allows keeping a deterministic MAC address which can be useful for
licensed software which might dislike changes.

Signed-off-by: Bastien Orivel <bastien.orivel@diateam.net>
VMX conversion parts rewritten to apply on top of previously merged
support for type='generated|static'

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/vmx/vmx.c
tests/genericxml2xmlindata/network-interface-mac-check.xml [new file with mode: 0644]
tests/genericxml2xmltest.c
tests/vmx2xmldata/vmx2xml-ethernet-other.xml
tests/xml2vmxdata/xml2vmx-ethernet-mac-type.vmx
tests/xml2vmxdata/xml2vmx-ethernet-mac-type.xml

index a810f569c6acf57742162ebd2ba4427c5ed8ac1c..8cbbd7e6e965a2eb0ae03720b47b517a3a2d40c1 100644 (file)
               </choice>
             </attribute>
           </optional>
+          <optional>
+            <attribute name="check">
+              <ref name="virYesNo"/>
+            </attribute>
+          </optional>
           <empty/>
         </element>
       </optional>
index 8d328819afc44fe4fea6b95996ba0b0c2e5c13f7..386b04b5b8f04744cc219e9c3cbc6e5548323420 100644 (file)
@@ -11925,6 +11925,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
     int rv, val;
     g_autofree char *macaddr = NULL;
     g_autofree char *macaddr_type = NULL;
+    g_autofree char *macaddr_check = NULL;
     g_autofree char *type = NULL;
     g_autofree char *network = NULL;
     g_autofree char *portgroup = NULL;
@@ -12006,6 +12007,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
             if (!macaddr && virXMLNodeNameEqual(cur, "mac")) {
                 macaddr = virXMLPropString(cur, "address");
                 macaddr_type = virXMLPropString(cur, "type");
+                macaddr_check = virXMLPropString(cur, "check");
             } else if (!network &&
                        def->type == VIR_DOMAIN_NET_TYPE_NETWORK &&
                        virXMLNodeNameEqual(cur, "source")) {
@@ -12206,6 +12208,16 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
         }
         def->mac_type = tmp;
     }
+    if (macaddr_check) {
+        int tmpCheck;
+        if ((tmpCheck = virTristateBoolTypeFromString(macaddr_check)) < 0) {
+            virReportError(VIR_ERR_XML_ERROR,
+                           _("invalid mac address check value: '%s'"),
+                           macaddr_check);
+            goto error;
+        }
+        def->mac_check = tmpCheck;
+    }
 
     if (virDomainDeviceInfoParseXML(xmlopt, node, &def->info,
                                     flags | VIR_DOMAIN_DEF_PARSE_ALLOW_BOOT
@@ -26555,6 +26567,8 @@ virDomainNetDefFormat(virBufferPtr buf,
                       virMacAddrFormat(&def->mac, macstr));
     if (def->mac_type)
         virBufferAsprintf(buf, " type='%s'", virDomainNetMacTypeTypeToString(def->mac_type));
+    if (def->mac_check != VIR_TRISTATE_BOOL_ABSENT)
+        virBufferAsprintf(buf, " check='%s'", virTristateBoolTypeToString(def->mac_check));
     virBufferAddLit(buf, "/>\n");
 
     if (publicActual) {
index 241149af2489e2b39c6884dda2bd9506feb00921..6e9da298b4af1878463b5bb2b78654f8f1367f9f 100644 (file)
@@ -982,6 +982,7 @@ struct _virDomainNetDef {
     virMacAddr mac;
     bool mac_generated; /* true if mac was *just now* auto-generated by libvirt */
     virDomainNetMacType mac_type;
+    virTristateBool mac_check;
     int model; /* virDomainNetModelType */
     char *modelstr;
     union {
index 72f6a7d8dd66c0816f745d6ff118a4e1e50d0efd..a123a8807cf1d1430ef51b341f3f18b412887694 100644 (file)
@@ -2638,6 +2638,14 @@ virVMXParseEthernet(virConfPtr conf, int controller, virDomainNetDefPtr *def)
         goto cleanup;
     }
 
+    if (checkMACAddress) {
+        if (STREQ(checkMACAddress, "true")) {
+            (*def)->mac_check = VIR_TRISTATE_BOOL_YES;
+        } else {
+            (*def)->mac_check = VIR_TRISTATE_BOOL_NO;
+        }
+    }
+
     /* vmx:virtualDev, vmx:features -> def:model */
     if (virVMXGetConfigString(conf, virtualDev_name, &virtualDev, true) < 0 ||
         virVMXGetConfigLong(conf, features_name, &features, 0, true) < 0) {
@@ -3865,6 +3873,9 @@ virVMXFormatEthernet(virDomainNetDefPtr def, int controller,
             mac_check = VIR_TRISTATE_BOOL_ABSENT;
     }
 
+    if (def->mac_check != VIR_TRISTATE_BOOL_ABSENT)
+        mac_check = def->mac_check;
+
     if (mac_type == VIR_DOMAIN_NET_MAC_TYPE_GENERATED) {
         virBufferAsprintf(buffer, "ethernet%d.addressType = \"%s\"\n",
                           controller, mac_vpx ? "vpx" : "generated");
diff --git a/tests/genericxml2xmlindata/network-interface-mac-check.xml b/tests/genericxml2xmlindata/network-interface-mac-check.xml
new file mode 100644 (file)
index 0000000..a84452f
--- /dev/null
@@ -0,0 +1,29 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219136</memory>
+  <currentMemory unit='KiB'>219136</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <interface type='bridge'>
+      <mac address='aa:bb:cc:dd:ee:ff'/>
+      <source bridge='br0'/>
+    </interface>
+    <interface type='bridge'>
+      <mac address='aa:bb:cc:dd:ee:fe' type='static' check='yes'/>
+      <source bridge='br1'/>
+    </interface>
+    <interface type='bridge'>
+      <mac address='aa:bb:cc:dd:ee:fd' type='generated' check='no'/>
+      <source bridge='br2'/>
+    </interface>
+  </devices>
+</domain>
index 8b9b0bafb6b45f9993a05b1591f7f7049f74a5e7..102abfdec25702c0a552a4517574d11ba41433dc 100644 (file)
@@ -183,6 +183,8 @@ mymain(void)
     DO_TEST("cpu-cache-passthrough");
     DO_TEST("cpu-cache-disable");
 
+    DO_TEST("network-interface-mac-check");
+
     DO_TEST_DIFFERENT("chardev-tcp");
     DO_TEST_FULL("chardev-tcp-missing-host", 0, false,
                  TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
index b90dfe5d9b5e4a25e250e3f761530172098e0445..ef324405d7d6eb953eb5caf05ce608cfcd2b3c1e 100644 (file)
@@ -12,7 +12,7 @@
   <on_crash>destroy</on_crash>
   <devices>
     <interface type='bridge'>
-      <mac address='00:12:34:56:78:90' type='static'/>
+      <mac address='00:12:34:56:78:90' type='static' check='no'/>
       <source bridge='VM Network'/>
     </interface>
     <video>
index 061aed3010b8cd33af01a30faa879ef0a583f811..8d7a0671888cfd41fdb48be9cd5fa3f5e387b5a3 100644 (file)
@@ -20,9 +20,11 @@ ethernet1.networkName = "br1"
 ethernet1.connectionType = "bridged"
 ethernet1.addressType = "static"
 ethernet1.address = "00:0c:29:dd:ee:fe"
+ethernet1.checkMACAddress = "true"
 ethernet2.present = "true"
 ethernet2.networkName = "br2"
 ethernet2.connectionType = "bridged"
 ethernet2.addressType = "generated"
 ethernet2.generatedAddress = "aa:bb:cc:dd:ee:fd"
 ethernet2.generatedAddressOffset = "0"
+ethernet2.checkMACAddress = "false"
index ee85a1a56a6b82e3cf525ceb224fe8a7f0000603..850fc4d80aa82b2e6ba0c7ca5db285ddc83555a0 100644 (file)
       <source bridge='br0'/>
     </interface>
     <interface type='bridge'>
-      <mac address='00:0c:29:dd:ee:fe' type='static'/>
+      <mac address='00:0c:29:dd:ee:fe' type='static' check='yes'/>
       <source bridge='br1'/>
     </interface>
     <interface type='bridge'>
-      <mac address='aa:bb:cc:dd:ee:fd' type='generated'/>
+      <mac address='aa:bb:cc:dd:ee:fd' type='generated' check='no'/>
       <source bridge='br2'/>
     </interface>
   </devices>