@@ -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);
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(-)