uboot-envtools: oxnas: drop redundant space after case keywords
[openwrt/staging/wigyori.git] / target / linux / generic / pending-5.10 / 640-18-netfilter-nf_flow_table-fix-untagging-with-hardware-.patch
1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Mon, 8 Mar 2021 12:06:44 +0100
3 Subject: [PATCH] netfilter: nf_flow_table: fix untagging with
4 hardware-offloaded bridge vlan_filtering
5
6 When switchdev offloading is enabled, treat an untagged VLAN as tagged for
7 ingress only
8
9 Signed-off-by: Felix Fietkau <nbd@nbd.name>
10 ---
11
12 --- a/include/linux/netdevice.h
13 +++ b/include/linux/netdevice.h
14 @@ -849,6 +849,7 @@ struct net_device_path {
15 DEV_PATH_BR_VLAN_KEEP,
16 DEV_PATH_BR_VLAN_TAG,
17 DEV_PATH_BR_VLAN_UNTAG,
18 + DEV_PATH_BR_VLAN_UNTAG_HW,
19 } vlan_mode;
20 u16 vlan_id;
21 __be16 vlan_proto;
22 --- a/include/net/netfilter/nf_flow_table.h
23 +++ b/include/net/netfilter/nf_flow_table.h
24 @@ -123,9 +123,10 @@ struct flow_offload_tuple {
25 /* All members above are keys for lookups, see flow_offload_hash(). */
26 struct { } __hash;
27
28 - u8 dir:4,
29 + u8 dir:2,
30 xmit_type:2,
31 - encap_num:2;
32 + encap_num:2,
33 + in_vlan_ingress:2;
34 u16 mtu;
35 union {
36 struct dst_entry *dst_cache;
37 @@ -185,7 +186,8 @@ struct nf_flow_route {
38 u16 id;
39 __be16 proto;
40 } encap[NF_FLOW_TABLE_ENCAP_MAX];
41 - u8 num_encaps;
42 + u8 num_encaps:2,
43 + ingress_vlans:2;
44 } in;
45 struct {
46 u32 ifindex;
47 --- a/net/bridge/br_device.c
48 +++ b/net/bridge/br_device.c
49 @@ -435,6 +435,7 @@ static int br_fill_forward_path(struct n
50 ctx->vlan[ctx->num_vlans].proto = path->bridge.vlan_proto;
51 ctx->num_vlans++;
52 break;
53 + case DEV_PATH_BR_VLAN_UNTAG_HW:
54 case DEV_PATH_BR_VLAN_UNTAG:
55 ctx->num_vlans--;
56 break;
57 --- a/net/bridge/br_vlan.c
58 +++ b/net/bridge/br_vlan.c
59 @@ -1374,6 +1374,8 @@ int br_vlan_fill_forward_path_mode(struc
60
61 if (path->bridge.vlan_mode == DEV_PATH_BR_VLAN_TAG)
62 path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP;
63 + else if (v->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV)
64 + path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG_HW;
65 else
66 path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG;
67
68 --- a/net/netfilter/nf_flow_table_core.c
69 +++ b/net/netfilter/nf_flow_table_core.c
70 @@ -95,6 +95,8 @@ static int flow_offload_fill_route(struc
71 for (i = route->tuple[dir].in.num_encaps - 1; i >= 0; i--) {
72 flow_tuple->encap[j].id = route->tuple[dir].in.encap[i].id;
73 flow_tuple->encap[j].proto = route->tuple[dir].in.encap[i].proto;
74 + if (route->tuple[dir].in.ingress_vlans & BIT(i))
75 + flow_tuple->in_vlan_ingress |= BIT(j);
76 j++;
77 }
78 flow_tuple->encap_num = route->tuple[dir].in.num_encaps;
79 --- a/net/netfilter/nf_flow_table_offload.c
80 +++ b/net/netfilter/nf_flow_table_offload.c
81 @@ -592,8 +592,12 @@ nf_flow_rule_route_common(struct net *ne
82 other_tuple = &flow->tuplehash[!dir].tuple;
83
84 for (i = 0; i < other_tuple->encap_num; i++) {
85 - struct flow_action_entry *entry = flow_action_entry_next(flow_rule);
86 + struct flow_action_entry *entry;
87
88 + if (other_tuple->in_vlan_ingress & BIT(i))
89 + continue;
90 +
91 + entry = flow_action_entry_next(flow_rule);
92 entry->id = FLOW_ACTION_VLAN_PUSH;
93 entry->vlan.vid = other_tuple->encap[i].id;
94 entry->vlan.proto = other_tuple->encap[i].proto;
95 --- a/net/netfilter/nft_flow_offload.c
96 +++ b/net/netfilter/nft_flow_offload.c
97 @@ -72,6 +72,7 @@ struct nft_forward_info {
98 __be16 proto;
99 } encap[NF_FLOW_TABLE_ENCAP_MAX];
100 u8 num_encaps;
101 + u8 ingress_vlans;
102 u8 h_source[ETH_ALEN];
103 u8 h_dest[ETH_ALEN];
104 enum flow_offload_xmit_type xmit_type;
105 @@ -130,6 +131,9 @@ static void nft_dev_path_info(const stru
106 memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
107
108 switch (path->bridge.vlan_mode) {
109 + case DEV_PATH_BR_VLAN_UNTAG_HW:
110 + info->ingress_vlans |= BIT(info->num_encaps - 1);
111 + break;
112 case DEV_PATH_BR_VLAN_TAG:
113 info->encap[info->num_encaps].id = path->bridge.vlan_id;
114 info->encap[info->num_encaps].proto = path->bridge.vlan_proto;
115 @@ -198,6 +202,7 @@ static void nft_dev_forward_path(struct
116 route->tuple[!dir].in.encap[i].proto = info.encap[i].proto;
117 }
118 route->tuple[!dir].in.num_encaps = info.num_encaps;
119 + route->tuple[!dir].in.ingress_vlans = info.ingress_vlans;
120
121 if (info.xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) {
122 memcpy(route->tuple[dir].out.h_source, info.h_source, ETH_ALEN);