From 060d4c83ef436cf56abfad51a4d64c39448e199d Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Fri, 30 Sep 2022 16:28:24 +0200 Subject: [PATCH] qemu: Refresh rx-filters more often MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are couple of scenarios where we need to reflect MAC change done in the guest: 1) domain restore from a file (here, we don't store updated MAC in the save file and thus on restore create the macvtap with the original MAC), 2) reconnecting to a running domain (here, the guest might have changed the MAC while we were not running), 3) migration (here, guest might change the MAC address but we fail to respond to it, Signed-off-by: Michal Privoznik Reviewed-by: Ján Tomko --- src/qemu/qemu_domain.c | 9 ++++++--- src/qemu/qemu_domain.h | 3 ++- src/qemu/qemu_driver.c | 2 +- src/qemu/qemu_process.c | 27 +++++++++++++++++++++++++++ 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 3ad01d7199..7cc58d9e2e 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -12017,14 +12017,17 @@ syncNicRxFilterMulticast(char *ifname, int qemuDomainSyncRxFilter(virDomainObj *vm, - virDomainNetDef *def) + virDomainNetDef *def, + virDomainAsyncJob asyncJob) { qemuDomainObjPrivate *priv = vm->privateData; g_autoptr(virNetDevRxFilter) guestFilter = NULL; g_autoptr(virNetDevRxFilter) hostFilter = NULL; int rc; - qemuDomainObjEnterMonitor(vm); + if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0) + return -1; + rc = qemuMonitorQueryRxFilter(priv->mon, def->info.alias, &guestFilter); qemuDomainObjExitMonitor(vm); if (rc < 0) @@ -12032,7 +12035,7 @@ qemuDomainSyncRxFilter(virDomainObj *vm, if (virDomainNetGetActualType(def) == VIR_DOMAIN_NET_TYPE_DIRECT) { if (virNetDevGetRxFilter(def->ifname, &hostFilter)) { - VIR_WARN("Couldn't get current RX filter for device %s while responding to NIC_RX_FILTER_CHANGED", + VIR_WARN("Couldn't get current RX filter for device %s", def->ifname); return -1; } diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index d5509d7e5f..d2e5d4661a 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -1106,4 +1106,5 @@ qemuDomainRefreshStatsSchema(virDomainObj *dom); int qemuDomainSyncRxFilter(virDomainObj *vm, - virDomainNetDef *def); + virDomainNetDef *def, + virDomainAsyncJob asyncJob); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index e2ca9a3961..59a3b37b98 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3662,7 +3662,7 @@ processNicRxFilterChangedEvent(virDomainObj *vm, VIR_DEBUG("process NIC_RX_FILTER_CHANGED event for network " "device %s in domain %s", def->info.alias, vm->def->name); - if (qemuDomainSyncRxFilter(vm, def) < 0) + if (qemuDomainSyncRxFilter(vm, def, VIR_ASYNC_JOB_NONE) < 0) goto endjob; endjob: diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 1a9175f40f..fe98601fce 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -7756,6 +7756,26 @@ qemuProcessLaunch(virConnectPtr conn, } +static int +qemuProcessRefreshRxFilters(virDomainObj *vm, + virDomainAsyncJob asyncJob) +{ + size_t i; + + for (i = 0; i < vm->def->nnets; i++) { + virDomainNetDef *def = vm->def->nets[i]; + + if (!virDomainNetGetActualTrustGuestRxFilters(def)) + continue; + + if (qemuDomainSyncRxFilter(vm, def, asyncJob) < 0) + return -1; + } + + return 0; +} + + /** * qemuProcessRefreshState: * @driver: qemu driver data @@ -7787,6 +7807,10 @@ qemuProcessRefreshState(virQEMUDriver *driver, if (qemuProcessRefreshDisks(vm, asyncJob) < 0) return -1; + VIR_DEBUG("Updating rx-filter data"); + if (qemuProcessRefreshRxFilters(vm, asyncJob) < 0) + return -1; + return 0; } @@ -8807,6 +8831,9 @@ qemuProcessReconnect(void *opaque) if (qemuSecurityReserveLabel(driver->securityManager, obj->def, obj->pid) < 0) goto error; + if (qemuProcessRefreshRxFilters(obj, VIR_ASYNC_JOB_NONE) < 0) + goto error; + qemuProcessNotifyNets(obj->def); qemuProcessFiltersInstantiate(obj->def);