[libvirt] [PATCH 2/2] Handle hotplug change on VLAN configuration using OVS

Antoine Millet antoine.millet at tdf.fr
Mon Jul 17 15:49:00 UTC 2017


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




More information about the libvir-list mailing list