netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH nf-next 0/3] netfilter: nft_bitwise: shift support
@ 2020-01-14 21:28 Jeremy Sowden
  2020-01-14 21:28 ` [PATCH nf-next 1/3] netfilter: nf_tables: white-space fixes Jeremy Sowden
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Jeremy Sowden @ 2020-01-14 21:28 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: Netfilter Devel

The connmark xtables extension supports bit-shifts.  Add support for
shifts to nft_bitwise in order to allow nftables to do likewise, e.g.:

  nft add rule t c oif lo ct mark set meta mark << 8 | 0xab
  nft add rule t c iif lo meta mark & 0xff 0xab ct mark set meta mark >> 8

There are a couple of preliminary tidying-up patches first.

Jeremy Sowden (3):
  netfilter: nf_tables: white-space fixes.
  netfilter: bitwise: replace gotos with returns.
  netfilter: bitwise: add support for shifts.

 include/uapi/linux/netfilter/nf_tables.h |  9 ++-
 net/netfilter/nft_bitwise.c              | 97 ++++++++++++++++++++----
 net/netfilter/nft_set_bitmap.c           |  4 +-
 net/netfilter/nft_set_hash.c             |  2 +-
 4 files changed, 94 insertions(+), 18 deletions(-)

-- 
2.24.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH nf-next 1/3] netfilter: nf_tables: white-space fixes.
  2020-01-14 21:28 [PATCH nf-next 0/3] netfilter: nft_bitwise: shift support Jeremy Sowden
@ 2020-01-14 21:28 ` Jeremy Sowden
  2020-01-14 21:28 ` [PATCH nf-next 2/3] netfilter: bitwise: replace gotos with returns Jeremy Sowden
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Jeremy Sowden @ 2020-01-14 21:28 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: Netfilter Devel

Indentation fixes for the parameters of a couple of nft set functions.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
 net/netfilter/nft_set_bitmap.c | 4 ++--
 net/netfilter/nft_set_hash.c   | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/netfilter/nft_set_bitmap.c b/net/netfilter/nft_set_bitmap.c
index 087a056e34d1..87e8d9ba0c9b 100644
--- a/net/netfilter/nft_set_bitmap.c
+++ b/net/netfilter/nft_set_bitmap.c
@@ -259,8 +259,8 @@ static u64 nft_bitmap_privsize(const struct nlattr * const nla[],
 }
 
 static int nft_bitmap_init(const struct nft_set *set,
-			 const struct nft_set_desc *desc,
-			 const struct nlattr * const nla[])
+			   const struct nft_set_desc *desc,
+			   const struct nlattr * const nla[])
 {
 	struct nft_bitmap *priv = nft_set_priv(set);
 
diff --git a/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c
index b331a3c9a3a8..d350a7cd3af0 100644
--- a/net/netfilter/nft_set_hash.c
+++ b/net/netfilter/nft_set_hash.c
@@ -645,7 +645,7 @@ static bool nft_hash_estimate(const struct nft_set_desc *desc, u32 features,
 }
 
 static bool nft_hash_fast_estimate(const struct nft_set_desc *desc, u32 features,
-			      struct nft_set_estimate *est)
+				   struct nft_set_estimate *est)
 {
 	if (!desc->size)
 		return false;
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH nf-next 2/3] netfilter: bitwise: replace gotos with returns.
  2020-01-14 21:28 [PATCH nf-next 0/3] netfilter: nft_bitwise: shift support Jeremy Sowden
  2020-01-14 21:28 ` [PATCH nf-next 1/3] netfilter: nf_tables: white-space fixes Jeremy Sowden
