Linux Netfilter development
 help / color / mirror / Atom feed
From: Pablo Neira Ayuso <pablo@netfilter.org>
To: netfilter-devel@vger.kernel.org
Cc: phil@nwl.cc
Subject: [PATCH nft,v2 4/5] src: allow reset commands in batch with list and get commands only
Date: Tue, 23 Jun 2026 19:21:27 +0200	[thread overview]
Message-ID: <20260623172128.401234-5-pablo@netfilter.org> (raw)
In-Reply-To: <20260623172128.401234-1-pablo@netfilter.org>

Currently, only single reset command is working properly, but more than
one fail because of the existing cache logic. Bail out in case user
mixes reset commands.

The reset command is special because it provides no transaction
semantics, like the list command. Allowing the use of the reset command
in conjunction with other commands require an implicit end of batch /
commit command.

Allow a batch that contains reset commands with list and get command
by now.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/cmd.h      |  2 ++
 src/cmd.c          | 37 +++++++++++++++++++++++++++++++++++++
 src/parser_bison.y | 12 ++++++++++--
 src/parser_json.c  |  8 ++++----
 4 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/include/cmd.h b/include/cmd.h
index cf7e43bf46ec..a457364aeeeb 100644
--- a/include/cmd.h
+++ b/include/cmd.h
@@ -11,4 +11,6 @@ bool nft_cmd_collapse_elems(enum cmd_ops op, struct list_head *cmds,
 
 void nft_cmd_expand(struct cmd *cmd);
 
+int cmd_batch_add(struct cmd *cmd, struct list_head *cmds);
+
 #endif
diff --git a/src/cmd.c b/src/cmd.c
index 9d5544f03c32..7ee2176191b1 100644
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -489,3 +489,40 @@ void nft_cmd_expand(struct cmd *cmd)
 		break;
 	}
 }
+
+static bool cmd_valid_mix(const struct cmd *cmd, const struct cmd *last_cmd)
+{
+	switch (cmd->op) {
+	case CMD_RESET:
+		if (last_cmd->op == CMD_RESET ||
+		    last_cmd->op == CMD_LIST ||
+		    last_cmd->op == CMD_GET)
+			return true;
+
+		return false;
+	case CMD_LIST:
+	case CMD_GET:
+		return true;
+	default:
+		if (last_cmd->op == CMD_RESET)
+			return false;
+		break;
+	}
+
+	return true;
+}
+
+int cmd_batch_add(struct cmd *cmd, struct list_head *cmds)
+{
+	struct cmd *last_cmd;
+	int ret = 0;
+
+	if (!list_empty(cmds)) {
+		last_cmd = list_last_entry(cmds, struct cmd, list);
+		if (!cmd_valid_mix(cmd, last_cmd))
+			ret = -1;
+	}
+	list_add_tail(&cmd->list, cmds);
+
+	return ret;
+}
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 5a334bf0c499..48151a419096 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -1073,7 +1073,11 @@ input			:	/* empty */
 			{
 				if ($2 != NULL) {
 					$2->location = @2;
-					list_add_tail(&$2->list, state->cmds);
+					if (cmd_batch_add($2, state->cmds) < 0) {
+						erec_queue(error(&@2, "unsupported command mix"),
+							   state->msgs);
+						YYERROR;
+					}
 				}
 			}
 			;
@@ -1210,7 +1214,11 @@ line			:	common_block			{ $$ = NULL; }
 				 */
 				if ($1 != NULL) {
 					$1->location = @1;
-					list_add_tail(&$1->list, state->cmds);
+					if (cmd_batch_add($1, state->cmds) < 0) {
+						erec_queue(error(&@2, "unsupported command mix"),
+							   state->msgs);
+						YYERROR;
+					}
 				}
 				$$ = NULL;
 				YYACCEPT;
diff --git a/src/parser_json.c b/src/parser_json.c
index f04772a022a0..47acc200ad83 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -4492,7 +4492,6 @@ static int __json_parse(struct json_ctx *ctx)
 
 	json_array_foreach(tmp, index, value) {
 		/* this is more or less from parser_bison.y:716 */
-		LIST_HEAD(list);
 		struct cmd *cmd;
 		json_t *tmp2;
 
@@ -4522,9 +4521,10 @@ static int __json_parse(struct json_ctx *ctx)
 			return -1;
 		}
 
-		list_add_tail(&cmd->list, &list);
-
-		list_splice_tail(&list, ctx->cmds);
+		if (cmd_batch_add(cmd, ctx->cmds) < 0) {
+			json_error(ctx, "unsupported command mix");
+			return -1;
+		}
 
 		if (nft_output_echo(&ctx->nft->output))
 			json_cmd_assoc_add(value, cmd);
-- 
2.47.3


  parent reply	other threads:[~2026-06-23 17:21 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-23 17:21 [PATCH nft,v2 0/5] support for several list and reset commands Pablo Neira Ayuso
2026-06-23 17:21 ` [PATCH nft,v2 1/5] libnftables: add nft_run_cmd_release() helper and use it Pablo Neira Ayuso
2026-06-23 17:21 ` [PATCH nft,v2 2/5] libnftables: split nft_run_cmd_from_buffer() in helper functions Pablo Neira Ayuso
2026-06-23 17:21 ` [PATCH nft,v2 3/5] libnftables: use nft_run_cmds() in nft_run_cmd_from_filename() Pablo Neira Ayuso
2026-06-23 17:21 ` Pablo Neira Ayuso [this message]
2026-06-23 17:21 ` [PATCH nft,v2 5/5] libnftables: support for several reset commands Pablo Neira Ayuso

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260623172128.401234-5-pablo@netfilter.org \
    --to=pablo@netfilter.org \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=phil@nwl.cc \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox