mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-30 18:50:18 +03:00
qemu: Reflect MAC address change in live domain XML
If a guest changes MAC address on its vNIC, then QEMU emits NIC_RX_FILTER_CHANGED event (the event is emitted in other cases too, but that's not important right now). Now, domain XML allows users to chose whether to trust these events or not: <interface trustGuestRxFilters='yes|no'/> For the 'no' case no action is performed and the event is ignored. But for the 'yes' case, some host side features of corresponding vNIC (well tap/macvtap device) are tweaked to reflect changed MAC address. But what is missing is reflecting this new MAC address in domain XML. Basically, what happens is: the host sees traffic with new MAC address, all tools inside the guest see the new MAC address (including 'virsh domifaddr --source agent') which makes it harder to match device in the guest with the one in the domain XML. Therefore, report this new MAC address as another attribute of the <mac/> element: <mac address="52:54:00:a4:6f:91" currentAddress="00:11:22:33:44:55"/> Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
This commit is contained in:
parent
d5666b3c2e
commit
ac95617d3d
@ -5052,6 +5052,11 @@ 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.
|
||||
|
||||
:since:`Since 11.2.0`, the ``<mac/>`` element can optionally contain
|
||||
``currentAddress`` attribute (output only), which contains new MAC address if the
|
||||
guest changed it. This is currently implemented only for QEMU/KVM and requires
|
||||
setting ``trustGuestRxFilters`` to ``yes``.
|
||||
|
||||
:since:`Since 7.3.0`, one can set the ACPI index against network interfaces.
|
||||
With some operating systems (eg Linux with systemd), the ACPI index is used
|
||||
to provide network interface device naming, that is stable across changes
|
||||
|
@ -2853,6 +2853,7 @@ virDomainNetDefFree(virDomainNetDef *def)
|
||||
if (!def)
|
||||
return;
|
||||
|
||||
g_free(def->currentAddress);
|
||||
g_free(def->modelstr);
|
||||
|
||||
switch (def->type) {
|
||||
@ -24948,6 +24949,11 @@ virDomainNetDefFormat(virBuffer *buf,
|
||||
virBufferAsprintf(&macAttrBuf, " type='%s'", virDomainNetMacTypeTypeToString(def->mac_type));
|
||||
if (def->mac_check != VIR_TRISTATE_BOOL_ABSENT)
|
||||
virBufferAsprintf(&macAttrBuf, " check='%s'", virTristateBoolTypeToString(def->mac_check));
|
||||
if (def->currentAddress &&
|
||||
!(flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE)) {
|
||||
virBufferAsprintf(&macAttrBuf, " currentAddress='%s'",
|
||||
virMacAddrFormat(def->currentAddress, macstr));
|
||||
}
|
||||
virXMLFormatElement(buf, "mac", &macAttrBuf, NULL);
|
||||
|
||||
if (publicActual) {
|
||||
|
@ -1091,6 +1091,9 @@ struct _virDomainNetDef {
|
||||
bool mac_generated; /* true if mac was *just now* auto-generated by libvirt */
|
||||
virDomainNetMacType mac_type;
|
||||
virTristateBool mac_check;
|
||||
virMacAddr *currentAddress; /* MAC address from query-rx-filter (as reported
|
||||
by guest). Not parsed from domain XML. Output
|
||||
only. */
|
||||
int model; /* virDomainNetModelType */
|
||||
char *modelstr;
|
||||
union {
|
||||
|
@ -3844,6 +3844,11 @@
|
||||
<ref name="virYesNo"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="currentAddress">
|
||||
<ref name="uniMacAddr"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<empty/>
|
||||
</element>
|
||||
</optional>
|
||||
|
@ -11072,6 +11072,19 @@ syncNicRxFilterMulticast(char *ifname,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* qemuDomainSyncRxFilter:
|
||||
* @vm: domain object
|
||||
* @def: domain interface definition
|
||||
* @asyncJob: async job type
|
||||
*
|
||||
* Fetch new state of RX Filter and set host side of the interface
|
||||
* accordingly (e.g. reflect MAC address change on macvtap).
|
||||
*
|
||||
* Reflect changed MAC address in the domain definition.
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
qemuDomainSyncRxFilter(virDomainObj *vm,
|
||||
virDomainNetDef *def,
|
||||
@ -11080,6 +11093,7 @@ qemuDomainSyncRxFilter(virDomainObj *vm,
|
||||
qemuDomainObjPrivate *priv = vm->privateData;
|
||||
g_autoptr(virNetDevRxFilter) guestFilter = NULL;
|
||||
g_autoptr(virNetDevRxFilter) hostFilter = NULL;
|
||||
virMacAddr *oldMac = NULL;
|
||||
int rc;
|
||||
|
||||
if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0)
|
||||
@ -11125,6 +11139,24 @@ qemuDomainSyncRxFilter(virDomainObj *vm,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (def->currentAddress)
|
||||
oldMac = def->currentAddress;
|
||||
else
|
||||
oldMac = &def->mac;
|
||||
|
||||
if (virMacAddrCmp(oldMac, &guestFilter->mac)) {
|
||||
/* Reflect changed MAC address in the domain XML. */
|
||||
if (virMacAddrCmp(&def->mac, &guestFilter->mac)) {
|
||||
if (!def->currentAddress) {
|
||||
def->currentAddress = g_new0(virMacAddr, 1);
|
||||
}
|
||||
|
||||
virMacAddrSet(def->currentAddress, &guestFilter->mac);
|
||||
} else {
|
||||
VIR_FREE(def->currentAddress);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3689,7 +3689,7 @@ processNicRxFilterChangedEvent(virDomainObj *vm,
|
||||
"from domain %p %s",
|
||||
devAlias, vm, vm->def->name);
|
||||
|
||||
if (virDomainObjBeginJob(vm, VIR_JOB_QUERY) < 0)
|
||||
if (virDomainObjBeginJob(vm, VIR_JOB_MODIFY) < 0)
|
||||
return;
|
||||
|
||||
if (!virDomainObjIsActive(vm)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user