@ 2020-01-14 21:28 ` Jeremy Sowden
  2020-01-14 21:29 ` [PATCH nf-next 3/3] netfilter: bitwise: add support for shifts Jeremy Sowden
  2020-01-14 21:30 ` [PATCH nf-next 0/3] netfilter: nft_bitwise: shift support Jeremy Sowden
  3 siblings, 0 replies; 6+ messages in thread
From: Jeremy Sowden @ 2020-01-14 21:28 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: Netfilter Devel

When dumping a bitwise expression, if any of the puts fails, we use goto
to jump to a label.  However, no clean-up is required and the only
statement at the label is a return.  Drop the goto's and return
immediately instead.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
 net/netfilter/nft_bitwise.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index 10e9d50e4e19..d7724250be1f 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -107,24 +107,21 @@ static int nft_bitwise_dump(struct sk_buff *skb, const struct nft_expr *expr)
 	const struct nft_bitwise *priv = nft_expr_priv(expr);
 
 	if (nft_dump_register(skb, NFTA_BITWISE_SREG, priv->sreg))
-		goto nla_put_failure;
+		return -1;
 	if (nft_dump_register(skb, NFTA_BITWISE_DREG, priv->dreg))
-		goto nla_put_failure;
+		return -1;
 	if (nla_put_be32(skb, NFTA_BITWISE_LEN, htonl(priv->len)))
-		goto nla_put_failure;
+		return -1;
 
 	if (nft_data_dump(skb, NFTA_BITWISE_MASK, &priv->mask,
 			  NFT_DATA_VALUE, priv->len) < 0)
-		goto nla_put_failure;
+		return -1;
 
 	if (nft_data_dump(skb, NFTA_BITWISE_XOR, &priv->xor,
 			  NFT_DATA_VALUE, priv->len) < 0)
-		goto nla_put_failure;
+		return -1;
 
 	return 0;
-
-nla_put_failure:
-	return -1;
 }
 
 static struct nft_data zero;
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH nf-next 3/3] netfilter: bitwise: add support for shifts.
  2020-01-14 21:28 [PATCH nf-next 0/3] netfilter: nft_bitwise: shift support Jeremy Sowden
  2020-01-14 21:28 ` [PATCH nf-next 1/3] netfilter: nf_tables: white-space fixes Jeremy Sowden
  2020-01-14 21:28 ` [PATCH nf-next 2/3] netfilter: bitwise: replace gotos with returns Jeremy Sowden
@ 2020-01-14 21:29 ` Jeremy Sowden
  2020-01-14 21:30 ` [PATCH nf-next 0/3] netfilter: nft_bitwise: shift support Jeremy Sowden
  3 siblings, 0 replies; 6+ messages in thread
From: Jeremy Sowden @ 2020-01-14 21:29 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: Netfilter Devel

Currently nft_bitwise only supports boolean operations: NOT, AND, OR and
XOR.  Extend it to do shifts as well.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
 include/uapi/linux/netfilter/nf_tables.h |  9 ++-
 net/netfilter/nft_bitwise.c              | 84 ++++++++++++++++++++++--
 2 files changed, 86 insertions(+), 7 deletions(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index dd4611767933..8f244ada0ad3 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -492,12 +492,15 @@ enum nft_immediate_attributes {
  * @NFTA_BITWISE_LEN: length of operands (NLA_U32)
  * @NFTA_BITWISE_MASK: mask value (NLA_NESTED: nft_data_attributes)
  * @NFTA_BITWISE_XOR: xor value (NLA_NESTED: nft_data_attributes)
+ * @NFTA_BITWISE_LSHIFT: left shift value (NLA_U32)
+ * @NFTA_BITWISE_RSHIFT: right shift value (NLA_U32)
  *
- * The bitwise expression performs the following operation:
+ * The bitwise expression supports boolean and shift operations.  It implements
+ * the boolean operations by performing the following operation:
  *
  * dreg = (sreg & mask) ^ xor
  *
- * which allow to express all bitwise operations:
+ * with these mask and xor values:
  *
  * 		mask	xor
  * NOT:		1	1
@@ -512,6 +515,8 @@ enum nft_bitwise_attributes {
 	NFTA_BITWISE_LEN,
 	NFTA_BITWISE_MASK,
 	NFTA_BITWISE_XOR,
+	NFTA_BITWISE_LSHIFT,
+	NFTA_BITWISE_RSHIFT,
 	__NFTA_BITWISE_MAX
 };
 #define NFTA_BITWISE_MAX	(__NFTA_BITWISE_MAX - 1)
diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index d7724250be1f..e4db77057b0e 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -15,12 +15,20 @@
 #include <net/netfilter/nf_tables.h>
 #include <net/netfilter/nf_tables_offload.h>
 
+enum nft_bitwise_ops {
+	OP_BOOL,
+	OP_LSHIFT,
+	OP_RSHIFT,
+};
+
 struct nft_bitwise {
 	enum nft_registers	sreg:8;
 	enum nft_registers	dreg:8;
+	enum nft_bitwise_ops	op:8;
 	u8			len;
 	struct nft_data		mask;
 	struct nft_data		xor;
+	u8			shift;
 };
 
 void nft_bitwise_eval(const struct nft_expr *expr,
@@ -31,6 +39,26 @@ void nft_bitwise_eval(const struct nft_expr *expr,
 	u32 *dst = &regs->data[priv->dreg];
 	unsigned int i;
 
+	if (priv->op == OP_LSHIFT) {
+		u32 carry = 0;
+
+		for (i = DIV_ROUND_UP(priv->len, sizeof(u32)); i > 0; i--) {
+			dst[i - 1] = (src[i - 1] << priv->shift) | carry;
+			carry = src[i - 1] >> (32 - priv->shift);
+		}
+		return;
+	}
+
+	if (priv->op == OP_RSHIFT) {
+		u32 carry = 0;
+
+		for (i = 0; i < DIV_ROUND_UP(priv->len, sizeof(u32)); i++) {
+			dst[i] = carry | (src[i] >> priv->shift);
+			carry = src[i] << (32 - priv->shift);
+		}
+		return;
+	}
+
 	for (i = 0; i < DIV_ROUND_UP(priv->len, 4); i++)
 		dst[i] = (src[i] & priv->mask.data[i]) ^ priv->xor.data[i];
 }
@@ -41,6 +69,8 @@ static const struct nla_policy nft_bitwise_policy[NFTA_BITWISE_MAX + 1] = {
 	[NFTA_BITWISE_LEN]	= { .type = NLA_U32 },
 	[NFTA_BITWISE_MASK]	= { .type = NLA_NESTED },
 	[NFTA_BITWISE_XOR]	= { .type = NLA_NESTED },
+	[NFTA_BITWISE_LSHIFT]	= { .type = NLA_U32 },
+	[NFTA_BITWISE_RSHIFT]	= { .type = NLA_U32 },
 };
 
 static int nft_bitwise_init(const struct nft_ctx *ctx,
@@ -52,11 +82,9 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
 	u32 len;
 	int err;
 
-	if (tb[NFTA_BITWISE_SREG] == NULL ||
-	    tb[NFTA_BITWISE_DREG] == NULL ||
-	    tb[NFTA_BITWISE_LEN] == NULL ||
-	    tb[NFTA_BITWISE_MASK] == NULL ||
-	    tb[NFTA_BITWISE_XOR] == NULL)
+	if (!tb[NFTA_BITWISE_SREG] ||
+	    !tb[NFTA_BITWISE_DREG] ||
+	    !tb[NFTA_BITWISE_LEN])
 		return -EINVAL;
 
 	err = nft_parse_u32_check(tb[NFTA_BITWISE_LEN], U8_MAX, &len);
@@ -76,6 +104,36 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
 	if (err < 0)
 		return err;
 
+	if (tb[NFTA_BITWISE_LSHIFT]) {
+		u32 shift;
+
+		err = nft_parse_u32_check(tb[NFTA_BITWISE_LSHIFT], U8_MAX,
+					  &shift);
+		if (err < 0)
+			return err;
+
+		priv->shift = shift;
+		priv->op = OP_LSHIFT;
+		return 0;
+	}
+
+	if (tb[NFTA_BITWISE_RSHIFT]) {
+		u32 shift;
+
+		err = nft_parse_u32_check(tb[NFTA_BITWISE_RSHIFT], U8_MAX,
+					  &shift);
+		if (err < 0)
+			return err;
+
+		priv->shift = shift;
+		priv->op = OP_RSHIFT;
+		return 0;
+	}
+
+	if (!tb[NFTA_BITWISE_MASK] ||
+	    !tb[NFTA_BITWISE_XOR])
+		return -EINVAL;
+
 	err = nft_data_init(NULL, &priv->mask, sizeof(priv->mask), &d1,
 			    tb[NFTA_BITWISE_MASK]);
 	if (err < 0)
@@ -94,6 +152,7 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
 		goto err2;
 	}
 
+	priv->op = OP_BOOL;
 	return 0;
 err2:
 	nft_data_release(&priv->xor, d2.type);
@@ -113,6 +172,18 @@ static int nft_bitwise_dump(struct sk_buff *skb, const struct nft_expr *expr)
 	if (nla_put_be32(skb, NFTA_BITWISE_LEN, htonl(priv->len)))
 		return -1;
 
+	if (priv->op == OP_LSHIFT) {
+		if (nla_put_be32(skb, NFTA_BITWISE_LSHIFT, htonl(priv->shift)))
+			return -1;
+		return 0;
+	}
+
+	if (priv->op == OP_RSHIFT) {
+		if (nla_put_be32(skb, NFTA_BITWISE_RSHIFT, htonl(priv->shift)))
+			return -1;
+		return 0;
+	}
+
 	if (nft_data_dump(skb, NFTA_BITWISE_MASK, &priv->mask,
 			  NFT_DATA_VALUE, priv->len) < 0)
 		return -1;
@@ -133,6 +204,9 @@ static int nft_bitwise_offload(struct nft_offload_ctx *ctx,
 	const struct nft_bitwise *priv = nft_expr_priv(expr);
 	struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
 
+	if (priv->op != OP_BOOL)
+		return -EOPNOTSUPP;
+
 	if (memcmp(&priv->xor, &zero, sizeof(priv->xor)) ||
 	    priv->sreg != priv->dreg || priv->len != reg->len)
 		return -EOPNOTSUPP;
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH nf-next 0/3] netfilter: nft_bitwise: shift support
  2020-01-14 21:28 [PATCH nf-next 0/3] netfilter: nft_bitwise: shift support Jeremy Sowden
                   ` (2 preceding siblings ...)
  2020-01-14 21:29 ` [PATCH nf-next 3/3] netfilter: bitwise: add support for shifts Jeremy Sowden
@ 2020-01-14 21:30 ` Jeremy Sowden
  3 siblings, 0 replies; 6+ messages in thread
