]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: support vlan change for linux host bridge during update-device
authorLaine Stump <laine@redhat.com>
Sun, 12 Jan 2025 02:10:40 +0000 (21:10 -0500)
committerMichal Privoznik <mprivozn@redhat.com>
Mon, 13 Jan 2025 08:58:00 +0000 (09:58 +0100)
Since we previously only supported vlan tagging for interfaces
connected to an OVS bridge [*], the code in qemuChangeNet() (used by
the update-device API) assumed an interface with modified vlan config
was on an OVS bridge, and would call the OVS-specific
virNetDevOpenvswitchUpdateVlan().

Now that we support vlan tagging for interfaces connected to a
standard Linux host bridge, we must check the type of connection and
only call the OVS function when connected to an OVS bridge *both
before and after the update*. Otherwise we just set the flag to
re-connect to the bridge, which has the side effect of redoing the
vlan setup.

([*] or an SRIOV VF assigned using VFIO, but we don't support *any
runtime changes to that type of netdev so it's irrelevant here.)

Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/qemu/qemu_hotplug.c

index de0777d330fd606f007c9be451ca0601a0c22159..5a7e6c3b1218b7bdc70e3f59d0cd1c920dd70b00 100644 (file)
@@ -4144,8 +4144,13 @@ qemuDomainChangeNet(virQEMUDriver *driver,
      * they don't apply to a particular type.
      */
 
-    if (!virNetDevVlanEqual(virDomainNetGetActualVlan(olddev),
-                             virDomainNetGetActualVlan(newdev))) {
+    /* since attaching to a new bridge will re-do the vlan setup,
+     * we don't need to separately do that in the case that we're
+     * already switching to a different bridge
+     */
+    if (!(needBridgeChange ||
+          virNetDevVlanEqual(virDomainNetGetActualVlan(olddev),
+                             virDomainNetGetActualVlan(newdev)))) {
         needVlanUpdate = true;
     }
 
@@ -4215,6 +4220,23 @@ qemuDomainChangeNet(virQEMUDriver *driver,
         needReplaceDevDef = true;
     }
 
+    if (needVlanUpdate) {
+        if (virDomainNetDefIsOvsport(olddev) && virDomainNetDefIsOvsport(newdev)) {
+            /* optimization if we're attached to an OVS bridge. This
+             * will redo vlan setup without needing to re-attach the
+             * tap device to the bridge
+             */
+            if (virNetDevOpenvswitchUpdateVlan(newdev->ifname, &newdev->vlan) < 0)
+                goto cleanup;
+        } else {
+             /* vlan setup is done as a part of reconnecting the tap
+              * device to a new bridge (either OVS or Linux host bridge).
+              */
+            needBridgeChange = true;
+        }
+        needReplaceDevDef = true;
+    }
+
     if (needBridgeChange) {
         if (qemuDomainChangeNetBridge(vm, olddev, newdev) < 0)
             goto cleanup;
@@ -4266,12 +4288,6 @@ qemuDomainChangeNet(virQEMUDriver *driver,
         goto cleanup;
     }
 
-    if (needVlanUpdate) {
-        if (virNetDevOpenvswitchUpdateVlan(newdev->ifname, &newdev->vlan) < 0)
-            goto cleanup;
-        needReplaceDevDef = true;
-    }
-
     if (needReplaceDevDef) {
         /* the changes above warrant replacing olddev with newdev in
          * the domain's nets list.