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.
+
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.
+
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);