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
if (!def)
return;
+ g_free(def->currentAddress);
g_free(def->modelstr);
switch (def->type) {
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) {
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 {
<ref name="virYesNo"/>
</attribute>
</optional>
+ <optional>
+ <attribute name="currentAddress">
+ <ref name="uniMacAddr"/>
+ </attribute>
+ </optional>
<empty/>
</element>
</optional>
}
+/**
+ * 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,
qemuDomainObjPrivate *priv = vm->privateData;
g_autoptr(virNetDevRxFilter) guestFilter = NULL;
g_autoptr(virNetDevRxFilter) hostFilter = NULL;
+ virMacAddr *oldMac = NULL;
int rc;
if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0)
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;
}
"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)) {