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@xxxxxxxxxxxxx> --- 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