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 <p...@nwl.cc>
---
 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to