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@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On 07/17/2017 05:49 PM, Antoine Millet wrote:
> 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);
This rewrites original error reported by
virNetDevOpenvswitchConstructVlans().
> + 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;
> +}
ACK
Michal
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
© 2016 - 2026 Red Hat, Inc.