* [PATCH nf-next 0/2] netfilter: bitwise: support variable RHS operands
@ 2020-02-24 12:49 Jeremy Sowden
2020-02-24 12:49 ` [PATCH nf-next 1/2] netfilter: bitwise: use more descriptive variable-names Jeremy Sowden
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Jeremy Sowden @ 2020-02-24 12:49 UTC (permalink / raw)
To: Pablo Neira Ayuso, Florian Westphal; +Cc: Netfilter Devel
Currently bitwise boolean operations can only have one variable operand
because the mask and xor values have to be passed as immediate data.
Support operations with two variable operands by allowing the mask and
xor to be passed in registers.
There is a preliminary patch that renames a couple of variables.
Jeremy Sowden (2):
netfilter: bitwise: use more descriptive variable-names.
netfilter: bitwise: add support for passing mask and xor values in
registers.
include/uapi/linux/netfilter/nf_tables.h | 4 +
net/netfilter/nft_bitwise.c | 120 +++++++++++++++++------
2 files changed, 94 insertions(+), 30 deletions(-)
--
2.25.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH nf-next 1/2] netfilter: bitwise: use more descriptive variable-names.
2020-02-24 12:49 [PATCH nf-next 0/2] netfilter: bitwise: support variable RHS operands Jeremy Sowden
@ 2020-02-24 12:49 ` Jeremy Sowden
2020-02-24 12:49 ` [PATCH nf-next 2/2] netfilter: bitwise: add support for passing mask and xor values in registers Jeremy Sowden
2020-03-02 12:23 ` [PATCH nf-next 0/2] netfilter: bitwise: support variable RHS operands Pablo Neira Ayuso
2 siblings, 0 replies; 4+ messages in thread
From: Jeremy Sowden @ 2020-02-24 12:49 UTC (permalink / raw)
To: Pablo Neira Ayuso, Florian Westphal; +Cc: Netfilter Devel
Name the mask and xor data variables, "mask" and "xor," instead of "d1"
and "d2."
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
net/netfilter/nft_bitwise.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index 0ed2281f03be..bc37d6c59db4 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -93,7 +93,7 @@ static const struct nla_policy nft_bitwise_policy[NFTA_BITWISE_MAX + 1] = {
static int nft_bitwise_init_bool(struct nft_bitwise *priv,
const struct nlattr *const tb[])
{
- struct nft_data_desc d1, d2;
+ struct nft_data_desc mask, xor;
int err;
if (tb[NFTA_BITWISE_DATA])
@@ -103,29 +103,29 @@ static int nft_bitwise_init_bool(struct nft_bitwise *priv,
!tb[NFTA_BITWISE_XOR])
return -EINVAL;
- err = nft_data_init(NULL, &priv->mask, sizeof(priv->mask), &d1,
+ err = nft_data_init(NULL, &priv->mask, sizeof(priv->mask), &mask,
tb[NFTA_BITWISE_MASK]);
if (err < 0)
return err;
- if (d1.type != NFT_DATA_VALUE || d1.len != priv->len) {
+ if (mask.type != NFT_DATA_VALUE || mask.len != priv->len) {
err = -EINVAL;
goto err1;
}
- err = nft_data_init(NULL, &priv->xor, sizeof(priv->xor), &d2,
+ err = nft_data_init(NULL, &priv->xor, sizeof(priv->xor), &xor,
tb[NFTA_BITWISE_XOR]);
if (err < 0)
goto err1;
- if (d2.type != NFT_DATA_VALUE || d2.len != priv->len) {
+ if (xor.type != NFT_DATA_VALUE || xor.len != priv->len) {
err = -EINVAL;
goto err2;
}
return 0;
err2:
- nft_data_release(&priv->xor, d2.type);
+ nft_data_release(&priv->xor, xor.type);
err1:
- nft_data_release(&priv->mask, d1.type);
+ nft_data_release(&priv->mask, mask.type);
return err;
}
--
2.25.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH nf-next 2/2] netfilter: bitwise: add support for passing mask and xor values in registers.
2020-02-24 12:49 [PATCH nf-next 0/2] netfilter: bitwise: support variable RHS operands Jeremy Sowden
2020-02-24 12:49 ` [PATCH nf-next 1/2] netfilter: bitwise: use more descriptive variable-names Jeremy Sowden
@ 2020-02-24 12:49 ` Jeremy Sowden
2020-03-02 12:23 ` [PATCH nf-next 0/2] netfilter: bitwise: support variable RHS operands Pablo Neira Ayuso
2 siblings, 0 replies; 4+ messages in thread
From: Jeremy Sowden @ 2020-02-24 12:49 UTC (permalink / raw)
To: Pablo Neira Ayuso, Florian Westphal; +Cc: Netfilter Devel
Currently bitwise boolean operations can only have one variable operand
because the mask and xor values have to be passed as immediate data.
Support operations with two variable operands by allowing the mask and
xor to be passed in registers.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
include/uapi/linux/netfilter/nf_tables.h | 4 +
net/netfilter/nft_bitwise.c | 118 +++++++++++++++++------
2 files changed, 93 insertions(+), 29 deletions(-)
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 9c3d2d04d6a1..bd48b5358890 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -526,6 +526,8 @@ enum nft_bitwise_ops {
* @NFTA_BITWISE_OP: type of operation (NLA_U32: nft_bitwise_ops)
* @NFTA_BITWISE_DATA: argument for non-boolean operations
* (NLA_NESTED: nft_data_attributes)
+ * @NFTA_BITWISE_MREG: mask register (NLA_U32: nft_registers)
+ * @NFTA_BITWISE_XREG: xor register (NLA_U32: nft_registers)
*
* The bitwise expression supports boolean and shift operations. It implements
* the boolean operations by performing the following operation:
@@ -549,6 +551,8 @@ enum nft_bitwise_attributes {
NFTA_BITWISE_XOR,
NFTA_BITWISE_OP,
NFTA_BITWISE_DATA,
+ NFTA_BITWISE_MREG,
+ NFTA_BITWISE_XREG,
__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 bc37d6c59db4..8877b50fed78 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -15,23 +15,47 @@
#include <net/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables_offload.h>
+enum nft_bitwise_flags {
+ NFT_BITWISE_MASK_REG = 1,
+ NFT_BITWISE_XOR_REG,
+};
+
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;
+ enum nft_bitwise_flags flags;
struct nft_data data;
+ union {
+ struct nft_data data;
+ enum nft_registers reg:8;
+ } mask;
+ union {
+ struct nft_data data;
+ enum nft_registers reg:8;
+ } xor;
};
static void nft_bitwise_eval_bool(u32 *dst, const u32 *src,
- const struct nft_bitwise *priv)
+ const struct nft_bitwise *priv,
+ struct nft_regs *regs)
{
+ const u32 *mask, *xor;
unsigned int i;
+ if (priv->flags & NFT_BITWISE_MASK_REG)
+ mask = ®s->data[priv->mask.reg];
+ else
+ mask = priv->mask.data.data;
+
+ if (priv->flags & NFT_BITWISE_XOR_REG)
+ xor = ®s->data[priv->xor.reg];
+ else
+ xor = priv->xor.data.data;
+
for (i = 0; i < DIV_ROUND_UP(priv->len, 4); i++)
- dst[i] = (src[i] & priv->mask.data[i]) ^ priv->xor.data[i];
+ dst[i] = (src[i] & mask[i]) ^ xor[i];
}
static void nft_bitwise_eval_lshift(u32 *dst, const u32 *src,
@@ -69,7 +93,7 @@ void nft_bitwise_eval(const struct nft_expr *expr,
switch (priv->op) {
case NFT_BITWISE_BOOL:
- nft_bitwise_eval_bool(dst, src, priv);
+ nft_bitwise_eval_bool(dst, src, priv, regs);
break;
case NFT_BITWISE_LSHIFT:
nft_bitwise_eval_lshift(dst, src, priv);
@@ -88,6 +112,8 @@ static const struct nla_policy nft_bitwise_policy[NFTA_BITWISE_MAX + 1] = {
[NFTA_BITWISE_XOR] = { .type = NLA_NESTED },
[NFTA_BITWISE_OP] = { .type = NLA_U32 },
[NFTA_BITWISE_DATA] = { .type = NLA_NESTED },
+ [NFTA_BITWISE_MREG] = { .type = NLA_U32 },
+ [NFTA_BITWISE_XREG] = { .type = NLA_U32 },
};
static int nft_bitwise_init_bool(struct nft_bitwise *priv,
@@ -99,33 +125,57 @@ static int nft_bitwise_init_bool(struct nft_bitwise *priv,
if (tb[NFTA_BITWISE_DATA])
return -EINVAL;
- if (!tb[NFTA_BITWISE_MASK] ||
- !tb[NFTA_BITWISE_XOR])
+ if ((!tb[NFTA_BITWISE_MASK] && !tb[NFTA_BITWISE_MREG]) ||
+ (tb[NFTA_BITWISE_MASK] && tb[NFTA_BITWISE_MREG]))
return -EINVAL;
- err = nft_data_init(NULL, &priv->mask, sizeof(priv->mask), &mask,
- tb[NFTA_BITWISE_MASK]);
- if (err < 0)
- return err;
- if (mask.type != NFT_DATA_VALUE || mask.len != priv->len) {
- err = -EINVAL;
- goto err1;
+ if ((!tb[NFTA_BITWISE_XOR] && !tb[NFTA_BITWISE_XREG]) ||
+ (tb[NFTA_BITWISE_XOR] && tb[NFTA_BITWISE_XREG]))
+ return -EINVAL;
+
+ if (tb[NFTA_BITWISE_MASK]) {
+ err = nft_data_init(NULL, &priv->mask.data,
+ sizeof(priv->mask.data), &mask,
+ tb[NFTA_BITWISE_MASK]);
+ if (err < 0)
+ return err;
+ if (mask.type != NFT_DATA_VALUE || mask.len != priv->len) {
+ err = -EINVAL;
+ goto err1;
+ }
+ } else {
+ priv->mask.reg = nft_parse_register(tb[NFTA_BITWISE_MREG]);
+ err = nft_validate_register_load(priv->mask.reg, priv->len);
+ if (err < 0)
+ return err;
+ priv->flags |= NFT_BITWISE_MASK_REG;
}
- err = nft_data_init(NULL, &priv->xor, sizeof(priv->xor), &xor,
- tb[NFTA_BITWISE_XOR]);
- if (err < 0)
- goto err1;
- if (xor.type != NFT_DATA_VALUE || xor.len != priv->len) {
- err = -EINVAL;
- goto err2;
+ if (tb[NFTA_BITWISE_XOR]) {
+ err = nft_data_init(NULL, &priv->xor.data,
+ sizeof(priv->xor.data), &xor,
+ tb[NFTA_BITWISE_XOR]);
+ if (err < 0)
+ goto err1;
+ if (xor.type != NFT_DATA_VALUE || xor.len != priv->len) {
+ err = -EINVAL;
+ goto err2;
+ }
+ } else {
+ priv->xor.reg = nft_parse_register(tb[NFTA_BITWISE_XREG]);
+ err = nft_validate_register_load(priv->xor.reg, priv->len);
+ if (err < 0)
+ return err;
+ priv->flags |= NFT_BITWISE_XOR_REG;
}
return 0;
err2:
- nft_data_release(&priv->xor, xor.type);
+ if (tb[NFTA_BITWISE_XOR])
+ nft_data_release(&priv->xor.data, xor.type);
err1:
- nft_data_release(&priv->mask, mask.type);
+ if (tb[NFTA_BITWISE_MASK])
+ nft_data_release(&priv->mask.data, mask.type);
return err;
}
@@ -215,13 +265,23 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
static int nft_bitwise_dump_bool(struct sk_buff *skb,
const struct nft_bitwise *priv)
{
- if (nft_data_dump(skb, NFTA_BITWISE_MASK, &priv->mask,
- NFT_DATA_VALUE, priv->len) < 0)
- return -1;
+ if (priv->flags & NFT_BITWISE_MASK_REG) {
+ if (nft_dump_register(skb, NFTA_BITWISE_MREG, priv->mask.reg))
+ return -1;
+ } else {
+ if (nft_data_dump(skb, NFTA_BITWISE_MASK, &priv->mask.data,
+ NFT_DATA_VALUE, priv->len) < 0)
+ return -1;
+ }
- if (nft_data_dump(skb, NFTA_BITWISE_XOR, &priv->xor,
- NFT_DATA_VALUE, priv->len) < 0)
- return -1;
+ if (priv->flags & NFT_BITWISE_XOR_REG) {
+ if (nft_dump_register(skb, NFTA_BITWISE_XREG, priv->xor.reg))
+ return -1;
+ } else {
+ if (nft_data_dump(skb, NFTA_BITWISE_XOR, &priv->xor.data,
+ NFT_DATA_VALUE, priv->len) < 0)
+ return -1;
+ }
return 0;
}
--
2.25.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH nf-next 0/2] netfilter: bitwise: support variable RHS operands
2020-02-24 12:49 [PATCH nf-next 0/2] netfilter: bitwise: support variable RHS operands Jeremy Sowden
2020-02-24 12:49 ` [PATCH nf-next 1/2] netfilter: bitwise: use more descriptive variable-names Jeremy Sowden
2020-02-24 12:49 ` [PATCH nf-next 2/2] netfilter: bitwise: add support for passing mask and xor values in registers Jeremy Sowden
@ 2020-03-02 12:23 ` Pablo Neira Ayuso
2 siblings, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2020-03-02 12:23 UTC (permalink / raw)
To: Jeremy Sowden; +Cc: Florian Westphal, Netfilter Devel
On Mon, Feb 24, 2020 at 12:49:29PM +0000, Jeremy Sowden wrote:
> Currently bitwise boolean operations can only have one variable operand
> because the mask and xor values have to be passed as immediate data.
> Support operations with two variable operands by allowing the mask and
> xor to be passed in registers.
Series applied, thanks.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2020-03-02 12:23 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-24 12:49 [PATCH nf-next 0/2] netfilter: bitwise: support variable RHS operands Jeremy Sowden
2020-02-24 12:49 ` [PATCH nf-next 1/2] netfilter: bitwise: use more descriptive variable-names Jeremy Sowden
2020-02-24 12:49 ` [PATCH nf-next 2/2] netfilter: bitwise: add support for passing mask and xor values in registers Jeremy Sowden
2020-03-02 12:23 ` [PATCH nf-next 0/2] netfilter: bitwise: support variable RHS operands Pablo Neira Ayuso
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.