diff mbox series

[libnftnl,v2,3/9] expr: bitwise: pass bit-length to and from the kernel

Message ID 20220404120623.188439-4-jeremy@azazel.net
State Changes Requested
Delegated to: Pablo Neira
Headers show
Series bitwise: support for boolean operations with variable RHS operands | expand

Commit Message

Jeremy Sowden April 4, 2022, 12:06 p.m. UTC
The kernel can now keep track of the bit-length of bitwise operations in
order to help user space eliminate generated operations during
delinearization.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
 include/libnftnl/expr.h       |  1 +
 src/expr/bitwise.c            | 15 +++++++++++++++
 tests/nft-expr_bitwise-test.c | 12 ++++++++++++
 3 files changed, 28 insertions(+)
diff mbox series

Patch

diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index 00c63ab9d19b..6adad4c222a6 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -128,6 +128,7 @@  enum {
 	NFTNL_EXPR_BITWISE_XOR,
 	NFTNL_EXPR_BITWISE_OP,
 	NFTNL_EXPR_BITWISE_DATA,
+	NFTNL_EXPR_BITWISE_NBITS,
 };
 
 enum {
diff --git a/src/expr/bitwise.c b/src/expr/bitwise.c
index d0c7827eacec..3fa627d7905d 100644
--- a/src/expr/bitwise.c
+++ b/src/expr/bitwise.c
@@ -29,6 +29,7 @@  struct nftnl_expr_bitwise {
 	union nftnl_data_reg	mask;
 	union nftnl_data_reg	xor;
 	union nftnl_data_reg	data;
+	unsigned int		nbits;
 };
 
 static int
@@ -62,6 +63,9 @@  nftnl_expr_bitwise_set(struct nftnl_expr *e, uint16_t type,
 		memcpy(&bitwise->data.val, data, data_len);
 		bitwise->data.len = data_len;
 		break;
+	case NFTNL_EXPR_BITWISE_NBITS:
+		memcpy(&bitwise->nbits, data, sizeof(bitwise->nbits));
+		break;
 	default:
 		return -1;
 	}
@@ -96,6 +100,9 @@  nftnl_expr_bitwise_get(const struct nftnl_expr *e, uint16_t type,
 	case NFTNL_EXPR_BITWISE_DATA:
 		*data_len = bitwise->data.len;
 		return &bitwise->data.val;
+	case NFTNL_EXPR_BITWISE_NBITS:
+		*data_len = sizeof(bitwise->nbits);
+		return &bitwise->nbits;
 	}
 	return NULL;
 }
@@ -113,6 +120,7 @@  static int nftnl_expr_bitwise_cb(const struct nlattr *attr, void *data)
 	case NFTA_BITWISE_DREG:
 	case NFTA_BITWISE_OP:
 	case NFTA_BITWISE_LEN:
+	case NFTA_BITWISE_NBITS:
 		if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
 			abi_breakage();
 		break;
@@ -141,6 +149,9 @@  nftnl_expr_bitwise_build(struct nlmsghdr *nlh, const struct nftnl_expr *e)
 		mnl_attr_put_u32(nlh, NFTA_BITWISE_OP, htonl(bitwise->op));
 	if (e->flags & (1 << NFTNL_EXPR_BITWISE_LEN))
 		mnl_attr_put_u32(nlh, NFTA_BITWISE_LEN, htonl(bitwise->len));
+	if (e->flags & (1 << NFTNL_EXPR_BITWISE_NBITS))
+		mnl_attr_put_u32(nlh, NFTA_BITWISE_NBITS,
+				 htonl(bitwise->nbits));
 	if (e->flags & (1 << NFTNL_EXPR_BITWISE_MASK)) {
 		struct nlattr *nest;
 
@@ -205,6 +216,10 @@  nftnl_expr_bitwise_parse(struct nftnl_expr *e, struct nlattr *attr)
 		ret = nftnl_parse_data(&bitwise->data, tb[NFTA_BITWISE_DATA], NULL);
 		e->flags |= (1 << NFTNL_EXPR_BITWISE_DATA);
 	}
