diff --git a/docs/drvesx.html.in b/docs/drvesx.html.in index ac7bc645d1..59b27bd43e 100644 --- a/docs/drvesx.html.in +++ b/docs/drvesx.html.in @@ -427,6 +427,13 @@ error: invalid argument in libvirt was built without the 'esx' driver
 ethernet0.checkMACAddress = "false"
 
+

+ Since 6.6.0, one can force libvirt to keep the + provided MAC address when it's in the reserved VMware range by adding a + type="static" attribute to the <mac/> element. + Note that this attribute is useless if the provided MAC address is outside of + the reserved VMWare ranges. +

Available hardware

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 84eafe6cd2..f5ee97de81 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -5768,6 +5768,13 @@ attribute type='pci' as documented above.

+

+ Since 6.6.0, one can force libvirt to keep the + provided MAC address when it's in the reserved VMware range by adding a + type="static" attribute to the <mac/> element. + Note that this attribute is useless if the provided MAC address is outside of + the reserved VMWare ranges. +

Virtual network
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 4b4aa60c66..a810f569c6 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -3179,6 +3179,14 @@ + + + + generated + static + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d14485f18d..bcebfc633f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -611,6 +611,13 @@ VIR_ENUM_IMPL(virDomainChrDeviceState, "disconnected", ); +VIR_ENUM_IMPL(virDomainNetMacType, + VIR_DOMAIN_NET_MAC_TYPE_LAST, + "", + "generated", + "static", +); + VIR_ENUM_IMPL(virDomainChrSerialTarget, VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_LAST, "none", @@ -11904,6 +11911,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, virDomainChrSourceReconnectDef reconnect = {0}; int rv, val; g_autofree char *macaddr = NULL; + g_autofree char *macaddr_type = NULL; g_autofree char *type = NULL; g_autofree char *network = NULL; g_autofree char *portgroup = NULL; @@ -11984,6 +11992,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, } if (!macaddr && virXMLNodeNameEqual(cur, "mac")) { macaddr = virXMLPropString(cur, "address"); + macaddr_type = virXMLPropString(cur, "type"); } else if (!network && def->type == VIR_DOMAIN_NET_TYPE_NETWORK && virXMLNodeNameEqual(cur, "source")) { @@ -12173,6 +12182,18 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, def->mac_generated = true; } + if (macaddr_type) { + int tmp; + if ((tmp = virDomainNetMacTypeTypeFromString(macaddr_type)) <= 0) { + virReportError(VIR_ERR_XML_ERROR, + _("invalid mac address check value: '%s'. Valid " + "values are \"generated\" and \"static\"."), + macaddr_type); + goto error; + } + def->mac_type = tmp; + } + if (virDomainDeviceInfoParseXML(xmlopt, node, &def->info, flags | VIR_DOMAIN_DEF_PARSE_ALLOW_BOOT | VIR_DOMAIN_DEF_PARSE_ALLOW_ROM) < 0) { @@ -26468,8 +26489,11 @@ virDomainNetDefFormat(virBufferPtr buf, virBufferAddLit(buf, ">\n"); virBufferAdjustIndent(buf, 2); - virBufferAsprintf(buf, "\n", + virBufferAsprintf(buf, "mac, macstr)); + if (def->mac_type) + virBufferAsprintf(buf, " type='%s'", virDomainNetMacTypeTypeToString(def->mac_type)); + virBufferAddLit(buf, "/>\n"); if (publicActual) { /* when there is a virDomainActualNetDef, and we haven't been diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 6a737591e2..241149af24 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -921,6 +921,15 @@ typedef enum { VIR_DOMAIN_NET_VIRTIO_TX_MODE_LAST } virDomainNetVirtioTxModeType; +/* whether a mac address should be marked as generated in the esx driver or not*/ +typedef enum { + VIR_DOMAIN_NET_MAC_TYPE_DEFAULT = 0, /* generated */ + VIR_DOMAIN_NET_MAC_TYPE_GENERATED, + VIR_DOMAIN_NET_MAC_TYPE_STATIC, + + VIR_DOMAIN_NET_MAC_TYPE_LAST +} virDomainNetMacType; + /* the type of teaming device */ typedef enum { VIR_DOMAIN_NET_TEAMING_TYPE_NONE, @@ -972,6 +981,7 @@ struct _virDomainNetDef { virDomainNetType type; virMacAddr mac; bool mac_generated; /* true if mac was *just now* auto-generated by libvirt */ + virDomainNetMacType mac_type; int model; /* virDomainNetModelType */ char *modelstr; union { @@ -3556,6 +3566,7 @@ VIR_ENUM_DECL(virDomainFSCacheMode); VIR_ENUM_DECL(virDomainNet); VIR_ENUM_DECL(virDomainNetBackend); VIR_ENUM_DECL(virDomainNetVirtioTxMode); +VIR_ENUM_DECL(virDomainNetMacType); VIR_ENUM_DECL(virDomainNetTeaming); VIR_ENUM_DECL(virDomainNetInterfaceLinkState); VIR_ENUM_DECL(virDomainNetModel); diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c index d4d66f6768..97ec84446a 100644 --- a/src/vmx/vmx.c +++ b/src/vmx/vmx.c @@ -3732,6 +3732,7 @@ virVMXFormatEthernet(virDomainNetDefPtr def, int controller, virBufferPtr buffer, int virtualHW_version) { char mac_string[VIR_MAC_STRING_BUFLEN]; + const bool staticMac = def->mac_type == VIR_DOMAIN_NET_MAC_TYPE_STATIC; unsigned int prefix, suffix; /* @@ -3829,19 +3830,19 @@ virVMXFormatEthernet(virDomainNetDefPtr def, int controller, prefix = (def->mac.addr[0] << 16) | (def->mac.addr[1] << 8) | def->mac.addr[2]; suffix = (def->mac.addr[3] << 16) | (def->mac.addr[4] << 8) | def->mac.addr[5]; - if (prefix == 0x000c29) { + if (prefix == 0x000c29 && !staticMac) { virBufferAsprintf(buffer, "ethernet%d.addressType = \"generated\"\n", controller); virBufferAsprintf(buffer, "ethernet%d.generatedAddress = \"%s\"\n", controller, mac_string); virBufferAsprintf(buffer, "ethernet%d.generatedAddressOffset = \"0\"\n", controller); - } else if (prefix == 0x005056 && suffix <= 0x3fffff) { + } else if (prefix == 0x005056 && suffix <= 0x3fffff && !staticMac) { virBufferAsprintf(buffer, "ethernet%d.addressType = \"static\"\n", controller); virBufferAsprintf(buffer, "ethernet%d.address = \"%s\"\n", controller, mac_string); - } else if (prefix == 0x005056 && suffix >= 0x800000 && suffix <= 0xbfffff) { + } else if (prefix == 0x005056 && suffix >= 0x800000 && suffix <= 0xbfffff && !staticMac) { virBufferAsprintf(buffer, "ethernet%d.addressType = \"vpx\"\n", controller); virBufferAsprintf(buffer, "ethernet%d.generatedAddress = \"%s\"\n", diff --git a/tests/xml2vmxdata/xml2vmx-ethernet-mac-type.vmx b/tests/xml2vmxdata/xml2vmx-ethernet-mac-type.vmx new file mode 100644 index 0000000000..212b3f192c --- /dev/null +++ b/tests/xml2vmxdata/xml2vmx-ethernet-mac-type.vmx @@ -0,0 +1,29 @@ +.encoding = "UTF-8" +config.version = "8" +virtualHW.version = "4" +guestOS = "other" +uuid.bios = "c7 a5 fd bd ed af 94 55-92 6a d6 5c 16 db 18 09" +displayName = "ethernet-mac-type" +memsize = "216" +sched.mem.max = "214" +numvcpus = "1" +floppy0.present = "false" +floppy1.present = "false" +ethernet0.present = "true" +ethernet0.networkName = "br0" +ethernet0.connectionType = "bridged" +ethernet0.addressType = "static" +ethernet0.address = "aa:bb:cc:dd:ee:ff" +ethernet0.checkMACAddress = "false" +ethernet1.present = "true" +ethernet1.networkName = "br1" +ethernet1.connectionType = "bridged" +ethernet1.addressType = "static" +ethernet1.address = "00:0c:29:dd:ee:fe" +ethernet1.checkMACAddress = "false" +ethernet2.present = "true" +ethernet2.networkName = "br2" +ethernet2.connectionType = "bridged" +ethernet2.addressType = "static" +ethernet2.address = "aa:bb:cc:dd:ee:fd" +ethernet2.checkMACAddress = "false" diff --git a/tests/xml2vmxdata/xml2vmx-ethernet-mac-type.xml b/tests/xml2vmxdata/xml2vmx-ethernet-mac-type.xml new file mode 100644 index 0000000000..ee85a1a56a --- /dev/null +++ b/tests/xml2vmxdata/xml2vmx-ethernet-mac-type.xml @@ -0,0 +1,29 @@ + + ethernet-mac-type + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219136 + 219136 + 1 + + hvm + + + + destroy + restart + destroy + + + + + + + + + + + + + + + diff --git a/tests/xml2vmxtest.c b/tests/xml2vmxtest.c index 8f0a2a72a4..b74fda29ef 100644 --- a/tests/xml2vmxtest.c +++ b/tests/xml2vmxtest.c @@ -255,6 +255,7 @@ mymain(void) DO_TEST("ethernet-static", "ethernet-static", 4); DO_TEST("ethernet-vpx", "ethernet-vpx", 4); DO_TEST("ethernet-other", "ethernet-other", 4); + DO_TEST("ethernet-mac-type", "ethernet-mac-type", 4); DO_TEST("serial-file", "serial-file", 4); DO_TEST("serial-device", "serial-device", 4);