[nft PATCH 11/12] libnftables: Keep cmds list outside of parser_state

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Parser basically turns input into a list of commands and error messages.
Having the commands list being part of struct parser_state does not make
sense from this point of view, also it will have to go away with
upcoming JSON support anyway.

While being at it, change nft_netlink() to take just the list of
commands instead of the whole parser state as parameter, also take care
of command freeing in nft_run_cmd_from_* functions (where the list
resides as auto-variable) instead of from inside nft_run().

Signed-off-by: Phil Sutter <phil@xxxxxx>
---
 include/parser.h   |  5 +++--
 src/libnftables.c  | 35 +++++++++++++++++++++--------------
 src/parser_bison.y |  9 +++++----
 3 files changed, 29 insertions(+), 20 deletions(-)

diff --git a/include/parser.h b/include/parser.h
index 0bdb3fa8225c0..7961275742bc2 100644
--- a/include/parser.h
+++ b/include/parser.h
@@ -25,7 +25,7 @@ struct parser_state {
 	struct scope			*scopes[SCOPE_NEST_MAX];
 	unsigned int			scope;
 
-	struct list_head		cmds;
+	struct list_head		*cmds;
 	struct eval_ctx			ectx;
 };
 
@@ -33,7 +33,8 @@ struct mnl_socket;
 
 extern void parser_init(struct mnl_socket *nf_sock, struct nft_cache *cache,
 			struct parser_state *state, struct list_head *msgs,
-			unsigned int debug_level, struct output_ctx *octx);
+			struct list_head *cmds, unsigned int debug_level,
+			struct output_ctx *octx);
 extern int nft_parse(struct nft_ctx *ctx, void *, struct parser_state *state);
 
 extern void *scanner_init(struct parser_state *state);
