From patchwork Wed Jun 16 21:16:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Westphal X-Patchwork-Id: 1493088 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4G4ygp3rCSz9sRf for ; Thu, 17 Jun 2021 07:17:26 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233966AbhFPVTc (ORCPT ); Wed, 16 Jun 2021 17:19:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60416 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233836AbhFPVTc (ORCPT ); Wed, 16 Jun 2021 17:19:32 -0400 Received: from Chamillionaire.breakpoint.cc (Chamillionaire.breakpoint.cc [IPv6:2a0a:51c0:0:12e:520::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ABC0BC061574 for ; Wed, 16 Jun 2021 14:17:25 -0700 (PDT) Received: from fw by Chamillionaire.breakpoint.cc with local (Exim 4.92) (envelope-from ) id 1ltcua-0002T6-65; Wed, 16 Jun 2021 23:17:24 +0200 From: Florian Westphal To: Cc: jake.owen@superloop.com, Florian Westphal Subject: [PATCH nft 1/8] evaluate: fix hash expression maxval Date: Wed, 16 Jun 2021 23:16:45 +0200 Message-Id: <20210616211652.11765-2-fw@strlen.de> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210616211652.11765-1-fw@strlen.de> References: <20210616211652.11765-1-fw@strlen.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org It needs to account for the offset too. Fixes: 9bee0c86f179 ("src: add offset attribute for hash expression") Fixes: d4f9a8fb9e9a ("src: add offset attribute for numgen expression") Signed-off-by: Florian Westphal --- src/evaluate.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/evaluate.c b/src/evaluate.c index aa7ec9bee4ae..bebdb3f827e9 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -1657,17 +1657,20 @@ static void expr_dtype_integer_compatible(struct eval_ctx *ctx, static int expr_evaluate_numgen(struct eval_ctx *ctx, struct expr **exprp) { struct expr *expr = *exprp; + unsigned int maxval; expr_dtype_integer_compatible(ctx, expr); + maxval = expr->numgen.mod + expr->numgen.offset - 1; __expr_set_context(&ctx->ectx, expr->dtype, expr->byteorder, expr->len, - expr->numgen.mod - 1); + maxval); return 0; } static int expr_evaluate_hash(struct eval_ctx *ctx, struct expr **exprp) { struct expr *expr = *exprp; + unsigned int maxval; expr_dtype_integer_compatible(ctx, expr); @@ -1680,8 +1683,9 @@ static int expr_evaluate_hash(struct eval_ctx *ctx, struct expr **exprp) * expression to be hashed. Since this input is transformed to a 4 bytes * integer, restore context to the datatype that results from hashing. */ + maxval = expr->hash.mod + expr->hash.offset - 1; __expr_set_context(&ctx->ectx, expr->dtype, expr->byteorder, expr->len, - expr->hash.mod - 1); + maxval); return 0; } From patchwork Wed Jun 16 21:16:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Westphal X-Patchwork-Id: 1493089 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4G4ygt48S2z9sRf for ; Thu, 17 Jun 2021 07:17:30 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233969AbhFPVTg (ORCPT ); Wed, 16 Jun 2021 17:19:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60432 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233836AbhFPVTg (ORCPT ); Wed, 16 Jun 2021 17:19:36 -0400 Received: from Chamillionaire.breakpoint.cc (Chamillionaire.breakpoint.cc [IPv6:2a0a:51c0:0:12e:520::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D2065C061574 for ; Wed, 16 Jun 2021 14:17:29 -0700 (PDT) Received: from fw by Chamillionaire.breakpoint.cc with local (Exim 4.92) (envelope-from ) id 1ltcue-0002TR-Bt; Wed, 16 Jun 2021 23:17:28 +0200 From: Florian Westphal To: Cc: jake.owen@superloop.com, Florian Westphal Subject: [PATCH nft 2/8] parser: restrict queue num expressiveness Date: Wed, 16 Jun 2021 23:16:46 +0200 Message-Id: <20210616211652.11765-3-fw@strlen.de> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210616211652.11765-1-fw@strlen.de> References: <20210616211652.11765-1-fw@strlen.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Else we run into trouble once we allow queue num symhash mod 4 and 1 and so on. Example problem: queue num jhash ip saddr mod 4 and 1 bypass This will fail to parse because the scanner is in the wrong state (ip, not queue), so 'bypass' is parsed as a string. Currently, while nft will eat the above just fine (minus 'bypass'), nft rejects this from the evaluation phase with Error: queue number is not constant So seems we are lucky and can restrict the supported expressions to integer and range. Furthermore, the line looks wrong because this statement: queue num jhash ip saddr mod 4 and 1 bypass doesn't specifiy a number, "queue num 4" does, or "queue num 1-2" do. For arbitrary expr support it seems sensible to enforce stricter ordering to avoid any problems with the flags, for example: queue bypass,futurekeyword to jhash ip saddr mod 42 Signed-off-by: Florian Westphal --- src/parser_bison.y | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/parser_bison.y b/src/parser_bison.y index bd2232a3de27..2ab47ed55166 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -705,6 +705,8 @@ int nft_lex(void *, void *, void *); %type queue_stmt queue_stmt_alloc %destructor { stmt_free($$); } queue_stmt queue_stmt_alloc +%type queue_stmt_expr +%destructor { expr_free($$); } queue_stmt_expr %type queue_stmt_flags queue_stmt_flag %type dup_stmt %destructor { stmt_free($$); } dup_stmt @@ -3753,7 +3755,7 @@ queue_stmt_args : queue_stmt_arg | queue_stmt_args queue_stmt_arg ; -queue_stmt_arg : QUEUENUM stmt_expr +queue_stmt_arg : QUEUENUM queue_stmt_expr { $0->queue.queue = $2; $0->queue.queue->location = @$; @@ -3764,6 +3766,10 @@ queue_stmt_arg : QUEUENUM stmt_expr } ; +queue_stmt_expr : integer_expr + | range_rhs_expr + ; + queue_stmt_flags : queue_stmt_flag | queue_stmt_flags COMMA queue_stmt_flag { From patchwork Wed Jun 16 21:16:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Westphal X-Patchwork-Id: 1493090 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4G4ygz35FJz9sRf for ; Thu, 17 Jun 2021 07:17:35 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233971AbhFPVTl (ORCPT ); Wed, 16 Jun 2021 17:19:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60448 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233836AbhFPVTk (ORCPT ); Wed, 16 Jun 2021 17:19:40 -0400 Received: from Chamillionaire.breakpoint.cc (Chamillionaire.breakpoint.cc [IPv6:2a0a:51c0:0:12e:520::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0658CC061574 for ; Wed, 16 Jun 2021 14:17:34 -0700 (PDT) Received: from fw by Chamillionaire.breakpoint.cc with local (Exim 4.92) (envelope-from ) id 1ltcui-0002Tp-HY; Wed, 16 Jun 2021 23:17:32 +0200 From: Florian Westphal To: Cc: jake.owen@superloop.com, Florian Westphal Subject: [PATCH nft 3/8] src: add queue expr and flags to queue_stmt_alloc Date: Wed, 16 Jun 2021 23:16:47 +0200 Message-Id: <20210616211652.11765-4-fw@strlen.de> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210616211652.11765-1-fw@strlen.de> References: <20210616211652.11765-1-fw@strlen.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Preparation patch to avoid too much $$ references in the parser. Signed-off-by: Florian Westphal --- include/statement.h | 3 ++- src/netlink_delinearize.c | 10 +++------- src/parser_bison.y | 2 +- src/parser_json.c | 22 +++++++++++----------- src/statement.c | 10 ++++++++-- 5 files changed, 25 insertions(+), 22 deletions(-) diff --git a/include/statement.h b/include/statement.h index 7637a82e4e00..06221040fa0c 100644 --- a/include/statement.h +++ b/include/statement.h @@ -159,7 +159,8 @@ struct queue_stmt { uint16_t flags; }; -extern struct stmt *queue_stmt_alloc(const struct location *loc); +extern struct stmt *queue_stmt_alloc(const struct location *loc, + struct expr *e, uint16_t flags); struct quota_stmt { uint64_t bytes; diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 5c80397db26c..7ea31e6a2639 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -1467,9 +1467,8 @@ static void netlink_parse_queue(struct netlink_parse_ctx *ctx, const struct location *loc, const struct nftnl_expr *nle) { + uint16_t num, total, flags; struct expr *expr, *high; - struct stmt *stmt; - uint16_t num, total; num = nftnl_expr_get_u16(nle, NFTNL_EXPR_QUEUE_NUM); total = nftnl_expr_get_u16(nle, NFTNL_EXPR_QUEUE_TOTAL); @@ -1483,11 +1482,8 @@ static void netlink_parse_queue(struct netlink_parse_ctx *ctx, expr = range_expr_alloc(loc, expr, high); } - stmt = queue_stmt_alloc(loc); - stmt->queue.queue = expr; - stmt->queue.flags = nftnl_expr_get_u16(nle, NFTNL_EXPR_QUEUE_FLAGS); - - ctx->stmt = stmt; + flags = nftnl_expr_get_u16(nle, NFTNL_EXPR_QUEUE_FLAGS); + ctx->stmt = queue_stmt_alloc(loc, expr, flags); } struct dynset_parse_ctx { diff --git a/src/parser_bison.y b/src/parser_bison.y index 2ab47ed55166..96676aed2e38 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -3744,7 +3744,7 @@ queue_stmt : queue_stmt_alloc close_scope_queue queue_stmt_alloc : QUEUE { - $$ = queue_stmt_alloc(&@$); + $$ = queue_stmt_alloc(&@$, NULL, 0); } ; diff --git a/src/parser_json.c b/src/parser_json.c index bb0e4169b477..e03b51697cb7 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -2559,14 +2559,14 @@ static int queue_flag_parse(const char *name, uint16_t *flags) static struct stmt *json_parse_queue_stmt(struct json_ctx *ctx, const char *key, json_t *value) { - struct stmt *stmt = queue_stmt_alloc(int_loc); + struct expr *qexpr = NULL; + uint16_t flags = 0; json_t *tmp; if (!json_unpack(value, "{s:o}", "num", &tmp)) { - stmt->queue.queue = json_parse_stmt_expr(ctx, tmp); - if (!stmt->queue.queue) { + qexpr = json_parse_stmt_expr(ctx, tmp); + if (!qexpr) { json_error(ctx, "Invalid queue num."); - stmt_free(stmt); return NULL; } } @@ -2578,15 +2578,15 @@ static struct stmt *json_parse_queue_stmt(struct json_ctx *ctx, if (json_is_string(tmp)) { flag = json_string_value(tmp); - if (queue_flag_parse(flag, &stmt->queue.flags)) { + if (queue_flag_parse(flag, &flags)) { json_error(ctx, "Invalid queue flag '%s'.", flag); - stmt_free(stmt); + expr_free(qexpr); return NULL; } } else if (!json_is_array(tmp)) { json_error(ctx, "Unexpected object type in queue flags."); - stmt_free(stmt); + expr_free(qexpr); return NULL; } @@ -2594,20 +2594,20 @@ static struct stmt *json_parse_queue_stmt(struct json_ctx *ctx, if (!json_is_string(val)) { json_error(ctx, "Invalid object in queue flag array at index %zu.", index); - stmt_free(stmt); + expr_free(qexpr); return NULL; } flag = json_string_value(val); - if (queue_flag_parse(flag, &stmt->queue.flags)) { + if (queue_flag_parse(flag, &flags)) { json_error(ctx, "Invalid queue flag '%s'.", flag); - stmt_free(stmt); + expr_free(qexpr); return NULL; } } } - return stmt; + return queue_stmt_alloc(int_loc, qexpr, flags); } static struct stmt *json_parse_connlimit_stmt(struct json_ctx *ctx, diff --git a/src/statement.c b/src/statement.c index 7537c07f495c..a713952c0af7 100644 --- a/src/statement.c +++ b/src/statement.c @@ -522,9 +522,15 @@ static const struct stmt_ops queue_stmt_ops = { .destroy = queue_stmt_destroy, }; -struct stmt *queue_stmt_alloc(const struct location *loc) +struct stmt *queue_stmt_alloc(const struct location *loc, struct expr *e, uint16_t flags) { - return stmt_alloc(loc, &queue_stmt_ops); + struct stmt *stmt; + + stmt = stmt_alloc(loc, &queue_stmt_ops); + stmt->queue.queue = e; + stmt->queue.flags = flags; + + return stmt; } static void quota_stmt_print(const struct stmt *stmt, struct output_ctx *octx) From patchwork Wed Jun 16 21:16:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Westphal X-Patchwork-Id: 1493091 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4G4yh260Pnz9sRf for ; Thu, 17 Jun 2021 07:17:38 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233975AbhFPVTo (ORCPT ); Wed, 16 Jun 2021 17:19:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60464 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233836AbhFPVTo (ORCPT ); Wed, 16 Jun 2021 17:19:44 -0400 Received: from Chamillionaire.breakpoint.cc (Chamillionaire.breakpoint.cc [IPv6:2a0a:51c0:0:12e:520::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 25CE0C061574 for ; Wed, 16 Jun 2021 14:17:38 -0700 (PDT) Received: from fw by Chamillionaire.breakpoint.cc with local (Exim 4.92) (envelope-from ) id 1ltcum-0002U5-N4; Wed, 16 Jun 2021 23:17:36 +0200 From: Florian Westphal To: Cc: jake.owen@superloop.com, Florian Westphal Subject: [PATCH nft 4/8] parser: add queue_stmt_compat Date: Wed, 16 Jun 2021 23:16:48 +0200 Message-Id: <20210616211652.11765-5-fw@strlen.de> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210616211652.11765-1-fw@strlen.de> References: <20210616211652.11765-1-fw@strlen.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Rename existing rules to _compat to make sure old rules using 'queue' statement will work. Next patch adds distinct input format where flags are explicitly provided: queue flags name, num 1 Without this, extension of queue expression to handle arbitrary expression instead of queue number or range results in parser errors. Example: queue num jhash ip saddr mod 4 and 1 bypass will fail because scanner is still in 'ip' state, not 'queue', when "bypass" is read. Signed-off-by: Florian Westphal --- src/parser_bison.y | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/parser_bison.y b/src/parser_bison.y index 96676aed2e38..9e45a5da1716 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -703,10 +703,10 @@ int nft_lex(void *, void *, void *); %destructor { stmt_free($$); } chain_stmt %type chain_stmt_type -%type queue_stmt queue_stmt_alloc -%destructor { stmt_free($$); } queue_stmt queue_stmt_alloc -%type queue_stmt_expr -%destructor { expr_free($$); } queue_stmt_expr +%type queue_stmt queue_stmt_alloc queue_stmt_compat +%destructor { stmt_free($$); } queue_stmt queue_stmt_alloc queue_stmt_compat +%type queue_stmt_expr_simple +%destructor { expr_free($$); } queue_stmt_expr_simple %type queue_stmt_flags queue_stmt_flag %type dup_stmt %destructor { stmt_free($$); } dup_stmt @@ -3738,8 +3738,11 @@ nf_nat_flag : RANDOM { $$ = NF_NAT_RANGE_PROTO_RANDOM; } | PERSISTENT { $$ = NF_NAT_RANGE_PERSISTENT; } ; -queue_stmt : queue_stmt_alloc close_scope_queue - | queue_stmt_alloc queue_stmt_args close_scope_queue +queue_stmt : queue_stmt_compat close_scope_queue + ; + +queue_stmt_compat : queue_stmt_alloc + | queue_stmt_alloc queue_stmt_args ; queue_stmt_alloc : QUEUE @@ -3755,7 +3758,7 @@ queue_stmt_args : queue_stmt_arg | queue_stmt_args queue_stmt_arg ; -queue_stmt_arg : QUEUENUM queue_stmt_expr +queue_stmt_arg : QUEUENUM queue_stmt_expr_simple { $0->queue.queue = $2; $0->queue.queue->location = @$; @@ -3766,7 +3769,7 @@ queue_stmt_arg : QUEUENUM queue_stmt_expr } ; -queue_stmt_expr : integer_expr +queue_stmt_expr_simple : integer_expr | range_rhs_expr ; From patchwork Wed Jun 16 21:16:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Westphal X-Patchwork-Id: 1493092 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4G4yh71lxMz9sW4 for ; Thu, 17 Jun 2021 07:17:43 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233979AbhFPVTt (ORCPT ); Wed, 16 Jun 2021 17:19:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60480 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233836AbhFPVTs (ORCPT ); Wed, 16 Jun 2021 17:19:48 -0400 Received: from Chamillionaire.breakpoint.cc (Chamillionaire.breakpoint.cc [IPv6:2a0a:51c0:0:12e:520::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 53641C061574 for ; Wed, 16 Jun 2021 14:17:42 -0700 (PDT) Received: from fw by Chamillionaire.breakpoint.cc with local (Exim 4.92) (envelope-from ) id 1ltcuq-0002UL-R9; Wed, 16 Jun 2021 23:17:40 +0200 From: Florian Westphal To: Cc: jake.owen@superloop.com, Florian Westphal Subject: [PATCH nft 5/8] parser: new queue flag input format Date: Wed, 16 Jun 2021 23:16:49 +0200 Message-Id: <20210616211652.11765-6-fw@strlen.de> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210616211652.11765-1-fw@strlen.de> References: <20210616211652.11765-1-fw@strlen.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org This changes output to first list the queue flags (with prepended "flags" keyword), then the queue number. This is to avoid parser problems when a flag is used after the queue number, e.g. "queue num 42 bypass". While this works fine, this does not: "queue num tcp dport bypass" ... because scanner state has been switched, "bypass" is parsed as symbol expression. Input parser is changed to recognize the stricter flag usage. Signed-off-by: Florian Westphal --- doc/statements.txt | 4 ++-- src/parser_bison.y | 4 ++++ src/statement.c | 15 ++++++++++----- tests/py/any/queue.t | 7 +++---- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/doc/statements.txt b/doc/statements.txt index 7c7240c82fab..602a5b2011a7 100644 --- a/doc/statements.txt +++ b/doc/statements.txt @@ -589,8 +589,8 @@ for details. [verse] ____ -*queue* [*num* 'queue_number'] [*bypass*] -*queue* [*num* 'queue_number_from' - 'queue_number_to'] ['QUEUE_FLAGS'] +*queue* [*flags* 'QUEUE_FLAGS'] [*num* 'queue_number'] +*queue* [*flags* 'QUEUE_FLAGS'] [*num* 'queue_number_from' - 'queue_number_to'] 'QUEUE_FLAGS' := 'QUEUE_FLAG' [*,* 'QUEUE_FLAGS'] 'QUEUE_FLAG' := *bypass* | *fanout* diff --git a/src/parser_bison.y b/src/parser_bison.y index 9e45a5da1716..cf90d5ce5672 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -3739,6 +3739,10 @@ nf_nat_flag : RANDOM { $$ = NF_NAT_RANGE_PROTO_RANDOM; } ; queue_stmt : queue_stmt_compat close_scope_queue + | QUEUE FLAGS queue_stmt_flags QUEUENUM queue_stmt_expr_simple close_scope_queue + { + $$ = queue_stmt_alloc(&@$, $5, $3); + } ; queue_stmt_compat : queue_stmt_alloc diff --git a/src/statement.c b/src/statement.c index a713952c0af7..9eb49339555b 100644 --- a/src/statement.c +++ b/src/statement.c @@ -493,20 +493,25 @@ struct stmt *limit_stmt_alloc(const struct location *loc) static void queue_stmt_print(const struct stmt *stmt, struct output_ctx *octx) { - const char *delim = " "; + struct expr *e = stmt->queue.queue; + const char *delim = " flags "; nft_print(octx, "queue"); - if (stmt->queue.queue != NULL) { - nft_print(octx, " num "); - expr_print(stmt->queue.queue, octx); - } + if (stmt->queue.flags & NFT_QUEUE_FLAG_BYPASS) { nft_print(octx, "%sbypass", delim); delim = ","; } + if (stmt->queue.flags & NFT_QUEUE_FLAG_CPU_FANOUT) nft_print(octx, "%sfanout", delim); + if (e) { + nft_print(octx, " num "); + expr_print(stmt->queue.queue, octx); + } else { + nft_print(octx, " num 0"); + } } static void queue_stmt_destroy(struct stmt *stmt) diff --git a/tests/py/any/queue.t b/tests/py/any/queue.t index 75c071dde44b..af844aa7c835 100644 --- a/tests/py/any/queue.t +++ b/tests/py/any/queue.t @@ -12,7 +12,6 @@ queue num 65535;ok queue num 65536;fail queue num 2-3;ok queue num 1-65535;ok -- queue num {3, 4, 6};ok -queue num 4-5 fanout bypass;ok;queue num 4-5 bypass,fanout -queue num 4-5 fanout;ok -queue num 4-5 bypass;ok +queue num 4-5 fanout bypass;ok;queue flags bypass,fanout num 4-5 +queue num 4-5 fanout;ok;queue flags fanout num 4-5 +queue num 4-5 bypass;ok;queue flags bypass num 4-5 From patchwork Wed Jun 16 21:16:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Westphal X-Patchwork-Id: 1493093 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4G4yhC2C8vz9sRf for ; Thu, 17 Jun 2021 07:17:47 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233983AbhFPVTx (ORCPT ); Wed, 16 Jun 2021 17:19:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60498 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233836AbhFPVTx (ORCPT ); Wed, 16 Jun 2021 17:19:53 -0400 Received: from Chamillionaire.breakpoint.cc (Chamillionaire.breakpoint.cc [IPv6:2a0a:51c0:0:12e:520::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8604AC061574 for ; Wed, 16 Jun 2021 14:17:46 -0700 (PDT) Received: from fw by Chamillionaire.breakpoint.cc with local (Exim 4.92) (envelope-from ) id 1ltcuv-0002Ub-0F; Wed, 16 Jun 2021 23:17:45 +0200 From: Florian Westphal To: Cc: jake.owen@superloop.com, Florian Westphal Subject: [PATCH nft 6/8] src: queue: allow use of arbitrary queue expressions Date: Wed, 16 Jun 2021 23:16:50 +0200 Message-Id: <20210616211652.11765-7-fw@strlen.de> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210616211652.11765-1-fw@strlen.de> References: <20210616211652.11765-1-fw@strlen.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org 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 --- doc/statements.txt | 4 ++++ src/evaluate.c | 13 ++++++----- src/netlink_delinearize.c | 48 +++++++++++++++++++++++++++++++-------- src/netlink_linearize.c | 28 +++++++++++++++++++---- src/parser_bison.y | 16 +++++++++++-- src/statement.c | 9 ++++++-- 6 files changed, 93 insertions(+), 25 deletions(-) diff --git a/doc/statements.txt b/doc/statements.txt index 602a5b2011a7..c2a616594fce 100644 --- a/doc/statements.txt +++ b/doc/statements.txt @@ -591,11 +591,15 @@ for details. ____ *queue* [*flags* 'QUEUE_FLAGS'] [*num* 'queue_number'] *queue* [*flags* 'QUEUE_FLAGS'] [*num* 'queue_number_from' - 'queue_number_to'] +*queue* [*flags* 'QUEUE_FLAGS'] [*to* 'QUEUE_EXPRESSION' ] 'QUEUE_FLAGS' := 'QUEUE_FLAG' [*,* 'QUEUE_FLAGS'] 'QUEUE_FLAG' := *bypass* | *fanout* +'QUEUE_EXPRESSION' := *numgen* | *hash* | *symhash* ____ +QUEUE_EXPRESSION can be used to compute a queue number +at run-time with the hash or numgen expressions. .queue statement values [options="header"] diff --git a/src/evaluate.c b/src/evaluate.c index bebdb3f827e9..4a7ec95cd961 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; @@ -3428,14 +3427,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; diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 7ea31e6a2639..07a6d06876e2 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -1467,19 +1467,32 @@ static void netlink_parse_queue(struct netlink_parse_ctx *ctx, const struct location *loc, const struct nftnl_expr *nle) { - uint16_t num, total, flags; - struct expr *expr, *high; + struct expr *expr; + uint16_t flags; - num = nftnl_expr_get_u16(nle, NFTNL_EXPR_QUEUE_NUM); - total = nftnl_expr_get_u16(nle, NFTNL_EXPR_QUEUE_TOTAL); + if (nftnl_expr_is_set(nle, NFTNL_EXPR_QUEUE_SREG_QNUM)) { + enum nft_registers reg = netlink_parse_register(nle, NFTNL_EXPR_QUEUE_SREG_QNUM); - expr = constant_expr_alloc(loc, &integer_type, - BYTEORDER_HOST_ENDIAN, 16, &num); - if (total > 1) { - total += num - 1; - high = constant_expr_alloc(loc, &integer_type, + expr = netlink_get_register(ctx, loc, reg); + if (!expr) { + netlink_error(ctx, loc, "queue statement has no sreg expression"); + return; + } + } else { + uint16_t total = nftnl_expr_get_u16(nle, NFTNL_EXPR_QUEUE_TOTAL); + uint16_t num = nftnl_expr_get_u16(nle, NFTNL_EXPR_QUEUE_NUM); + + expr = constant_expr_alloc(loc, &integer_type, + BYTEORDER_HOST_ENDIAN, 16, &num); + + if (total > 1) { + struct expr *high; + + total += num - 1; + high = constant_expr_alloc(loc, &integer_type, BYTEORDER_HOST_ENDIAN, 16, &total); - expr = range_expr_alloc(loc, expr, high); + expr = range_expr_alloc(loc, expr, high); + } } flags = nftnl_expr_get_u16(nle, NFTNL_EXPR_QUEUE_FLAGS); @@ -2788,6 +2801,18 @@ static void stmt_payload_postprocess(struct rule_pp_ctx *ctx) expr_postprocess(ctx, &stmt->payload.val); } +static void stmt_queue_postprocess(struct rule_pp_ctx *ctx) +{ + struct stmt *stmt = ctx->stmt; + struct expr *e = stmt->queue.queue; + + if (e == NULL || e->etype == EXPR_VALUE || + e->etype == EXPR_RANGE) + return; + + expr_postprocess(ctx, &stmt->queue.queue); +} + /* * We can only remove payload dependencies if they occur without * a statement with side effects in between. @@ -2889,6 +2914,9 @@ static void rule_parse_postprocess(struct netlink_parse_ctx *ctx, struct rule *r case STMT_OBJREF: expr_postprocess(&rctx, &stmt->objref.expr); break; + case STMT_QUEUE: + stmt_queue_postprocess(&rctx); + break; default: break; } diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c index 7b35aae1f913..b1f3feeeb4b7 100644 --- a/src/netlink_linearize.c +++ b/src/netlink_linearize.c @@ -1334,21 +1334,39 @@ static void netlink_gen_fwd_stmt(struct netlink_linearize_ctx *ctx, static void netlink_gen_queue_stmt(struct netlink_linearize_ctx *ctx, const struct stmt *stmt) { + enum nft_registers sreg = 0; struct nftnl_expr *nle; uint16_t total_queues; + struct expr *expr; mpz_t low, high; mpz_init2(low, 16); mpz_init2(high, 16); - if (stmt->queue.queue != NULL) { - range_expr_value_low(low, stmt->queue.queue); - range_expr_value_high(high, stmt->queue.queue); + + expr = stmt->queue.queue; + + if (expr) { + if (expr->etype == EXPR_RANGE || expr->etype == EXPR_VALUE) { + range_expr_value_low(low, stmt->queue.queue); + range_expr_value_high(high, stmt->queue.queue); + } else { + sreg = get_register(ctx, expr); + netlink_gen_expr(ctx, expr, sreg); + release_register(ctx, expr); + } } + total_queues = mpz_get_uint16(high) - mpz_get_uint16(low) + 1; nle = alloc_nft_expr("queue"); - nftnl_expr_set_u16(nle, NFTNL_EXPR_QUEUE_NUM, mpz_get_uint16(low)); - nftnl_expr_set_u16(nle, NFTNL_EXPR_QUEUE_TOTAL, total_queues); + + if (sreg) { + netlink_put_register(nle, NFTNL_EXPR_QUEUE_SREG_QNUM, sreg); + } else { + nftnl_expr_set_u16(nle, NFTNL_EXPR_QUEUE_NUM, mpz_get_uint16(low)); + nftnl_expr_set_u16(nle, NFTNL_EXPR_QUEUE_TOTAL, total_queues); + } + if (stmt->queue.flags) nftnl_expr_set_u16(nle, NFTNL_EXPR_QUEUE_FLAGS, stmt->queue.flags); diff --git a/src/parser_bison.y b/src/parser_bison.y index cf90d5ce5672..d75960715a90 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -705,8 +705,8 @@ int nft_lex(void *, void *, void *); %type queue_stmt queue_stmt_alloc queue_stmt_compat %destructor { stmt_free($$); } queue_stmt queue_stmt_alloc queue_stmt_compat -%type queue_stmt_expr_simple -%destructor { expr_free($$); } queue_stmt_expr_simple +%type queue_stmt_expr_simple queue_stmt_expr +%destructor { expr_free($$); } queue_stmt_expr_simple queue_stmt_expr %type queue_stmt_flags queue_stmt_flag %type dup_stmt %destructor { stmt_free($$); } dup_stmt @@ -3739,6 +3739,14 @@ nf_nat_flag : RANDOM { $$ = NF_NAT_RANGE_PROTO_RANDOM; } ; queue_stmt : queue_stmt_compat close_scope_queue + | QUEUE TO queue_stmt_expr close_scope_queue + { + $$ = queue_stmt_alloc(&@$, $3, 0); + } + | QUEUE FLAGS queue_stmt_flags TO queue_stmt_expr close_scope_queue + { + $$ = queue_stmt_alloc(&@$, $5, $3); + } | QUEUE FLAGS queue_stmt_flags QUEUENUM queue_stmt_expr_simple close_scope_queue { $$ = queue_stmt_alloc(&@$, $5, $3); @@ -3777,6 +3785,10 @@ queue_stmt_expr_simple : integer_expr | range_rhs_expr ; +queue_stmt_expr : numgen_expr + | hash_expr + ; + queue_stmt_flags : queue_stmt_flag | queue_stmt_flags COMMA queue_stmt_flag { diff --git a/src/statement.c b/src/statement.c index 9eb49339555b..dfd275104c59 100644 --- a/src/statement.c +++ b/src/statement.c @@ -507,8 +507,13 @@ static void queue_stmt_print(const struct stmt *stmt, struct output_ctx *octx) nft_print(octx, "%sfanout", delim); if (e) { - nft_print(octx, " num "); - expr_print(stmt->queue.queue, octx); + if (e->etype == EXPR_VALUE || e->etype == EXPR_RANGE) { + nft_print(octx, " num "); + expr_print(stmt->queue.queue, octx); + } else { + nft_print(octx, " to "); + expr_print(stmt->queue.queue, octx); + } } else { nft_print(octx, " num 0"); } From patchwork Wed Jun 16 21:16:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Westphal X-Patchwork-Id: 1493094 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4G4yhH2Twkz9sRf for ; Thu, 17 Jun 2021 07:17:51 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233985AbhFPVT5 (ORCPT ); Wed, 16 Jun 2021 17:19:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60514 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233836AbhFPVT5 (ORCPT ); Wed, 16 Jun 2021 17:19:57 -0400 Received: from Chamillionaire.breakpoint.cc (Chamillionaire.breakpoint.cc [IPv6:2a0a:51c0:0:12e:520::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A33D4C061574 for ; Wed, 16 Jun 2021 14:17:50 -0700 (PDT) Received: from fw by Chamillionaire.breakpoint.cc with local (Exim 4.92) (envelope-from ) id 1ltcuz-0002Us-5k; Wed, 16 Jun 2021 23:17:49 +0200 From: Florian Westphal To: Cc: jake.owen@superloop.com, Florian Westphal Subject: [PATCH nft 7/8] tests: extend queue testcases for new sreg support Date: Wed, 16 Jun 2021 23:16:51 +0200 Message-Id: <20210616211652.11765-8-fw@strlen.de> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210616211652.11765-1-fw@strlen.de> References: <20210616211652.11765-1-fw@strlen.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Signed-off-by: Florian Westphal --- tests/py/any/queue.t | 10 +++++++ tests/py/any/queue.t.json | 56 ++++++++++++++++++++++++++++++++++++ tests/py/any/queue.t.payload | 16 +++++++++++ 3 files changed, 82 insertions(+) diff --git a/tests/py/any/queue.t b/tests/py/any/queue.t index af844aa7c835..670dfd92d5b0 100644 --- a/tests/py/any/queue.t +++ b/tests/py/any/queue.t @@ -15,3 +15,13 @@ queue num 1-65535;ok queue num 4-5 fanout bypass;ok;queue flags bypass,fanout num 4-5 queue num 4-5 fanout;ok;queue flags fanout num 4-5 queue num 4-5 bypass;ok;queue flags bypass num 4-5 + +queue to symhash mod 2 offset 65536;fail +queue num symhash mod 65536;fail +queue to symhash mod 65536;ok +queue flags fanout to symhash mod 65536;fail +queue flags bypass,fanout to symhash mod 65536;fail +queue flags bypass to numgen inc mod 65536;ok +queue to jhash oif . meta mark mod 32;ok +queue to oif;fail +queue num oif;fail diff --git a/tests/py/any/queue.t.json b/tests/py/any/queue.t.json index 48e86727a2ff..18ed3c817ac9 100644 --- a/tests/py/any/queue.t.json +++ b/tests/py/any/queue.t.json @@ -84,3 +84,59 @@ } ] +# queue to symhash mod 65536 +[ + { + "queue": { + "num": { + "symhash": { + "mod": 65536 + } + } + } + } +] + +# queue flags bypass to numgen inc mod 65536 +[ + { + "queue": { + "flags": "bypass", + "num": { + "numgen": { + "mod": 65536, + "mode": "inc", + "offset": 0 + } + } + } + } +] + +# queue to jhash oif . meta mark mod 32 +[ + { + "queue": { + "num": { + "jhash": { + "expr": { + "concat": [ + { + "meta": { + "key": "oif" + } + }, + { + "meta": { + "key": "mark" + } + } + ] + }, + "mod": 32 + } + } + } + } +] + diff --git a/tests/py/any/queue.t.payload b/tests/py/any/queue.t.payload index 78d939c692e9..35e757ee5cf0 100644 --- a/tests/py/any/queue.t.payload +++ b/tests/py/any/queue.t.payload @@ -30,3 +30,19 @@ ip test-ip4 output ip test-ip4 output [ queue num 4-5 bypass ] +# queue to symhash mod 65536 +ip + [ hash reg 1 = symhash() % mod 65536 ] + [ queue sreg_qnum 1 ] + +# queue to jhash oif . meta mark mod 32 +ip + [ meta load oif => reg 2 ] + [ meta load mark => reg 13 ] + [ hash reg 1 = jhash(reg 2, 8, 0x0) % mod 32 ] + [ queue sreg_qnum 1 ] + +# queue flags bypass to numgen inc mod 65536 +ip + [ numgen reg 1 = inc mod 65536 ] + [ queue sreg_qnum 1 bypass ] From patchwork Wed Jun 16 21:16:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Westphal X-Patchwork-Id: 1493095 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4G4yhQ00w3z9sRf for ; Thu, 17 Jun 2021 07:17:57 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233987AbhFPVUE (ORCPT ); Wed, 16 Jun 2021 17:20:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60530 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233836AbhFPVUB (ORCPT ); Wed, 16 Jun 2021 17:20:01 -0400 Received: from Chamillionaire.breakpoint.cc (Chamillionaire.breakpoint.cc [IPv6:2a0a:51c0:0:12e:520::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C6CC8C061574 for ; Wed, 16 Jun 2021 14:17:54 -0700 (PDT) Received: from fw by Chamillionaire.breakpoint.cc with local (Exim 4.92) (envelope-from ) id 1ltcv3-0002VA-9y; Wed, 16 Jun 2021 23:17:53 +0200 From: Florian Westphal To: Cc: jake.owen@superloop.com, Florian Westphal Subject: [PATCH nft 8/8] src: queue: allow use of MAP statement for queue number retrieval Date: Wed, 16 Jun 2021 23:16:52 +0200 Message-Id: <20210616211652.11765-9-fw@strlen.de> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210616211652.11765-1-fw@strlen.de> References: <20210616211652.11765-1-fw@strlen.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org This allows to chose a queue number at run time using map statements, e.g.: queue flags bypass to ip saddr map { 192.168.7/24 : 0, 192.168.0/24 : 1 } Signed-off-by: Florian Westphal --- doc/statements.txt | 6 ++++-- src/parser_bison.y | 1 + tests/py/any/queue.t | 1 + tests/py/any/queue.t.json | 34 ++++++++++++++++++++++++++++++++++ tests/py/any/queue.t.payload | 9 +++++++++ 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/doc/statements.txt b/doc/statements.txt index c2a616594fce..097cf2e07eeb 100644 --- a/doc/statements.txt +++ b/doc/statements.txt @@ -595,11 +595,13 @@ ____ 'QUEUE_FLAGS' := 'QUEUE_FLAG' [*,* 'QUEUE_FLAGS'] 'QUEUE_FLAG' := *bypass* | *fanout* -'QUEUE_EXPRESSION' := *numgen* | *hash* | *symhash* +'QUEUE_EXPRESSION' := *numgen* | *hash* | *symhash* | *MAP STATEMENT* ____ QUEUE_EXPRESSION can be used to compute a queue number -at run-time with the hash or numgen expressions. +at run-time with the hash or numgen expressions. It also +allows to use the map statement to assign fixed queue numbers +based on external inputs such as the source ip address or interface names. .queue statement values [options="header"] diff --git a/src/parser_bison.y b/src/parser_bison.y index d75960715a90..2615db1ba14b 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -3787,6 +3787,7 @@ queue_stmt_expr_simple : integer_expr queue_stmt_expr : numgen_expr | hash_expr + | map_expr ; queue_stmt_flags : queue_stmt_flag diff --git a/tests/py/any/queue.t b/tests/py/any/queue.t index 670dfd92d5b0..446b8b1806f2 100644 --- a/tests/py/any/queue.t +++ b/tests/py/any/queue.t @@ -25,3 +25,4 @@ queue flags bypass to numgen inc mod 65536;ok queue to jhash oif . meta mark mod 32;ok queue to oif;fail queue num oif;fail +queue flags bypass to oifname map { "eth0" : 0, "ppp0" : 2, "eth1" : 2 };ok diff --git a/tests/py/any/queue.t.json b/tests/py/any/queue.t.json index 18ed3c817ac9..162bdff875d6 100644 --- a/tests/py/any/queue.t.json +++ b/tests/py/any/queue.t.json @@ -140,3 +140,37 @@ } ] +# queue flags bypass to oifname map { "eth0" : 0, "ppp0" : 2, "eth1" : 2 } +[ + { + "queue": { + "flags": "bypass", + "num": { + "map": { + "data": { + "set": [ + [ + "eth0", + 0 + ], + [ + "ppp0", + 2 + ], + [ + "eth1", + 2 + ] + ] + }, + "key": { + "meta": { + "key": "oifname" + } + } + } + } + } + } +] + diff --git a/tests/py/any/queue.t.payload b/tests/py/any/queue.t.payload index 35e757ee5cf0..02660afa8d30 100644 --- a/tests/py/any/queue.t.payload +++ b/tests/py/any/queue.t.payload @@ -46,3 +46,12 @@ ip ip [ numgen reg 1 = inc mod 65536 ] [ queue sreg_qnum 1 bypass ] + +# queue flags bypass to oifname map { "eth0" : 0, "ppp0" : 2, "eth1" : 2 } +__map%d test-ip4 b size 3 +__map%d test-ip4 0 + element 30687465 00000000 00000000 00000000 : 00000000 0 [end] element 30707070 00000000 00000000 00000000 : 00000002 0 [end] element 31687465 00000000 00000000 00000000 : 00000002 0 [end] +ip + [ meta load oifname => reg 1 ] + [ lookup reg 1 set __map%d dreg 1 ] + [ queue sreg_qnum 1 bypass ]