]> xenbits.xensource.com Git - people/aperard/libvirt.git/commitdiff
qemuDomainChangeNet: Reflect trustGuestRxFilters change
authorMichal Privoznik <mprivozn@redhat.com>
Tue, 5 Dec 2023 13:32:48 +0000 (14:32 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Wed, 6 Dec 2023 11:36:03 +0000 (12:36 +0100)
On device-update, when user requests change of
trustGuestRxFilters we currently do nothing. Nor error out, nor
act on the request. While we can just throw an error,
implementing this is pretty trivial.

Resolves: https://issues.redhat.com/browse/RHEL-735
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/qemu/qemu_hotplug.c

index 4e2fc724c03a01d3d7197f52d1f7a828dfc1cee9..75e1d39b6042f4f2b87abc238535150c62f43855 100644 (file)
@@ -3625,6 +3625,43 @@ qemuDomainChangeNetLinkState(virDomainObj *vm,
     return ret;
 }
 
+static int
+qemuDomainQueryRxFilterDummy(virDomainObj *vm,
+                             virDomainNetDef *dev,
+                             bool trustGuestRxFilters)
+{
+    qemuDomainObjPrivate *priv = vm->privateData;
+
+    VIR_DEBUG("dev: %s, trustGuestRxFilters: %d",
+              NULLSTR(dev->info.alias), trustGuestRxFilters);
+
+    /* Transition from "yes" to "no" is simple, just record the new
+     * setting and processNicRxFilterChangedEvent() will ignore
+     * NIC_RX_FILTER_CHANGED event.
+     * Transition from "no" to "yes" requires issuing query-rx-filter
+     * monitor command to enable the event delivery again.
+     */
+    if (trustGuestRxFilters) {
+        int rc;
+
+        if (!dev->info.alias) {
+            virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+                           _("can't query rx filters: device alias not found"));
+            return -1;
+        }
+
+        qemuDomainObjEnterMonitor(vm);
+        rc = qemuMonitorQueryRxFilter(priv->mon, dev->info.alias, NULL);
+        qemuDomainObjExitMonitor(vm);
+        if (rc < 0)
+            return -1;
+    }
+
+    /* modify the device configuration */
+    dev->trustGuestRxFilters = trustGuestRxFilters;
+    return 0;
+}
+
 static int
 qemuDomainChangeNet(virQEMUDriver *driver,
                     virDomainObj *vm,
@@ -3644,6 +3681,7 @@ qemuDomainChangeNet(virQEMUDriver *driver,
     bool needCoalesceChange = false;
     bool needVlanUpdate = false;
     bool needIsolatedPortChange = false;
+    bool needQueryRxFilter = false;
     int ret = -1;
     int changeidx = -1;
     g_autoptr(virConnect) conn = NULL;
@@ -3999,6 +4037,11 @@ qemuDomainChangeNet(virQEMUDriver *driver,
         needIsolatedPortChange = true;
     }
 
+    if (virDomainNetGetActualTrustGuestRxFilters(olddev) !=
+        virDomainNetGetActualTrustGuestRxFilters(newdev)) {
+        needQueryRxFilter = true;
+    }
+
     if (olddev->linkstate != newdev->linkstate)
         needLinkStateChange = true;
 
@@ -4091,6 +4134,14 @@ qemuDomainChangeNet(virQEMUDriver *driver,
         needReplaceDevDef = true;
     }
 
+    if (needQueryRxFilter) {
+        if (qemuDomainQueryRxFilterDummy(vm, olddev,
+                                         virDomainNetGetActualTrustGuestRxFilters(newdev)) < 0) {
+            goto cleanup;
+        }
+        needReplaceDevDef = true;
+    }
+
     if (needLinkStateChange &&
         qemuDomainChangeNetLinkState(vm, olddev, newdev->linkstate) < 0) {
         goto cleanup;