@@ -104,6 +104,7 @@ struct nft_cache {
struct mnl_socket;
struct parser_state;
+struct scope;
#define MAX_INCLUDE_DEPTH 16
@@ -119,6 +120,7 @@ struct nft_ctx {
uint32_t flags;
struct parser_state *state;
void *scanner;
+ struct scope *top_scope;
void *json_root;
FILE *f[MAX_INCLUDE_DEPTH];
};
@@ -22,7 +22,6 @@ struct parser_state {
struct list_head *msgs;
unsigned int nerrs;
- struct scope top_scope;
struct scope *scopes[SCOPE_NEST_MAX];
unsigned int scope;
@@ -32,7 +31,8 @@ struct parser_state {
struct mnl_socket;
extern void parser_init(struct nft_ctx *nft, struct parser_state *state,
- struct list_head *msgs, struct list_head *cmds);
+ struct list_head *msgs, struct list_head *cmds,
+ struct scope *top_scope);
extern int nft_parse(struct nft_ctx *ctx, void *, struct parser_state *state);
extern void *scanner_init(struct parser_state *state);
@@ -155,6 +155,8 @@ struct nft_ctx *nft_ctx_new(uint32_t flags)
nft_ctx_add_include_path(ctx, DEFAULT_INCLUDE_PATH);
ctx->parser_max_errors = 10;
init_list_head(&ctx->cache.list);
+ ctx->top_scope = xzalloc(sizeof(struct scope));
+ init_list_head(&ctx->top_scope->symbols);
ctx->flags = flags;
ctx->output.output_fp = stdout;
ctx->output.error_fp = stderr;
@@ -292,6 +294,8 @@ void nft_ctx_free(struct nft_ctx *ctx)
iface_cache_release();
cache_release(&ctx->cache);
nft_ctx_clear_include_paths(ctx);
+ scope_release(ctx->top_scope);
+ xfree(ctx->top_scope);
xfree(ctx->state);
nft_exit(ctx);
xfree(ctx);
@@ -368,7 +372,7 @@ static int nft_parse_bison_buffer(struct nft_ctx *nft, const char *buf,
{
int ret;
- parser_init(nft, nft->state, msgs, cmds);
+ parser_init(nft, nft->state, msgs, cmds, nft->top_scope);
nft->scanner = scanner_init(nft->state);
scanner_push_buffer(nft->scanner, &indesc_cmdline, buf);
@@ -384,7 +388,7 @@ static int nft_parse_bison_filename(struct nft_ctx *nft, const char *filename,
{
int ret;
- parser_init(nft, nft->state, msgs, cmds);
+ parser_init(nft, nft->state, msgs, cmds, nft->top_scope);
nft->scanner = scanner_init(nft->state);
if (scanner_read_file(nft, filename, &internal_location) < 0)
return -1;
new file mode 100755
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+set -e
+
+# test if using defines in interactive nft sessions works
+
+$NFT -i >/dev/null <<EOF
+add table inet t
+add chain inet t c
+define ports = { 22, 443 }
+add rule inet t c tcp dport \$ports accept
+add rule inet t c udp dport \$ports accept
+EOF
+
+$NFT -i >/dev/null <<EOF
+define port = 22
+flush chain inet t c
+redefine port = 443
+delete chain inet t c
+undefine port
+delete table inet t
+EOF
Allow for interactive sessions to make use of defines. Since parser is initialized for each line, top scope defines didn't persist although they are actually useful for stuff like: | # nft -i | goodports = { 22, 23, 80, 443 } | add rule inet t c tcp dport $goodports accept | add rule inet t c tcp sport $goodports accept Signed-off-by: Phil Sutter <phil@nwl.cc> --- include/nftables.h | 2 ++ include/parser.h | 4 ++-- src/libnftables.c | 8 ++++++-- tests/shell/testcases/nft-i/0001define_0 | 22 ++++++++++++++++++++++ 4 files changed, 32 insertions(+), 4 deletions(-) create mode 100755 tests/shell/testcases/nft-i/0001define_0