diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2020-11-25 23:50:17 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2020-11-27 12:10:47 +0100 |
commit | a5d45bc0dc50f9dd83703510e9804d813a9cac32 (patch) | |
tree | 5649d545ae81423cd33e5e2264e6271972e53fcf /net/netfilter/nft_cmp.c | |
parent | 3c78e9e0d33a27ab8050e4492c03c6a1f8d0ed6b (diff) | |
download | linux-a5d45bc0dc50f9dd83703510e9804d813a9cac32.tar.gz linux-a5d45bc0dc50f9dd83703510e9804d813a9cac32.tar.bz2 linux-a5d45bc0dc50f9dd83703510e9804d813a9cac32.zip |
netfilter: nftables_offload: build mask based from the matching bytes
Userspace might match on prefix bytes of header fields if they are on
the byte boundary, this requires that the mask is adjusted accordingly.
Use NFT_OFFLOAD_MATCH_EXACT() for meta since prefix byte matching is not
allowed for this type of selector.
The bitwise expression might be optimized out by userspace, hence the
kernel needs to infer the prefix from the number of payload bytes to
match on. This patch adds nft_payload_offload_mask() to calculate the
bitmask to match on the prefix.
Fixes: c9626a2cbdb2 ("netfilter: nf_tables: add hardware offload support")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter/nft_cmp.c')
-rw-r--r-- | net/netfilter/nft_cmp.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c index bc079d68a536..00e563a72d3d 100644 --- a/net/netfilter/nft_cmp.c +++ b/net/netfilter/nft_cmp.c @@ -123,11 +123,11 @@ static int __nft_cmp_offload(struct nft_offload_ctx *ctx, u8 *mask = (u8 *)&flow->match.mask; u8 *key = (u8 *)&flow->match.key; - if (priv->op != NFT_CMP_EQ || reg->len != priv->len) + if (priv->op != NFT_CMP_EQ || priv->len > reg->len) return -EOPNOTSUPP; - memcpy(key + reg->offset, &priv->data, priv->len); - memcpy(mask + reg->offset, ®->mask, priv->len); + memcpy(key + reg->offset, &priv->data, reg->len); + memcpy(mask + reg->offset, ®->mask, reg->len); flow->match.dissector.used_keys |= BIT(reg->key); flow->match.dissector.offset[reg->key] = reg->base_offset; @@ -137,7 +137,7 @@ static int __nft_cmp_offload(struct nft_offload_ctx *ctx, nft_reg_load16(priv->data.data) != ARPHRD_ETHER) return -EOPNOTSUPP; - nft_offload_update_dependency(ctx, &priv->data, priv->len); + nft_offload_update_dependency(ctx, &priv->data, reg->len); return 0; } |