[prev in list] [next in list] [prev in thread] [next in thread]
List: netfilter-devel
Subject: [PATCH nft v5 6/8] evaluate: allow binop expressions with variable right-hand operands
From: Jeremy Sowden <jeremy () azazel ! net>
Date: 2023-05-28 14:00:56
Message-ID: 20230528140058.1218669-7-jeremy () azazel ! net
[Download RAW message or body]
Hitherto, the kernel has required constant values for the `xor` and
`mask` attributes of boolean bitwise expressions. This has meant that
the right-hand operand of a boolean binop must be constant. Now the
kernel has support for AND, OR and XOR operations with right-hand
operands passed via registers, we can relax this restriction. Allow
non-constant right-hand operands if the left-hand operand is not
constant, e.g.:
ct mark & 0xffff0000 | meta mark & 0xffff
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
src/evaluate.c | 43 +++++++++++++++++++++++++++----------------
1 file changed, 27 insertions(+), 16 deletions(-)
diff --git a/src/evaluate.c b/src/evaluate.c
index 136b4539e828..c98bd578f38b 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1369,16 +1369,18 @@ static int expr_evaluate_bitwise(struct eval_ctx *ctx, struct expr **expr)
op->byteorder = byteorder;
op->len = max_len;
- if (expr_is_constant(left))
+ if (expr_is_constant(left) && expr_is_constant(op->right))
return constant_binop_simplify(ctx, expr);
return 0;
}
/*
- * Binop expression: both sides must be of integer base type. The left
- * hand side may be either constant or non-constant; in case its constant
- * it must be a singleton. The ride hand side must always be a constant
- * singleton.
+ * Binop expression: both sides must be of integer base type. The left-hand side
+ * may be either constant or non-constant; if it is constant, it must be a
+ * singleton. For bitwise operations, the right-hand side must be constant if
+ * the left-hand side is constant; the right-hand side may be constant or
+ * non-constant, if the left-hand side is non-constant; for shifts, the
+ * right-hand side must be constant; if it is constant, it must be a singleton.
*/
static int expr_evaluate_binop(struct eval_ctx *ctx, struct expr **expr)
{
@@ -1419,27 +1421,36 @@ static int expr_evaluate_binop(struct eval_ctx *ctx, struct expr **expr)
"for %s expressions",
sym, expr_name(left));
- if (!expr_is_constant(right))
- return expr_binary_error(ctx->msgs, right, op,
- "Right hand side of binary operation "
- "(%s) must be constant", sym);
-
- if (!expr_is_singleton(right))
- return expr_binary_error(ctx->msgs, left, op,
- "Binary operation (%s) is undefined "
- "for %s expressions",
- sym, expr_name(right));
-
/* The grammar guarantees this */
assert(datatype_equal(expr_basetype(left), expr_basetype(right)));
switch (op->op) {
case OP_LSHIFT:
case OP_RSHIFT:
+ if (!expr_is_constant(right))
+ return expr_binary_error(ctx->msgs, right, op,
+ "Right hand side of binary operation "
+ "(%s) must be constant", sym);
+
+ if (!expr_is_singleton(right))
+ return expr_binary_error(ctx->msgs, left, op,
+ "Binary operation (%s) is undefined "
+ "for %s expressions",
+ sym, expr_name(right));
return expr_evaluate_shift(ctx, expr);
case OP_AND:
case OP_XOR:
case OP_OR:
+ if (expr_is_constant(left) && !expr_is_constant(right))
+ return expr_binary_error(ctx->msgs, right, op,
+ "Right hand side of binary operation "
+ "(%s) must be constant", sym);
+
+ if (expr_is_constant(right) && !expr_is_singleton(right))
+ return expr_binary_error(ctx->msgs, left, op,
+ "Binary operation (%s) is undefined "
+ "for %s expressions",
+ sym, expr_name(right));
return expr_evaluate_bitwise(ctx, expr);
default:
BUG("invalid binary operation %u\n", op->op);
--
2.39.2
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic