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(a)solinno.co.uk>
---
meson.build | 1 +
src/util/virnetdevbridge.c | 57 ++++++++++++++++++++++++++++++++++++++
2 files changed, 58 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..353f95b040 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,64 @@ 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;
+
+ if (virtVlan->nativeTag) {
+ 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 ||
+ virtVlan->nativeMode == VIR_NATIVE_VLAN_MODE_DEFAULT)
+ 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