qemu: support vlan change for linux host bridge during update-device

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>
This commit is contained in:
Laine Stump 2025-01-11 21:10:40 -05:00 committed by Michal Privoznik
parent f35bddae90
commit 7a903458f1

View 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.