| From 39512e3a378a5ce7d076e566076226076267e69b Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Sat, 19 Jun 2021 01:25:14 +0200 |
| Subject: netfilter: nf_tables_offload: check FLOW_DISSECTOR_KEY_BASIC in VLAN |
| transfer logic |
| |
| From: Pablo Neira Ayuso <pablo@netfilter.org> |
| |
| [ Upstream commit ea45fdf82cc90430bb7c280e5e53821e833782c5 ] |
| |
| The VLAN transfer logic should actually check for |
| FLOW_DISSECTOR_KEY_BASIC, not FLOW_DISSECTOR_KEY_CONTROL. Moreover, do |
| not fallback to case 2) .n_proto is set to 802.1q or 802.1ad, if |
| FLOW_DISSECTOR_KEY_BASIC is unset. |
| |
| Fixes: 783003f3bb8a ("netfilter: nftables_offload: special ethertype handling for VLAN") |
| Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| net/netfilter/nf_tables_offload.c | 17 +++++++---------- |
| 1 file changed, 7 insertions(+), 10 deletions(-) |
| |
| diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c |
| index 2b00f7f47693..9ce776175214 100644 |
| --- a/net/netfilter/nf_tables_offload.c |
| +++ b/net/netfilter/nf_tables_offload.c |
| @@ -54,15 +54,10 @@ static void nft_flow_rule_transfer_vlan(struct nft_offload_ctx *ctx, |
| struct nft_flow_rule *flow) |
| { |
| struct nft_flow_match *match = &flow->match; |
| - struct nft_offload_ethertype ethertype; |
| - |
| - if (match->dissector.used_keys & BIT(FLOW_DISSECTOR_KEY_CONTROL) && |
| - match->key.basic.n_proto != htons(ETH_P_8021Q) && |
| - match->key.basic.n_proto != htons(ETH_P_8021AD)) |
| - return; |
| - |
| - ethertype.value = match->key.basic.n_proto; |
| - ethertype.mask = match->mask.basic.n_proto; |
| + struct nft_offload_ethertype ethertype = { |
| + .value = match->key.basic.n_proto, |
| + .mask = match->mask.basic.n_proto, |
| + }; |
| |
| if (match->dissector.used_keys & BIT(FLOW_DISSECTOR_KEY_VLAN) && |
| (match->key.vlan.vlan_tpid == htons(ETH_P_8021Q) || |
| @@ -76,7 +71,9 @@ static void nft_flow_rule_transfer_vlan(struct nft_offload_ctx *ctx, |
| match->dissector.offset[FLOW_DISSECTOR_KEY_CVLAN] = |
| offsetof(struct nft_flow_key, cvlan); |
| match->dissector.used_keys |= BIT(FLOW_DISSECTOR_KEY_CVLAN); |
| - } else { |
| + } else if (match->dissector.used_keys & BIT(FLOW_DISSECTOR_KEY_BASIC) && |
| + (match->key.basic.n_proto == htons(ETH_P_8021Q) || |
| + match->key.basic.n_proto == htons(ETH_P_8021AD))) { |
| match->key.basic.n_proto = match->key.vlan.vlan_tpid; |
| match->mask.basic.n_proto = match->mask.vlan.vlan_tpid; |
| match->key.vlan.vlan_tpid = ethertype.value; |
| -- |
| 2.30.2 |
| |