diff options
author | Felix Fietkau <nbd@nbd.name> | 2021-04-10 13:20:04 +0200 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2021-04-10 16:14:34 +0200 |
commit | f07fe36f22fcf3f3da4e0440dfc5c39516e2cb55 (patch) | |
tree | dae926ce58c604551a2e1ac09834cae4c222ef30 /target/linux/generic/backport-5.10/610-v5.13-14-net-bridge-resolve-forwarding-path-for-VLAN-tag-acti.patch | |
parent | 012a9aa00b3e193c93600ac707dfb5bfb1bd4609 (diff) | |
download | upstream-f07fe36f22fcf3f3da4e0440dfc5c39516e2cb55.tar.gz upstream-f07fe36f22fcf3f3da4e0440dfc5c39516e2cb55.tar.bz2 upstream-f07fe36f22fcf3f3da4e0440dfc5c39516e2cb55.zip |
kernel: update flow offload patches to upstream version
Move patches to backport-5.10, since the series was accepted upstream
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'target/linux/generic/backport-5.10/610-v5.13-14-net-bridge-resolve-forwarding-path-for-VLAN-tag-acti.patch')
-rw-r--r-- | target/linux/generic/backport-5.10/610-v5.13-14-net-bridge-resolve-forwarding-path-for-VLAN-tag-acti.patch | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/target/linux/generic/backport-5.10/610-v5.13-14-net-bridge-resolve-forwarding-path-for-VLAN-tag-acti.patch b/target/linux/generic/backport-5.10/610-v5.13-14-net-bridge-resolve-forwarding-path-for-VLAN-tag-acti.patch new file mode 100644 index 0000000000..2c1d935d9e --- /dev/null +++ b/target/linux/generic/backport-5.10/610-v5.13-14-net-bridge-resolve-forwarding-path-for-VLAN-tag-acti.patch @@ -0,0 +1,207 @@ +From: Felix Fietkau <nbd@nbd.name> +Date: Wed, 24 Mar 2021 02:30:35 +0100 +Subject: [PATCH] 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> +--- + +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -841,10 +841,20 @@ struct net_device_path { + u16 id; + __be16 proto; + } encap; ++ struct { ++ enum { ++ DEV_PATH_BR_VLAN_KEEP, ++ DEV_PATH_BR_VLAN_TAG, ++ DEV_PATH_BR_VLAN_UNTAG, ++ } vlan_mode; ++ u16 vlan_id; ++ __be16 vlan_proto; ++ } bridge; + }; + }; + + #define NET_DEVICE_PATH_STACK_MAX 5 ++#define NET_DEVICE_PATH_VLAN_MAX 2 + + struct net_device_path_stack { + int num_paths; +@@ -854,6 +864,12 @@ struct net_device_path_stack { + struct net_device_path_ctx { + const struct net_device *dev; + const u8 *daddr; ++ ++ int num_vlans; ++ struct { ++ u16 id; ++ __be16 proto; ++ } vlan[NET_DEVICE_PATH_VLAN_MAX]; + }; + + enum tc_setup_type { +--- a/net/8021q/vlan_dev.c ++++ b/net/8021q/vlan_dev.c +@@ -777,6 +777,12 @@ static int vlan_dev_fill_forward_path(st + path->encap.proto = vlan->vlan_proto; + path->dev = ctx->dev; + ctx->dev = vlan->real_dev; ++ if (ctx->num_vlans >= ARRAY_SIZE(ctx->vlan)) ++ return -ENOSPC; ++ ++ ctx->vlan[ctx->num_vlans].id = vlan->vlan_id; ++ ctx->vlan[ctx->num_vlans].proto = vlan->vlan_proto; ++ ctx->num_vlans++; + + return 0; + } +--- a/net/bridge/br_device.c ++++ b/net/bridge/br_device.c +@@ -409,7 +409,10 @@ static int br_fill_forward_path(struct n + 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; + +@@ -417,10 +420,28 @@ static int br_fill_forward_path(struct n + 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; + } + +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -1095,6 +1095,13 @@ void br_vlan_notify(const struct net_bri + bool br_vlan_can_enter_range(const struct net_bridge_vlan *v_curr, + const struct net_bridge_vlan *range_end); + ++void br_vlan_fill_forward_path_pvid(struct net_bridge *br, ++ struct net_device_path_ctx *ctx, ++ struct net_device_path *path); ++int br_vlan_fill_forward_path_mode(struct net_bridge *br, ++ struct net_bridge_port *dst, ++ struct net_device_path *path); ++ + static inline struct net_bridge_vlan_group *br_vlan_group( + const struct net_bridge *br) + { +@@ -1252,6 +1259,19 @@ static inline int nbp_get_num_vlan_infos + { + return 0; + } ++ ++static inline void br_vlan_fill_forward_path_pvid(struct net_bridge *br, ++ struct net_device_path_ctx *ctx, ++ struct net_device_path *path) ++{ ++} ++ ++static inline int br_vlan_fill_forward_path_mode(struct net_bridge *br, ++ struct net_bridge_port *dst, ++ struct net_device_path *path) ++{ ++ return 0; ++} + + static inline struct net_bridge_vlan_group *br_vlan_group( + const struct net_bridge *br) +--- a/net/bridge/br_vlan.c ++++ b/net/bridge/br_vlan.c +@@ -1327,6 +1327,59 @@ int br_vlan_get_pvid_rcu(const struct ne + } + EXPORT_SYMBOL_GPL(br_vlan_get_pvid_rcu); + ++void br_vlan_fill_forward_path_pvid(struct net_bridge *br, ++ struct net_device_path_ctx *ctx, ++ struct net_device_path *path) ++{ ++ struct net_bridge_vlan_group *vg; ++ int idx = ctx->num_vlans - 1; ++ u16 vid; ++ ++ path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP; ++ ++ if (!br_opt_get(br, BROPT_VLAN_ENABLED)) ++ return; ++ ++ vg = br_vlan_group(br); ++ ++ if (idx >= 0 && ++ ctx->vlan[idx].proto == br->vlan_proto) { ++ vid = ctx->vlan[idx].id; ++ } else { ++ path->bridge.vlan_mode = DEV_PATH_BR_VLAN_TAG; ++ vid = br_get_pvid(vg); ++ } ++ ++ path->bridge.vlan_id = vid; ++ path->bridge.vlan_proto = br->vlan_proto; ++} ++ ++int br_vlan_fill_forward_path_mode(struct net_bridge *br, ++ struct net_bridge_port *dst, ++ struct net_device_path *path) ++{ ++ struct net_bridge_vlan_group *vg; ++ struct net_bridge_vlan *v; ++ ++ if (!br_opt_get(br, BROPT_VLAN_ENABLED)) ++ return 0; ++ ++ vg = nbp_vlan_group_rcu(dst); ++ v = br_vlan_find(vg, path->bridge.vlan_id); ++ if (!v || !br_vlan_should_use(v)) ++ return -EINVAL; ++ ++ if (!(v->flags & BRIDGE_VLAN_INFO_UNTAGGED)) ++ return 0; ++ ++ if (path->bridge.vlan_mode == DEV_PATH_BR_VLAN_TAG) ++ path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP; ++ else ++ path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG; ++ ++ return 0; ++} ++ + int br_vlan_get_info(const struct net_device *dev, u16 vid, + struct bridge_vlan_info *p_vinfo) + { |