From: Jeremy Sowden @ 2020-01-14 21:30 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: Netfilter Devel

[-- Attachment #1: Type: text/plain, Size: 905 bytes --]

On 2020-01-14, at 21:28:57 +0000, Jeremy Sowden wrote:
> The connmark xtables extension supports bit-shifts.  Add support for
> shifts to nft_bitwise in order to allow nftables to do likewise, e.g.:
>
>   nft add rule t c oif lo ct mark set meta mark << 8 | 0xab
>   nft add rule t c iif lo meta mark & 0xff 0xab ct mark set meta mark >> 8
>
> There are a couple of preliminary tidying-up patches first.
>
> Jeremy Sowden (3):
>   netfilter: nf_tables: white-space fixes.
>   netfilter: bitwise: replace gotos with returns.
>   netfilter: bitwise: add support for shifts.
>
>  include/uapi/linux/netfilter/nf_tables.h |  9 ++-
>  net/netfilter/nft_bitwise.c              | 97 ++++++++++++++++++++----
>  net/netfilter/nft_set_bitmap.c           |  4 +-
>  net/netfilter/nft_set_hash.c             |  2 +-
>  4 files changed, 94 insertions(+), 18 deletions(-)

Resent these by accident, please ignore.

J.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH nf-next 2/3] netfilter: bitwise: replace gotos with returns.
  2020-01-10 12:33 Jeremy Sowden
