summaryrefslogtreecommitdiffstats
path: root/src/libnftables.c
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2018-05-15 11:37:56 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2018-05-15 12:16:42 +0200
commitbd82e03e15df882497eee46e4ba5db1442d88248 (patch)
tree3467189ed58eaa4b2c809ea28f9f94b4bceebbba /src/libnftables.c
parentfbc0768cb69686d00035456f1e9e0613927b1d4f (diff)
libnftables: Move scanner object into struct nft_ctx
The initial approach of keeping as much of lex/yacc-specific data local to the relevant parsing routines was flawed in that input descriptors which parsed commands' location information points at were freed after parsing (in scanner_destroy()) although they were required later for error reporting in case a command was rejected by the kernel. To overcome this, keep the scanner pointer in struct nft_ctx so that it can be kept in place until kernel communication has finished. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/libnftables.c')
-rw-r--r--src/libnftables.c43
1 files changed, 21 insertions, 22 deletions
diff --git a/src/libnftables.c b/src/libnftables.c
index d9b2c081..5bc7ba0d 100644
--- a/src/libnftables.c
+++ b/src/libnftables.c
@@ -398,24 +398,20 @@ static int nft_parse_bison_buffer(struct nft_ctx *nft, char *buf, size_t buflen,
struct list_head *msgs, struct list_head *cmds)
{
struct cmd *cmd;
- void *scanner;
int ret;
parser_init(nft, nft->state, msgs, cmds);
- scanner = scanner_init(nft->state);
- scanner_push_buffer(scanner, &indesc_cmdline, buf);
+ nft->scanner = scanner_init(nft->state);
+ scanner_push_buffer(nft->scanner, &indesc_cmdline, buf);
+
+ ret = nft_parse(nft, nft->scanner, nft->state);
+ if (ret != 0 || nft->state->nerrs > 0)
+ return -1;
- ret = nft_parse(nft, scanner, nft->state);
- if (ret != 0 || nft->state->nerrs > 0) {
- ret = -1;
- goto err;
- }
list_for_each_entry(cmd, cmds, list)
nft_cmd_expand(cmd);
-err:
- scanner_destroy(scanner);
- return ret;
+ return 0;
}
static int nft_parse_bison_filename(struct nft_ctx *nft, const char *filename,
@@ -427,22 +423,17 @@ static int nft_parse_bison_filename(struct nft_ctx *nft, const char *filename,
parser_init(nft, nft->state, msgs, cmds);
scanner = scanner_init(nft->state);
- if (scanner_read_file(scanner, filename, &internal_location) < 0) {
- ret = -1;
- goto err;
- }
+ if (scanner_read_file(scanner, filename, &internal_location) < 0)
+ return -1;
ret = nft_parse(nft, scanner, nft->state);
- if (ret != 0 || nft->state->nerrs > 0) {
- ret = -1;
- goto err;
- }
+ if (ret != 0 || nft->state->nerrs > 0)
+ return -1;
+
list_for_each_entry(cmd, cmds, list)
nft_cmd_expand(cmd);
-err:
- scanner_destroy(scanner);
- return ret;
+ return 0;
}
int nft_run_cmd_from_buffer(struct nft_ctx *nft, char *buf, size_t buflen)
@@ -474,6 +465,10 @@ err:
}
erec_print_list(&nft->output, &msgs, nft->debug_mask);
iface_cache_release();
+ if (nft->scanner) {
+ scanner_destroy(nft->scanner);
+ nft->scanner = NULL;
+ }
free(nlbuf);
return rc;
@@ -511,6 +506,10 @@ err:
}
erec_print_list(&nft->output, &msgs, nft->debug_mask);
iface_cache_release();
+ if (nft->scanner) {
+ scanner_destroy(nft->scanner);
+ nft->scanner = NULL;
+ }
return rc;
}