summaryrefslogtreecommitdiffstats
path: root/src/evaluate.c
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2021-06-15 14:57:08 +0200
committerFlorian Westphal <fw@strlen.de>2021-06-21 14:44:58 +0200
commit6cf0f2c17bfb96c05dd0c03e0b91a75d732917cf (patch)
treeabb34028a9da0d2de41f26f1d40a61657022233c /src/evaluate.c
parent3486127e52426d1861a78b44f10e5997c3a69ff2 (diff)
src: queue: allow use of arbitrary queue expressions
back in 2016 Liping Zhang added support to kernel and libnftnl to specify a source register containing the queue number to use. This was never added to nft itself, so allow this. On linearization side, check if attached expression is a range. If its not, allocate a new register and set NFTNL_EXPR_QUEUE_SREG_QNUM attribute after generating the lowlevel expressions for the kernel. On delinarization we need to check for presence of NFTNL_EXPR_QUEUE_SREG_QNUM and decode the expression(s) when present. Also need to do postprocessing for STMT_QUEUE so that the protocol context is set correctly, without this only raw payload expressions will be shown (@nh,32,...) instead of 'ip ...'. Next patch adds test cases. Signed-off-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'src/evaluate.c')
-rw-r--r--src/evaluate.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/src/evaluate.c b/src/evaluate.c
index c24fee4c..4f19dc43 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1019,7 +1019,6 @@ static int expr_evaluate_range(struct eval_ctx *ctx, struct expr **expr)
if (mpz_cmp(left->value, right->value) >= 0)
return expr_error(ctx->msgs, range,
"Range has zero or negative size");
-
datatype_set(range, left->dtype);
range->flags |= EXPR_F_CONSTANT;
return 0;
@@ -3446,14 +3445,16 @@ static int stmt_evaluate_queue(struct eval_ctx *ctx, struct stmt *stmt)
BYTEORDER_HOST_ENDIAN,
&stmt->queue.queue) < 0)
return -1;
- if (!expr_is_constant(stmt->queue.queue))
- return expr_error(ctx->msgs, stmt->queue.queue,
- "queue number is not constant");
- if (stmt->queue.queue->etype != EXPR_RANGE &&
- (stmt->queue.flags & NFT_QUEUE_FLAG_CPU_FANOUT))
+
+ if ((stmt->queue.flags & NFT_QUEUE_FLAG_CPU_FANOUT) &&
+ stmt->queue.queue->etype != EXPR_RANGE)
return expr_error(ctx->msgs, stmt->queue.queue,
"fanout requires a range to be "
"specified");
+
+ if (ctx->ectx.maxval > USHRT_MAX)
+ return expr_error(ctx->msgs, stmt->queue.queue,
+ "queue expression max value exceeds %u", USHRT_MAX);
}
stmt->flags |= STMT_F_TERMINAL;
return 0;