aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/pending-5.10/640-18-netfilter-flowtable-handle-bridge-vlan-filter-offloa.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic/pending-5.10/640-18-netfilter-flowtable-handle-bridge-vlan-filter-offloa.patch')
-rw-r--r--target/linux/generic/pending-5.10/640-18-netfilter-flowtable-handle-bridge-vlan-filter-offloa.patch106
1 files changed, 106 insertions, 0 deletions
diff --git a/target/linux/generic/pending-5.10/640-18-netfilter-flowtable-handle-bridge-vlan-filter-offloa.patch b/target/linux/generic/pending-5.10/640-18-netfilter-flowtable-handle-bridge-vlan-filter-offloa.patch
new file mode 100644
index 0000000000..ba480f3520
--- /dev/null
+++ b/target/linux/generic/pending-5.10/640-18-netfilter-flowtable-handle-bridge-vlan-filter-offloa.patch
@@ -0,0 +1,106 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Wed, 10 Feb 2021 19:44:33 +0100
+Subject: [PATCH] netfilter: flowtable: handle bridge vlan filter offload
+ tags from DSA/switchdev
+
+When a switchdev/DSA port is an untagged member of a bridge vlan, ingress
+packets could potentially be tagged with the id of the VLAN.
+When the VLAN port group has been uploaded to switchdev, report the bridge
+tag mode as DEV_PATH_BR_VLAN_UNTAG_HW instead of DEV_PATH_BR_VLAN_UNTAG
+and handle it in netfilter flow offloading by storing the tag in the tuple
+in_pvid field.
+This allows the ingress hook to detect the optional tag and remove it for
+software offload. This tag processing is for ingress only, egress needs to be
+fully untagged
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -853,6 +853,7 @@ struct net_device_path {
+ DEV_PATH_BR_VLAN_KEEP,
+ DEV_PATH_BR_VLAN_TAG,
+ DEV_PATH_BR_VLAN_UNTAG,
++ DEV_PATH_BR_VLAN_UNTAG_HW,
+ } vlan_mode;
+ u16 vlan_id;
+ __be16 vlan_proto;
+--- a/include/net/netfilter/nf_flow_table.h
++++ b/include/net/netfilter/nf_flow_table.h
+@@ -183,6 +183,10 @@ struct nf_flow_route {
+ u32 ifindex;
+ u16 vid[NF_FLOW_TABLE_VLAN_MAX];
+ __be16 vproto[NF_FLOW_TABLE_VLAN_MAX];
++ struct {
++ u16 id;
++ __be16 proto;
++ } pvid;
+ u8 num_vlans;
+ } in;
+ struct {
+--- a/net/bridge/br_device.c
++++ b/net/bridge/br_device.c
+@@ -435,6 +435,7 @@ static int br_fill_forward_path(struct n
+ ctx->vlan[ctx->num_vlans].proto = path->bridge.vlan_proto;
+ ctx->num_vlans++;
+ break;
++ case DEV_PATH_BR_VLAN_UNTAG_HW:
+ case DEV_PATH_BR_VLAN_UNTAG:
+ ctx->num_vlans--;
+ break;
+--- a/net/bridge/br_vlan.c
++++ b/net/bridge/br_vlan.c
+@@ -1374,6 +1374,8 @@ int br_vlan_fill_forward_path_mode(struc
+
+ if (path->bridge.vlan_mode == DEV_PATH_BR_VLAN_TAG)
+ path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP;
++ else if (v->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV)
++ path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG_HW;
+ else
+ path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG;
+
+--- a/net/netfilter/nf_flow_table_core.c
++++ b/net/netfilter/nf_flow_table_core.c
+@@ -98,6 +98,8 @@ static int flow_offload_fill_route(struc
+ j++;
+ }
+ flow_tuple->in_vlan_num = route->tuple[dir].in.num_vlans;
++ flow_tuple->in_pvid.id = route->tuple[dir].in.pvid.id;
++ flow_tuple->in_pvid.proto = route->tuple[dir].in.pvid.proto;
+
+ switch (route->tuple[dir].xmit_type) {
+ case FLOW_OFFLOAD_XMIT_DIRECT:
+--- a/net/netfilter/nft_flow_offload.c
++++ b/net/netfilter/nft_flow_offload.c
+@@ -67,6 +67,10 @@ struct nft_forward_info {
+ const struct net_device *dev;
+ __u16 vid[NF_FLOW_TABLE_VLAN_MAX];
+ __be16 vproto[NF_FLOW_TABLE_VLAN_MAX];
++ struct {
++ __u16 id;
++ __be16 proto;
++ } pvid;
+ u8 num_vlans;
+ u8 h_source[ETH_ALEN];
+ u8 h_dest[ETH_ALEN];
+@@ -127,6 +131,10 @@ static void nft_dev_path_info(const stru
+ info->vproto[info->num_vlans] = path->bridge.vlan_proto;
+ info->num_vlans++;
+ break;
++ case DEV_PATH_BR_VLAN_UNTAG_HW:
++ info->pvid.id = info->vid[info->num_vlans - 1];
++ info->pvid.proto = info->vproto[info->num_vlans - 1];
++ fallthrough;
+ case DEV_PATH_BR_VLAN_UNTAG:
+ info->num_vlans--;
+ break;
+@@ -185,6 +193,8 @@ static void nft_dev_forward_path(struct
+ route->tuple[!dir].in.vid[i] = info.vid[i];
+ route->tuple[!dir].in.vproto[i] = info.vproto[i];
+ }
++ route->tuple[!dir].in.pvid.id = info.pvid.id;
++ route->tuple[!dir].in.pvid.proto = info.pvid.proto;
+ route->tuple[!dir].in.num_vlans = info.num_vlans;
+
+ if (info.xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) {