From bcf2766b1377421b7c9259865b25c1b62a7fa686 Mon Sep 17 00:00:00 2001 From: Felix Fietkau <nbd@nbd.name> Date: Wed, 24 Mar 2021 02:30:35 +0100 Subject: net: bridge: resolve forwarding path for VLAN tag actions in bridge devices Depending on the VLAN settings of the bridge and the port, the bridge can either add or remove a tag. When vlan filtering is enabled, the fdb lookup also needs to know the VLAN tag/proto for the destination address To provide this, keep track of the stack of VLAN tags for the path in the lookup context Signed-off-by: Felix Fietkau <nbd@nbd.name> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: David S. Miller <davem@davemloft.net> --- net/bridge/br_device.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'net/bridge/br_device.c') diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index c241719013f4..0c72503e0d39 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -396,7 +396,10 @@ static int br_fill_forward_path(struct net_device_path_ctx *ctx, return -1; br = netdev_priv(ctx->dev); - f = br_fdb_find_rcu(br, ctx->daddr, 0); + + br_vlan_fill_forward_path_pvid(br, ctx, path); + + f = br_fdb_find_rcu(br, ctx->daddr, path->bridge.vlan_id); if (!f || !f->dst) return -1; @@ -404,10 +407,28 @@ static int br_fill_forward_path(struct net_device_path_ctx *ctx, if (!dst) return -1; + if (br_vlan_fill_forward_path_mode(br, dst, path)) + return -1; + path->type = DEV_PATH_BRIDGE; path->dev = dst->br->dev; ctx->dev = dst->dev; + switch (path->bridge.vlan_mode) { + case DEV_PATH_BR_VLAN_TAG: + if (ctx->num_vlans >= ARRAY_SIZE(ctx->vlan)) + return -ENOSPC; + ctx->vlan[ctx->num_vlans].id = path->bridge.vlan_id; + ctx->vlan[ctx->num_vlans].proto = path->bridge.vlan_proto; + ctx->num_vlans++; + break; + case DEV_PATH_BR_VLAN_UNTAG: + ctx->num_vlans--; + break; + case DEV_PATH_BR_VLAN_KEEP: + break; + } + return 0; } -- cgit