+	if (tb[NFTA_BITWISE_NBITS]) {
+		bitwise->nbits = ntohl(mnl_attr_get_u32(tb[NFTA_BITWISE_NBITS]));
+		e->flags |= (1 << NFTNL_EXPR_BITWISE_NBITS);
+	}
 
 	return ret;
 }
diff --git a/tests/nft-expr_bitwise-test.c b/tests/nft-expr_bitwise-test.c
index f134728fdd86..9d01376a69bd 100644
--- a/tests/nft-expr_bitwise-test.c
+++ b/tests/nft-expr_bitwise-test.c
@@ -45,6 +45,9 @@  static void cmp_nftnl_expr_bool(struct nftnl_expr *rule_a,
 	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_BITWISE_LEN) !=
 	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_BITWISE_LEN))
 		print_err("bool", "Expr BITWISE_LEN mismatches");
+	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_BITWISE_NBITS) !=
+	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_BITWISE_NBITS))
+		print_err("bool", "Expr BITWISE_NBITS mismatches");
 	nftnl_expr_get(rule_a, NFTNL_EXPR_BITWISE_MASK, &maska);
 	nftnl_expr_get(rule_b, NFTNL_EXPR_BITWISE_MASK, &maskb);
 	if (maska != maskb)
@@ -72,6 +75,9 @@  static void cmp_nftnl_expr_lshift(struct nftnl_expr *rule_a,
 	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_BITWISE_LEN) !=
 	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_BITWISE_LEN))
 		print_err("lshift", "Expr BITWISE_LEN mismatches");
+	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_BITWISE_NBITS) !=
+	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_BITWISE_NBITS))
+		print_err("lshift", "Expr BITWISE_NBITS mismatches");
 	nftnl_expr_get(rule_a, NFTNL_EXPR_BITWISE_DATA, &data_a);
 	nftnl_expr_get(rule_b, NFTNL_EXPR_BITWISE_DATA, &data_b);
 	if (data_a != data_b)
@@ -95,6 +101,9 @@  static void cmp_nftnl_expr_rshift(struct nftnl_expr *rule_a,
 	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_BITWISE_LEN) !=
 	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_BITWISE_LEN))
 		print_err("rshift", "Expr BITWISE_LEN mismatches");
+	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_BITWISE_NBITS) !=
+	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_BITWISE_NBITS))
+		print_err("rshift", "Expr BITWISE_NBITS mismatches");
 	nftnl_expr_get(rule_a, NFTNL_EXPR_BITWISE_DATA, &data_a);
 	nftnl_expr_get(rule_b, NFTNL_EXPR_BITWISE_DATA, &data_b);
 	if (data_a != data_b)
@@ -124,6 +133,7 @@  static void test_bool(void)
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_DREG, 0x78123456);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_OP, NFT_BITWISE_BOOL);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_LEN, 0x56781234);
+	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_NBITS, 0x11223344);
 	nftnl_expr_set(ex, NFTNL_EXPR_BITWISE_MASK, &mask, sizeof(mask));
 	nftnl_expr_set(ex, NFTNL_EXPR_BITWISE_XOR, &xor, sizeof(xor));
 
@@ -179,6 +189,7 @@  static void test_lshift(void)
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_DREG, 0x78123456);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_OP, NFT_BITWISE_LSHIFT);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_LEN, 0x56781234);
+	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_NBITS, 0x11223344);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_DATA, 13);
 
 	nftnl_rule_add_expr(a, ex);
@@ -233,6 +244,7 @@  static void test_rshift(void)
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_DREG, 0x78123456);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_OP, NFT_BITWISE_RSHIFT);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_LEN, 0x56781234);
+	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_NBITS, 0x11223344);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_DATA, 17);
 
 	nftnl_rule_add_expr(a, ex);