A new function virNetDevOpenvswitchUpdateVlan has been created to instruct OVS of the changes. qemuDomainChangeNet has been modified to handle the update of the VLAN configuration for a running guest and rely on virNetDevOpenvswitchUpdateVlan to do the actual update if needed. --- src/libvirt_private.syms | 1 + src/qemu/qemu_hotplug.c | 16 +++++++++++++--- src/util/virnetdevopenvswitch.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/util/virnetdevopenvswitch.h | 4 ++++ 4 files changed, 59 insertions(+), 3 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 187b12b32..36caf6fbf 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2206,6 +2206,7 @@ virNetDevOpenvswitchInterfaceStats; virNetDevOpenvswitchRemovePort; virNetDevOpenvswitchSetMigrateData; virNetDevOpenvswitchSetTimeout; +virNetDevOpenvswitchUpdateVlan; # util/virnetdevtap.h diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 4bc49720b..b9ad9e6c8 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -2998,6 +2998,7 @@ qemuDomainChangeNet(virQEMUDriverPtr driver, bool needReplaceDevDef = false; bool needBandwidthSet = false; bool needCoalesceChange = false; + bool needVlanUpdate = false; int ret = -1; int changeidx = -1; @@ -3279,12 +3280,15 @@ qemuDomainChangeNet(virQEMUDriverPtr driver, virDomainNetGetActualDirectDev(newdev)) || virDomainNetGetActualDirectMode(olddev) != virDomainNetGetActualDirectMode(newdev) || !virNetDevVPortProfileEqual(virDomainNetGetActualVirtPortProfile(olddev), - virDomainNetGetActualVirtPortProfile(newdev)) || - !virNetDevVlanEqual(virDomainNetGetActualVlan(olddev), - virDomainNetGetActualVlan(newdev))) { + virDomainNetGetActualVirtPortProfile(newdev))) { needReconnect = true; } + if (!virNetDevVlanEqual(virDomainNetGetActualVlan(olddev), + virDomainNetGetActualVlan(newdev))) { + needVlanUpdate = true; + } + if (olddev->linkstate != newdev->linkstate) needLinkStateChange = true; @@ -3344,6 +3348,12 @@ qemuDomainChangeNet(virQEMUDriverPtr 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. diff --git a/src/util/virnetdevopenvswitch.c b/src/util/virnetdevopenvswitch.c index 89ed0c91c..a12bc3dbc 100644 --- a/src/util/virnetdevopenvswitch.c +++ b/src/util/virnetdevopenvswitch.c @@ -459,3 +459,44 @@ virNetDevOpenvswitchGetVhostuserIfname(const char *path, VIR_FREE(ovs_timeout); return ret; } + +/** + * virNetDevOpenvswitchUpdateVlan: + * @ifname: the network interface name + * @virtVlan: VLAN configuration to be applied + * + * Update VLAN configuration of an OVS port. + * + * Returns 0 in case of success or -1 in case of failure. + */ +int virNetDevOpenvswitchUpdateVlan(const char *ifname, + virNetDevVlanPtr virtVlan) +{ + int ret = -1; + virCommandPtr cmd = NULL; + + cmd = virCommandNew(OVSVSCTL); + virNetDevOpenvswitchAddTimeout(cmd); + virCommandAddArgList(cmd, + "--", "--if-exists", "clear", "Port", ifname, "tag", + "--", "--if-exists", "clear", "Port", ifname, "trunk", + "--", "--if-exists", "clear", "Port", ifname, "vlan_mode", + "--", "--if-exists", "set", "Port", ifname, NULL); + + if (virNetDevOpenvswitchConstructVlans(cmd, virtVlan) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to construct vlan configuration for port %s"), ifname); + goto cleanup; + } + + if (virCommandRun(cmd, NULL) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to set vlan configuration on port %s"), ifname); + goto cleanup; + } + + ret = 0; + cleanup: + virCommandFree(cmd); + return ret; +} diff --git a/src/util/virnetdevopenvswitch.h b/src/util/virnetdevopenvswitch.h index 94b4c695b..aa69ade6a 100644 --- a/src/util/virnetdevopenvswitch.h +++ b/src/util/virnetdevopenvswitch.h @@ -66,4 +66,8 @@ int virNetDevOpenvswitchGetVhostuserIfname(const char *path, char **ifname) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NOINLINE; +int virNetDevOpenvswitchUpdateVlan(const char *ifname, + virNetDevVlanPtr virtVlan) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + #endif /* __VIR_NETDEV_OPENVSWITCH_H__ */ -- 2.13.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list