@ 2020-01-10 12:33 ` Jeremy Sowden
  0 siblings, 0 replies; 6+ messages in thread
From: Jeremy Sowden @ 2020-01-10 12:33 UTC (permalink / raw)
  To: Netfilter Devel

When dumping a bitwise expression, if any of the puts fails, we use goto
to jump to a label.  However, no clean-up is required and the only
statement at the label is a return.  Drop the goto's and return
immediately instead.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
 net/netfilter/nft_bitwise.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index 10e9d50e4e19..d7724250be1f 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -107,24 +107,21 @@ static int nft_bitwise_dump(struct sk_buff *skb, const struct nft_expr *expr)
 	const struct nft_bitwise *priv = nft_expr_priv(expr);
 
 	if (nft_dump_register(skb, NFTA_BITWISE_SREG, priv->sreg))
-		goto nla_put_failure;
+		return -1;
 	if (nft_dump_register(skb, NFTA_BITWISE_DREG, priv->dreg))
-		goto nla_put_failure;
+		return -1;
 	if (nla_put_be32(skb, NFTA_BITWISE_LEN, htonl(priv->len)))
-		goto nla_put_failure;
+		return -1;
 
 	if (nft_data_dump(skb, NFTA_BITWISE_MASK, &priv->mask,
 			  NFT_DATA_VALUE, priv->len) < 0)
-		goto nla_put_failure;
+		return -1;
 
 	if (nft_data_dump(skb, NFTA_BITWISE_XOR, &priv->xor,
 			  NFT_DATA_VALUE, priv->len) < 0)
-		goto nla_put_failure;
+		return -1;
 
 	return 0;
-
-nla_put_failure:
-	return -1;
 }
 
 static struct nft_data zero;
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2020-01-14 21:30 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-14 21:28 [PATCH nf-next 0/3] netfilter: nft_bitwise: shift support Jeremy Sowden
2020-01-14 21:28 ` [PATCH nf-next 1/3] netfilter: nf_tables: white-space fixes Jeremy Sowden
2020-01-14 21:28 ` [PATCH nf-next 2/3] netfilter: bitwise: replace gotos with returns Jeremy Sowden
2020-01-14 21:29 ` [PATCH nf-next 3/3] netfilter: bitwise: add support for shifts Jeremy Sowden
2020-01-14 21:30 ` [PATCH nf-next 0/3] netfilter: nft_bitwise: shift support Jeremy Sowden
  -- strict thread matches above, loose matches on Subject: below --
2020-01-10 12:33 Jeremy Sowden
2020-01-10 12:33 ` [PATCH nf-next 2/3] netfilter: bitwise: replace gotos with returns Jeremy Sowden

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).