diff --git a/src/libnftables.c b/src/libnftables.c
index cd356250df869..56a98ab1aaefe 100644
--- a/src/libnftables.c
+++ b/src/libnftables.c
@@ -18,7 +18,7 @@
 #include <string.h>
 
 static int nft_netlink(struct nft_ctx *nft,
-		       struct parser_state *state, struct list_head *msgs,
+		       struct list_head *cmds, struct list_head *msgs,
 		       struct mnl_socket *nf_sock)
 {
 	uint32_t batch_seqnum, seqnum = 0;
@@ -29,13 +29,13 @@ static int nft_netlink(struct nft_ctx *nft,
 	LIST_HEAD(err_list);
 	int ret = 0;
 
-	if (list_empty(&state->cmds))
+	if (list_empty(cmds))
 		return 0;
 
 	batch = mnl_batch_init();
 
 	batch_seqnum = mnl_batch_begin(batch, mnl_seqnum_alloc(&seqnum));
-	list_for_each_entry(cmd, &state->cmds, list) {
+	list_for_each_entry(cmd, cmds, list) {
 		memset(&ctx, 0, sizeof(ctx));
 		ctx.msgs = msgs;
 		ctx.seqnum = cmd->seqnum = mnl_seqnum_alloc(&seqnum);
@@ -58,7 +58,7 @@ static int nft_netlink(struct nft_ctx *nft,
 	ret = netlink_batch_send(&ctx, &err_list);
 
 	list_for_each_entry_safe(err, tmp, &err_list, head) {
-		list_for_each_entry(cmd, &state->cmds, list) {
+		list_for_each_entry(cmd, cmds, list) {
 			if (err->seqnum == cmd->seqnum ||
 			    err->seqnum == batch_seqnum) {
 				netlink_io_error(&ctx, &cmd->location,
@@ -81,7 +81,7 @@ static int nft_run(struct nft_ctx *nft, struct mnl_socket *nf_sock,
 		   void *scanner, struct parser_state *state,
 		   struct list_head *msgs)
 {
-	struct cmd *cmd, *next;
+	struct cmd *cmd;
 	int ret;
 
 	ret = nft_parse(nft, scanner, state);
@@ -90,16 +90,11 @@ static int nft_run(struct nft_ctx *nft, struct mnl_socket *nf_sock,
 		goto err1;
 	}
 
-	list_for_each_entry(cmd, &state->cmds, list)
+	list_for_each_entry(cmd, state->cmds, list)
 		nft_cmd_expand(cmd);
 
-	ret = nft_netlink(nft, state, msgs, nf_sock);
+	ret = nft_netlink(nft, state->cmds, msgs, nf_sock);
 err1:
-	list_for_each_entry_safe(cmd, next, &state->cmds, list) {
-		list_del(&cmd->list);
-		cmd_free(cmd);
-	}
-
 	return ret;
 }
 
@@ -402,7 +397,9 @@ int nft_run_cmd_from_buffer(struct nft_ctx *nft, char *buf, size_t buflen)
 {
 	int rc = 0;
 	struct parser_state state;
+	struct cmd *cmd, *next;
 	LIST_HEAD(msgs);
+	LIST_HEAD(cmds);
 	size_t nlbuflen;
 	void *scanner;
 	char *nlbuf;
@@ -412,13 +409,17 @@ int nft_run_cmd_from_buffer(struct nft_ctx *nft, char *buf, size_t buflen)
 	snprintf(nlbuf, nlbuflen, "%s\n", buf);
 
 	parser_init(nft->nf_sock, &nft->cache, &state,
-		    &msgs, nft->debug_mask, &nft->output);
+		    &msgs, &cmds, nft->debug_mask, &nft->output);
 	scanner = scanner_init(&state);
 	scanner_push_buffer(scanner, &indesc_cmdline, nlbuf);
 
 	if (nft_run(nft, nft->nf_sock, scanner, &state, &msgs) != 0)
 		rc = -1;
 
+	list_for_each_entry_safe(cmd, next, &cmds, list) {
+		list_del(&cmd->list);
+		cmd_free(cmd);
+	}
 	erec_print_list(&nft->output, &msgs, nft->debug_mask);
 	scanner_destroy(scanner);
 	iface_cache_release();
@@ -430,7 +431,9 @@ int nft_run_cmd_from_buffer(struct nft_ctx *nft, char *buf, size_t buflen)
 int nft_run_cmd_from_filename(struct nft_ctx *nft, const char *filename)
 {
 	struct parser_state state;
+	struct cmd *cmd, *next;
 	LIST_HEAD(msgs);
+	LIST_HEAD(cmds);
 	void *scanner;
 	int rc;
 
@@ -443,7 +446,7 @@ int nft_run_cmd_from_filename(struct nft_ctx *nft, const char *filename)
 		filename = "/dev/stdin";
 
 	parser_init(nft->nf_sock, &nft->cache, &state,
-		    &msgs, nft->debug_mask, &nft->output);
+		    &msgs, &cmds, nft->debug_mask, &nft->output);
 	scanner = scanner_init(&state);
 	if (scanner_read_file(scanner, filename, &internal_location) < 0) {
 		rc = -1;
@@ -453,6 +456,10 @@ int nft_run_cmd_from_filename(struct nft_ctx *nft, const char *filename)
 	if (nft_run(nft, nft->nf_sock, scanner, &state, &msgs) != 0)
 		rc = -1;
 err:
+	list_for_each_entry_safe(cmd, next, &cmds, list) {
+		list_del(&cmd->list);
+		cmd_free(cmd);
+	}
 	erec_print_list(&nft->output, &msgs, nft->debug_mask);
 	scanner_destroy(scanner);
 	iface_cache_release();
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 93346d76e2ef5..1ca5d4048c288 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -38,12 +38,13 @@
 
 void parser_init(struct mnl_socket *nf_sock, struct nft_cache *cache,
 		 struct parser_state *state, struct list_head *msgs,
-		 unsigned int debug_mask, struct output_ctx *octx)
+		 struct list_head *cmds, unsigned int debug_mask,
+		 struct output_ctx *octx)
 {
 	memset(state, 0, sizeof(*state));
-	init_list_head(&state->cmds);
 	init_list_head(&state->top_scope.symbols);
 	state->msgs = msgs;
+	state->cmds = cmds;
 	state->scopes[0] = scope_init(&state->top_scope, NULL);
 	state->ectx.cache = cache;
 	state->ectx.msgs = msgs;
@@ -748,7 +749,7 @@ input			:	/* empty */
 						if (++state->nerrs == nft->parser_max_errors)
 							YYABORT;
 					} else
-						list_splice_tail(&list, &state->cmds);
+						list_splice_tail(&list, state->cmds);
 				}
 			}
 			;
@@ -834,7 +835,7 @@ line			:	common_block			{ $$ = NULL; }
 						if (++state->nerrs == nft->parser_max_errors)
 							YYABORT;
 					} else
-						list_splice_tail(&list, &state->cmds);
+						list_splice_tail(&list, state->cmds);
 				}
 				if (state->nerrs)
 					YYABORT;
-- 
2.16.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux