* [PATCH nf-next,v2 1/3] netfilter: nft_payload: fix C-VLAN offload support
@ 2021-04-12 18:13 Pablo Neira Ayuso
2021-04-12 18:13 ` [PATCH nf-next,v2 2/3] netfilter: nftables_offload: VLAN id needs host byteorder in flow dissector Pablo Neira Ayuso
2021-04-12 18:13 ` [PATCH nf-next,v2 3/3] netfilter: nftables_offload: special ethertype handling for VLAN Pablo Neira Ayuso
0 siblings, 2 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2021-04-12 18:13 UTC (permalink / raw)
To: netfilter-devel; +Cc: wenxu
- add another struct flow_dissector_key_vlan for C-VLAN
- update layer 3 dependency to allow to match on IPv4/IPv6
Fixes: 89d8fd44abfb ("netfilter: nft_payload: add C-VLAN offload support")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
v2: no changes.
include/net/netfilter/nf_tables_offload.h | 1 +
net/netfilter/nft_payload.c | 5 +++--
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/include/net/netfilter/nf_tables_offload.h b/include/net/netfilter/nf_tables_offload.h
index 1d34fe154fe0..b4d080061399 100644
--- a/include/net/netfilter/nf_tables_offload.h
+++ b/include/net/netfilter/nf_tables_offload.h
@@ -45,6 +45,7 @@ struct nft_flow_key {
struct flow_dissector_key_ports tp;
struct flow_dissector_key_ip ip;
struct flow_dissector_key_vlan vlan;
+ struct flow_dissector_key_vlan cvlan;
struct flow_dissector_key_eth_addrs eth_addrs;
struct flow_dissector_key_meta meta;
} __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */
diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c
index cb1c8c231880..a990f37e0a60 100644
--- a/net/netfilter/nft_payload.c
+++ b/net/netfilter/nft_payload.c
@@ -241,7 +241,7 @@ static int nft_payload_offload_ll(struct nft_offload_ctx *ctx,
if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
return -EOPNOTSUPP;
- NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_CVLAN, vlan,
+ NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_CVLAN, cvlan,
vlan_tci, sizeof(__be16), reg);
break;
case offsetof(struct vlan_ethhdr, h_vlan_encapsulated_proto) +
@@ -249,8 +249,9 @@ static int nft_payload_offload_ll(struct nft_offload_ctx *ctx,
if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
return -EOPNOTSUPP;
- NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_CVLAN, vlan,
+ NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_CVLAN, cvlan,
vlan_tpid, sizeof(__be16), reg);
+ nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_NETWORK);
break;
default:
return -EOPNOTSUPP;
--
2.30.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH nf-next,v2 2/3] netfilter: nftables_offload: VLAN id needs host byteorder in flow dissector
2021-04-12 18:13 [PATCH nf-next,v2 1/3] netfilter: nft_payload: fix C-VLAN offload support Pablo Neira Ayuso
@ 2021-04-12 18:13 ` Pablo Neira Ayuso
2021-04-13 10:59 ` kernel test robot
2021-04-12 18:13 ` [PATCH nf-next,v2 3/3] netfilter: nftables_offload: special ethertype handling for VLAN Pablo Neira Ayuso
1 sibling, 1 reply; 4+ messages in thread
From: Pablo Neira Ayuso @ 2021-04-12 18:13 UTC (permalink / raw)
To: netfilter-devel; +Cc: wenxu
The flow dissector representation expects the VLAN id in host byteorder.
Add the NFT_OFFLOAD_F_NETWORK2HOST flag to swap the bytes from nft_cmp.
Fixes: a82055af5959 ("netfilter: nft_payload: add VLAN offload support")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
v2: no changes.
include/net/netfilter/nf_tables_offload.h | 11 +++++-
net/netfilter/nft_cmp.c | 41 +++++++++++++++++++++--
net/netfilter/nft_payload.c | 10 +++---
3 files changed, 55 insertions(+), 7 deletions(-)
diff --git a/include/net/netfilter/nf_tables_offload.h b/include/net/netfilter/nf_tables_offload.h
index b4d080061399..434a6158852f 100644
--- a/include/net/netfilter/nf_tables_offload.h
+++ b/include/net/netfilter/nf_tables_offload.h
@@ -4,11 +4,16 @@
#include <net/flow_offload.h>
#include <net/netfilter/nf_tables.h>
+enum nft_offload_reg_flags {
+ NFT_OFFLOAD_F_NETWORK2HOST = (1 << 0),
+};
+
struct nft_offload_reg {
u32 key;
u32 len;
u32 base_offset;
u32 offset;
+ u32 flags;
struct nft_data data;
struct nft_data mask;
};
@@ -72,13 +77,17 @@ struct nft_flow_rule *nft_flow_rule_create(struct net *net, const struct nft_rul
void nft_flow_rule_destroy(struct nft_flow_rule *flow);
int nft_flow_rule_offload_commit(struct net *net);
-#define NFT_OFFLOAD_MATCH(__key, __base, __field, __len, __reg) \
+#define NFT_OFFLOAD_MATCH_FLAGS(__key, __base, __field, __len, __reg, __flags) \
(__reg)->base_offset = \
offsetof(struct nft_flow_key, __base); \
(__reg)->offset = \
offsetof(struct nft_flow_key, __base.__field); \
(__reg)->len = __len; \
(__reg)->key = __key; \
+ (__reg)->flags = __flags;
+
+#define NFT_OFFLOAD_MATCH(__key, __base, __field, __len, __reg) \
+ NFT_OFFLOAD_MATCH_FLAGS(__key, __base, __field, __len, __reg, 0)
#define NFT_OFFLOAD_MATCH_EXACT(__key, __base, __field, __len, __reg) \
NFT_OFFLOAD_MATCH(__key, __base, __field, __len, __reg) \
diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c
index eb6a43a180bb..47b6d05f1ae6 100644
--- a/net/netfilter/nft_cmp.c
+++ b/net/netfilter/nft_cmp.c
@@ -114,19 +114,56 @@ static int nft_cmp_dump(struct sk_buff *skb, const struct nft_expr *expr)
return -1;
}
+union nft_cmp_offload_data {
+ u16 val16;
+ u32 val32;
+ u64 val64;
+};
+
+static void nft_payload_n2h(union nft_cmp_offload_data *data,
+ const u8 *val, u32 len)
+{
+ switch (len) {
+ case 2:
+ data->val16 = ntohs(*((u16 *)val));
+ break;
+ case 4:
+ data->val32 = ntohl(*((u32 *)val));
+ break;
+ case 8:
+ data->val64 = be64_to_cpu(*((u64 *)val));
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ break;
+ }
+}
+
static int __nft_cmp_offload(struct nft_offload_ctx *ctx,
struct nft_flow_rule *flow,
const struct nft_cmp_expr *priv)
{
struct nft_offload_reg *reg = &ctx->regs[priv->sreg];
+ union nft_cmp_offload_data _data, _datamask;
u8 *mask = (u8 *)&flow->match.mask;
u8 *key = (u8 *)&flow->match.key;
+ u8 *data, *datamask;
if (priv->op != NFT_CMP_EQ || priv->len > reg->len)
return -EOPNOTSUPP;
- memcpy(key + reg->offset, &priv->data, reg->len);
- memcpy(mask + reg->offset, ®->mask, reg->len);
+ if (reg->flags & NFT_OFFLOAD_F_NETWORK2HOST) {
+ nft_payload_n2h(&_data, (u8 *)&priv->data, reg->len);
+ nft_payload_n2h(&_datamask, (u8 *)®->mask, reg->len);
+ data = (u8 *)&_data;
+ datamask = (u8 *)&_datamask;
+ } else {
+ data = (u8 *)&priv->data;
+ datamask = (u8 *)®->mask;
+ }
+
+ memcpy(key + reg->offset, data, reg->len);
+ memcpy(mask + reg->offset, datamask, reg->len);
flow->match.dissector.used_keys |= BIT(reg->key);
flow->match.dissector.offset[reg->key] = reg->base_offset;
diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c
index a990f37e0a60..501c5b24cc39 100644
--- a/net/netfilter/nft_payload.c
+++ b/net/netfilter/nft_payload.c
@@ -226,8 +226,9 @@ static int nft_payload_offload_ll(struct nft_offload_ctx *ctx,
if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
return -EOPNOTSUPP;
- NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_VLAN, vlan,
- vlan_tci, sizeof(__be16), reg);
+ NFT_OFFLOAD_MATCH_FLAGS(FLOW_DISSECTOR_KEY_VLAN, vlan,
+ vlan_tci, sizeof(__be16), reg,
+ NFT_OFFLOAD_F_NETWORK2HOST);
break;
case offsetof(struct vlan_ethhdr, h_vlan_encapsulated_proto):
if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
@@ -241,8 +242,9 @@ static int nft_payload_offload_ll(struct nft_offload_ctx *ctx,
if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16)))
return -EOPNOTSUPP;
- NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_CVLAN, cvlan,
- vlan_tci, sizeof(__be16), reg);
+ NFT_OFFLOAD_MATCH_FLAGS(FLOW_DISSECTOR_KEY_CVLAN, cvlan,
+ vlan_tci, sizeof(__be16), reg,
+ NFT_OFFLOAD_F_NETWORK2HOST);
break;
case offsetof(struct vlan_ethhdr, h_vlan_encapsulated_proto) +
sizeof(struct vlan_hdr):
--
2.30.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH nf-next,v2 3/3] netfilter: nftables_offload: special ethertype handling for VLAN
2021-04-12 18:13 [PATCH nf-next,v2 1/3] netfilter: nft_payload: fix C-VLAN offload support Pablo Neira Ayuso
2021-04-12 18:13 ` [PATCH nf-next,v2 2/3] netfilter: nftables_offload: VLAN id needs host byteorder in flow dissector Pablo Neira Ayuso
@ 2021-04-12 18:13 ` Pablo Neira Ayuso
1 sibling, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2021-04-12 18:13 UTC (permalink / raw)
To: netfilter-devel; +Cc: wenxu
The nftables offload parser sets FLOW_DISSECTOR_KEY_BASIC .n_proto to the
ethertype field in the ethertype frame. However:
- FLOW_DISSECTOR_KEY_BASIC .n_proto field always stores either IPv4 or IPv6
ethertypes.
- FLOW_DISSECTOR_KEY_VLAN .vlan_tpid stores either the 802.1q and 802.1ad
ethertypes. Same as for FLOW_DISSECTOR_KEY_CVLAN.
This function adjusts the flow dissector to handle two scenarios:
1) FLOW_DISSECTOR_KEY_VLAN .vlan_tpid is set to 802.1q or 802.1ad.
Then, transfer:
- the .n_proto field to FLOW_DISSECTOR_KEY_VLAN .tpid.
- the original FLOW_DISSECTOR_KEY_VLAN .tpid to the
FLOW_DISSECTOR_KEY_CVLAN .tpid
- the original FLOW_DISSECTOR_KEY_CVLAN .tpid to the .n_proto field.
2) .n_proto is set to 802.1q or 802.1ad. Then, transfer:
- the .n_proto field to FLOW_DISSECTOR_KEY_VLAN .tpid.
- the original FLOW_DISSECTOR_KEY_VLAN .tpid to the .n_proto field.
Fixes: a82055af5959 ("netfilter: nft_payload: add VLAN offload support")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
v2: simplify vlan scenarios.
net/netfilter/nf_tables_offload.c | 45 +++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c
index 43b56eff3b04..0ae2fbf3d97b 100644
--- a/net/netfilter/nf_tables_offload.c
+++ b/net/netfilter/nf_tables_offload.c
@@ -47,6 +47,49 @@ void nft_flow_rule_set_addr_type(struct nft_flow_rule *flow,
offsetof(struct nft_flow_key, control);
}
+struct nft_offload_ethertype {
+ __be16 value;
+ __be16 mask;
+};
+
+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->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;
+
+ if (match->key.vlan.vlan_tpid == htons(ETH_P_8021Q) ||
+ match->key.vlan.vlan_tpid == htons(ETH_P_8021AD)) {
+ match->key.basic.n_proto = match->key.cvlan.vlan_tpid;
+ match->mask.basic.n_proto = match->mask.cvlan.vlan_tpid;
+ match->key.cvlan.vlan_tpid = match->key.vlan.vlan_tpid;
+ match->mask.cvlan.vlan_tpid = match->mask.vlan.vlan_tpid;
+ match->key.vlan.vlan_tpid = ethertype.value;
+ match->mask.vlan.vlan_tpid = ethertype.mask;
+ match->dissector.offset[FLOW_DISSECTOR_KEY_VLAN] =
+ offsetof(struct nft_flow_key, vlan);
+ match->dissector.offset[FLOW_DISSECTOR_KEY_CVLAN] =
+ offsetof(struct nft_flow_key, cvlan);
+ match->dissector.used_keys |= BIT(FLOW_DISSECTOR_KEY_VLAN) |
+ BIT(FLOW_DISSECTOR_KEY_CVLAN);
+ } else {
+ 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;
+ match->mask.vlan.vlan_tpid = ethertype.mask;
+ match->dissector.offset[FLOW_DISSECTOR_KEY_VLAN] =
+ offsetof(struct nft_flow_key, vlan);
+ match->dissector.used_keys |= BIT(FLOW_DISSECTOR_KEY_VLAN);
+ }
+}
+
struct nft_flow_rule *nft_flow_rule_create(struct net *net,
const struct nft_rule *rule)
{
@@ -91,6 +134,8 @@ struct nft_flow_rule *nft_flow_rule_create(struct net *net,
expr = nft_expr_next(expr);
}
+ nft_flow_rule_transfer_vlan(ctx, flow);
+
flow->proto = ctx->dep.l3num;
kfree(ctx);
--
2.30.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH nf-next,v2 2/3] netfilter: nftables_offload: VLAN id needs host byteorder in flow dissector
2021-04-12 18:13 ` [PATCH nf-next,v2 2/3] netfilter: nftables_offload: VLAN id needs host byteorder in flow dissector Pablo Neira Ayuso
@ 2021-04-13 10:59 ` kernel test robot
0 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2021-04-13 10:59 UTC (permalink / raw)
To: Pablo Neira Ayuso, netfilter-devel; +Cc: kbuild-all, wenxu
[-- Attachment #1: Type: text/plain, Size: 4199 bytes --]
Hi Pablo,
I love your patch! Perhaps something to improve:
[auto build test WARNING on nf/master]
[also build test WARNING on nf-next/master linus/master v5.12-rc7 next-20210412]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Pablo-Neira-Ayuso/netfilter-nft_payload-fix-C-VLAN-offload-support/20210413-021535
base: https://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git master
config: microblaze-randconfig-s031-20210413 (attached as .config)
compiler: microblaze-linux-gcc (GCC) 9.3.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# apt-get install sparse
# sparse version: v0.6.3-280-g2cd6d34e-dirty
# https://github.com/0day-ci/linux/commit/10b8731b5f73d5e52f6f2e247e7f4b33e4d1ddb0
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Pablo-Neira-Ayuso/netfilter-nft_payload-fix-C-VLAN-offload-support/20210413-021535
git checkout 10b8731b5f73d5e52f6f2e247e7f4b33e4d1ddb0
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=microblaze
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
sparse warnings: (new ones prefixed by >>)
>> net/netfilter/nft_cmp.c:128:31: sparse: sparse: cast to restricted __be16
>> net/netfilter/nft_cmp.c:128:31: sparse: sparse: cast to restricted __be16
>> net/netfilter/nft_cmp.c:128:31: sparse: sparse: cast to restricted __be16
>> net/netfilter/nft_cmp.c:128:31: sparse: sparse: cast to restricted __be16
>> net/netfilter/nft_cmp.c:131:31: sparse: sparse: cast to restricted __be32
>> net/netfilter/nft_cmp.c:131:31: sparse: sparse: cast to restricted __be32
>> net/netfilter/nft_cmp.c:131:31: sparse: sparse: cast to restricted __be32
>> net/netfilter/nft_cmp.c:131:31: sparse: sparse: cast to restricted __be32
>> net/netfilter/nft_cmp.c:131:31: sparse: sparse: cast to restricted __be32
>> net/netfilter/nft_cmp.c:131:31: sparse: sparse: cast to restricted __be32
>> net/netfilter/nft_cmp.c:134:31: sparse: sparse: cast to restricted __be64
>> net/netfilter/nft_cmp.c:134:31: sparse: sparse: cast to restricted __be64
>> net/netfilter/nft_cmp.c:134:31: sparse: sparse: cast to restricted __be64
>> net/netfilter/nft_cmp.c:134:31: sparse: sparse: cast to restricted __be64
>> net/netfilter/nft_cmp.c:134:31: sparse: sparse: cast to restricted __be64
>> net/netfilter/nft_cmp.c:134:31: sparse: sparse: cast to restricted __be64
>> net/netfilter/nft_cmp.c:134:31: sparse: sparse: cast to restricted __be64
>> net/netfilter/nft_cmp.c:134:31: sparse: sparse: cast to restricted __be64
>> net/netfilter/nft_cmp.c:134:31: sparse: sparse: cast to restricted __be64
>> net/netfilter/nft_cmp.c:134:31: sparse: sparse: cast to restricted __be64
net/netfilter/nft_cmp.c: note: in included file:
include/net/netfilter/nf_tables_core.h:53:16: sparse: sparse: incorrect type in return expression (different base types) @@ expected unsigned int @@ got restricted __le32 [usertype] @@
include/net/netfilter/nf_tables_core.h:53:16: sparse: expected unsigned int
include/net/netfilter/nf_tables_core.h:53:16: sparse: got restricted __le32 [usertype]
vim +128 net/netfilter/nft_cmp.c
122
123 static void nft_payload_n2h(union nft_cmp_offload_data *data,
124 const u8 *val, u32 len)
125 {
126 switch (len) {
127 case 2:
> 128 data->val16 = ntohs(*((u16 *)val));
129 break;
130 case 4:
> 131 data->val32 = ntohl(*((u32 *)val));
132 break;
133 case 8:
> 134 data->val64 = be64_to_cpu(*((u64 *)val));
135 break;
136 default:
137 WARN_ON_ONCE(1);
138 break;
139 }
140 }
141
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 30069 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-04-13 10:59 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-04-12 18:13 [PATCH nf-next,v2 1/3] netfilter: nft_payload: fix C-VLAN offload support Pablo Neira Ayuso
2021-04-12 18:13 ` [PATCH nf-next,v2 2/3] netfilter: nftables_offload: VLAN id needs host byteorder in flow dissector Pablo Neira Ayuso
2021-04-13 10:59 ` kernel test robot
2021-04-12 18:13 ` [PATCH nf-next,v2 3/3] netfilter: nftables_offload: special ethertype handling for VLAN Pablo Neira Ayuso
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).