conf: Generate MAC address instead of keeping all zeroes

When we parse <mac address="00:00:00:00:00:00"/> we keep that in memory
and pass it down to the hypervisor. However, that MAC address is not
strictly valid as it is not marked as locally administered (bit 0x02)
but it is not even globally unique. It is also used for loopback device
on Linux, for example. And QEMU sees such MAC address just as "not
specified" and generates a new one that libvirt does not even know
about. So to make the overall experience better we now generate it if
the supplied one is all clear.

Resolves: https://issues.redhat.com/browse/RHEL-974

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Martin Kletzander 2023-09-01 16:51:59 +02:00
parent c2e6897e54
commit e95b81c2fd
7 changed files with 53 additions and 2 deletions

View File

@ -9665,7 +9665,7 @@ virDomainNetDefParseXML(virDomainXMLOption *xmlopt,
return NULL; return NULL;
} }
if (!macaddr) { if (!macaddr || virMacAddrIsAllClear(&def->mac)) {
virDomainNetGenerateMAC(xmlopt, &def->mac); virDomainNetGenerateMAC(xmlopt, &def->mac);
def->mac_generated = true; def->mac_generated = true;
} }

View File

@ -2743,6 +2743,7 @@ virMacAddrCompare;
virMacAddrFormat; virMacAddrFormat;
virMacAddrGenerate; virMacAddrGenerate;
virMacAddrGetRaw; virMacAddrGetRaw;
virMacAddrIsAllClear;
virMacAddrIsBroadcastRaw; virMacAddrIsBroadcastRaw;
virMacAddrIsMulticast; virMacAddrIsMulticast;
virMacAddrIsUnicast; virMacAddrIsUnicast;

View File

@ -246,6 +246,11 @@ virMacAddrIsBroadcastRaw(const unsigned char s[VIR_MAC_BUFLEN])
return memcmp(virMacAddrBroadcastAddrRaw, s, sizeof(*s)) == 0; return memcmp(virMacAddrBroadcastAddrRaw, s, sizeof(*s)) == 0;
} }
bool virMacAddrIsAllClear(const virMacAddr *addr)
{
return !virMacAddrCmpRaw(addr, (const unsigned char[VIR_MAC_BUFLEN]){0});
}
void void
virMacAddrFree(virMacAddr *addr) virMacAddrFree(virMacAddr *addr)
{ {

View File

@ -58,6 +58,7 @@ int virMacAddrParseHex(const char* str,
bool virMacAddrIsUnicast(const virMacAddr *addr); bool virMacAddrIsUnicast(const virMacAddr *addr);
bool virMacAddrIsMulticast(const virMacAddr *addr); bool virMacAddrIsMulticast(const virMacAddr *addr);
bool virMacAddrIsBroadcastRaw(const unsigned char s[VIR_MAC_BUFLEN]); bool virMacAddrIsBroadcastRaw(const unsigned char s[VIR_MAC_BUFLEN]);
bool virMacAddrIsAllClear(const virMacAddr *addr);
void virMacAddrFree(virMacAddr *addr); void virMacAddrFree(virMacAddr *addr);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virMacAddr, virMacAddrFree); G_DEFINE_AUTOPTR_CLEANUP_FUNC(virMacAddr, virMacAddrFree);

View File

@ -0,0 +1,21 @@
<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='x86_64' 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='00:00:00:00:00:00'/>
<source bridge='br0'/>
</interface>
</devices>
</domain>

View File

@ -0,0 +1,21 @@
<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='x86_64' 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='52:54:00:00:00:00'/>
<source bridge='br0'/>
</interface>
</devices>
</domain>

View File

@ -187,6 +187,7 @@ mymain(void)
DO_TEST("cpu-cache-disable"); DO_TEST("cpu-cache-disable");
DO_TEST("network-interface-mac-check"); DO_TEST("network-interface-mac-check");
DO_TEST_DIFFERENT("network-interface-mac-clear");
DO_TEST_DIFFERENT("chardev-tcp"); DO_TEST_DIFFERENT("chardev-tcp");
DO_TEST_FAIL_ACTIVE("chardev-tcp-missing-host"); DO_TEST_FAIL_ACTIVE("chardev-tcp-missing-host");
@ -257,4 +258,5 @@ mymain(void)
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
} }
VIR_TEST_MAIN(mymain) VIR_TEST_MAIN_PRELOAD(mymain,
VIR_TEST_MOCK("virrandom"))