Skip to content

Commit 26267bf

Browse files
nbd168davem330
authored andcommitted
netfilter: flowtable: bridge vlan hardware offload and switchdev
The switch might have already added the VLAN tag through PVID hardware offload. Keep this extra VLAN in the flowtable but skip it on egress. Signed-off-by: Felix Fietkau <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 73f9702 commit 26267bf

File tree

7 files changed

+21
-4
lines changed

7 files changed

+21
-4
lines changed

include/linux/netdevice.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,7 @@ struct net_device_path {
870870
DEV_PATH_BR_VLAN_KEEP,
871871
DEV_PATH_BR_VLAN_TAG,
872872
DEV_PATH_BR_VLAN_UNTAG,
873+
DEV_PATH_BR_VLAN_UNTAG_HW,
873874
} vlan_mode;
874875
u16 vlan_id;
875876
__be16 vlan_proto;

include/net/netfilter/nf_flow_table.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,10 @@ struct flow_offload_tuple {
123123
/* All members above are keys for lookups, see flow_offload_hash(). */
124124
struct { } __hash;
125125

126-
u8 dir:4,
126+
u8 dir:2,
127127
xmit_type:2,
128-
encap_num:2;
128+
encap_num:2,
129+
in_vlan_ingress:2;
129130
u16 mtu;
130131
union {
131132
struct dst_entry *dst_cache;
@@ -185,7 +186,8 @@ struct nf_flow_route {
185186
u16 id;
186187
__be16 proto;
187188
} encap[NF_FLOW_TABLE_ENCAP_MAX];
188-
u8 num_encaps;
189+
u8 num_encaps:2,
190+
ingress_vlans:2;
189191
} in;
190192
struct {
191193
u32 ifindex;

net/bridge/br_device.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ static int br_fill_forward_path(struct net_device_path_ctx *ctx,
422422
ctx->vlan[ctx->num_vlans].proto = path->bridge.vlan_proto;
423423
ctx->num_vlans++;
424424
break;
425+
case DEV_PATH_BR_VLAN_UNTAG_HW:
425426
case DEV_PATH_BR_VLAN_UNTAG:
426427
ctx->num_vlans--;
427428
break;

net/bridge/br_vlan.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,6 +1386,8 @@ int br_vlan_fill_forward_path_mode(struct net_bridge *br,
13861386

13871387
if (path->bridge.vlan_mode == DEV_PATH_BR_VLAN_TAG)
13881388
path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP;
1389+
else if (v->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV)
1390+
path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG_HW;
13891391
else
13901392
path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG;
13911393

net/netfilter/nf_flow_table_core.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ static int flow_offload_fill_route(struct flow_offload *flow,
9595
for (i = route->tuple[dir].in.num_encaps - 1; i >= 0; i--) {
9696
flow_tuple->encap[j].id = route->tuple[dir].in.encap[i].id;
9797
flow_tuple->encap[j].proto = route->tuple[dir].in.encap[i].proto;
98+
if (route->tuple[dir].in.ingress_vlans & BIT(i))
99+
flow_tuple->in_vlan_ingress |= BIT(j);
98100
j++;
99101
}
100102
flow_tuple->encap_num = route->tuple[dir].in.num_encaps;

net/netfilter/nf_flow_table_offload.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,8 +594,12 @@ nf_flow_rule_route_common(struct net *net, const struct flow_offload *flow,
594594
other_tuple = &flow->tuplehash[!dir].tuple;
595595

596596
for (i = 0; i < other_tuple->encap_num; i++) {
597-
struct flow_action_entry *entry = flow_action_entry_next(flow_rule);
597+
struct flow_action_entry *entry;
598598

599+
if (other_tuple->in_vlan_ingress & BIT(i))
600+
continue;
601+
602+
entry = flow_action_entry_next(flow_rule);
599603
entry->id = FLOW_ACTION_VLAN_PUSH;
600604
entry->vlan.vid = other_tuple->encap[i].id;
601605
entry->vlan.proto = other_tuple->encap[i].proto;

net/netfilter/nft_flow_offload.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ struct nft_forward_info {
7272
__be16 proto;
7373
} encap[NF_FLOW_TABLE_ENCAP_MAX];
7474
u8 num_encaps;
75+
u8 ingress_vlans;
7576
u8 h_source[ETH_ALEN];
7677
u8 h_dest[ETH_ALEN];
7778
enum flow_offload_xmit_type xmit_type;
@@ -130,6 +131,9 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack,
130131
memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
131132

132133
switch (path->bridge.vlan_mode) {
134+
case DEV_PATH_BR_VLAN_UNTAG_HW:
135+
info->ingress_vlans |= BIT(info->num_encaps - 1);
136+
break;
133137
case DEV_PATH_BR_VLAN_TAG:
134138
info->encap[info->num_encaps].id = path->bridge.vlan_id;
135139
info->encap[info->num_encaps].proto = path->bridge.vlan_proto;
@@ -198,6 +202,7 @@ static void nft_dev_forward_path(struct nf_flow_route *route,
198202
route->tuple[!dir].in.encap[i].proto = info.encap[i].proto;
199203
}
200204
route->tuple[!dir].in.num_encaps = info.num_encaps;
205+
route->tuple[!dir].in.ingress_vlans = info.ingress_vlans;
201206

202207
if (info.xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) {
203208
memcpy(route->tuple[dir].out.h_source, info.h_source, ETH_ALEN);

0 commit comments

Comments
 (0)