[RFC PATCH 1/3] util: bridge: add virNetDevBridgeSetupVlans()

Leigh Brown posted 3 patches 2 weeks, 3 days ago
There is a newer version of this series
[RFC PATCH 1/3] util: bridge: add virNetDevBridgeSetupVlans()
Posted by Leigh Brown 2 weeks, 3 days ago
In preparation for adding vlan support using iproute2 bridge vlan
functionality, add the virNetDevBridgeSetupVlans function that
configures a bridge interface using the passed virNetDevVlan
struct.

Signed-off-by: Leigh Brown <leigh@solinno.co.uk>
---
 meson.build                |  1 +
 src/util/virnetdevbridge.c | 54 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/meson.build b/meson.build
index ca1b915737..39c01ebeef 100644
--- a/meson.build
+++ b/meson.build
@@ -857,6 +857,7 @@ optional_programs = [
   'ovs-vsctl',
   'rmmod',
   'tc',
+  'bridge',
 ] + optional_test_programs
 
 missing_optional_programs = []
diff --git a/src/util/virnetdevbridge.c b/src/util/virnetdevbridge.c
index 5fd88f3195..0862342cee 100644
--- a/src/util/virnetdevbridge.c
+++ b/src/util/virnetdevbridge.c
@@ -24,6 +24,7 @@
 #include "virfile.h"
 #include "virlog.h"
 #include "virstring.h"
+#include "vircommand.h"
 
 #ifdef WITH_NET_IF_H
 # include <net/if.h>
@@ -379,8 +380,61 @@ virNetDevBridgePortSetIsolated(const char *brname G_GNUC_UNUSED,
                          _("Unable to set bridge port isolated on this platform"));
     return -1;
 }
+
 #endif
 
+static int
+virNetDevBridgeSetupVlans(const char *ifname, const virNetDevVlan *virtVlan)
+{
+    g_autoptr(virCommand) cmd = NULL;
+
+    if (!virtVlan || !virtVlan->nTags)
+        return 0;
+
+    // The interface will have been automatically added to vlan 1, so remove it
+    cmd = virCommandNewArgList(BRIDGE, "vlan", "delete",
+                                       "dev", ifname, "vid", "1", NULL);
+    if (virCommandRun(cmd, NULL) < 0)
+        return -1;
+
+    // If trunk mode, add the native VLAN then add any others
+    if (virtVlan->trunk) {
+        size_t i;
+
+        virCommandFree(cmd);
+        cmd = virCommandNewArgList(BRIDGE, "vlan", "add",
+                                   "dev", ifname, "vid", NULL);
+        virCommandAddArgFormat(cmd, "%d", virtVlan->nativeTag);
+        virCommandAddArg(cmd, "pvid");
+        if (virtVlan->nativeMode == VIR_NATIVE_VLAN_MODE_UNTAGGED)
+            virCommandAddArg(cmd, "untagged");
+        if (virCommandRun(cmd, NULL) < 0)
+            return -1;
+
+        for (i = 0; i < virtVlan->nTags; i++) {
+            if (virtVlan->tag[i] != virtVlan->nativeTag) {
+                virCommandFree(cmd);
+                cmd = virCommandNewArgList(BRIDGE, "vlan", "add",
+                                           "dev", ifname, "vid", NULL);
+                virCommandAddArgFormat(cmd, "%d", virtVlan->tag[i]);
+                if (virCommandRun(cmd, NULL) < 0)
+                    return -1;
+            }
+        }
+    } else {
+        // In native mode, add the single VLAN as pvid untagged
+        virCommandFree(cmd);
+        cmd = virCommandNewArgList(BRIDGE, "vlan", "add",
+                                   "dev", ifname, "vid", NULL);
+        virCommandAddArgFormat(cmd, "%d", virtVlan->tag[0]);
+        virCommandAddArgList(cmd, "pvid", "untagged", NULL);
+        if (virCommandRun(cmd, NULL) < 0)
+            return -1;
+    }
+
+    return 0;
+}
+
 
 /**
  * virNetDevBridgeCreate:
-- 
2.39.5