netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [nft PATCH v2] libnftables: Store top_scope in struct nft_ctx
@ 2019-11-06 14:00 Phil Sutter
  2019-11-06 14:22 ` Phil Sutter
  0 siblings, 1 reply; 6+ messages in thread
From: Phil Sutter @ 2019-11-06 14:00 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

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
| define goodports = { 22, 23, 80, 443 }
| add rule inet t c tcp dport $goodports accept
| add rule inet t c tcp sport $goodports accept

While being at it, introduce scope_alloc() and scope_free().

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
Changes since v1:
- Fix usage example in commit message.
- Add scope_{alloc,free} functions.
---
 include/nftables.h                       |  2 ++
 include/parser.h                         |  4 ++--
 include/rule.h                           |  2 ++
 src/libnftables.c                        |  6 ++++--
 src/parser_bison.y                       |  6 +++---
 src/rule.c                               | 15 +++++++++++++++
 tests/shell/testcases/nft-i/0001define_0 | 22 ++++++++++++++++++++++
 7 files changed, 50 insertions(+), 7 deletions(-)
 create mode 100755 tests/shell/testcases/nft-i/0001define_0

diff --git a/include/nftables.h b/include/nftables.h
index 21553c6bb3a52..90d331960ef29 100644
--- a/include/nftables.h
+++ b/include/nftables.h
@@ -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];
 };
diff --git a/include/parser.h b/include/parser.h
index 39a752121a6b8..949284d9466c6 100644
--- a/include/parser.h
+++ b/include/parser.h
@@ -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);
diff --git a/include/rule.h b/include/rule.h
index a718923b14a36..44bf1a4546ce0 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -97,8 +97,10 @@ struct scope {
 	struct list_head	symbols;
 };
 
+extern struct scope *scope_alloc(void);
 extern struct scope *scope_init(struct scope *scope, const struct scope *parent);
 extern void scope_release(const struct scope *scope);
+extern void scope_free(struct scope *scope);
 
 /**
  * struct symbol
diff --git a/src/libnftables.c b/src/libnftables.c
index e20372438db62..cd2fcf2fd5221 100644
--- a/src/libnftables.c
+++ b/src/libnftables.c
@@ -155,6 +155,7 @@ 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 = scope_alloc();
 	ctx->flags = flags;
 	ctx->output.output_fp = stdout;
 	ctx->output.error_fp = stderr;
@@ -292,6 +293,7 @@ void nft_ctx_free(struct nft_ctx *ctx)
 	iface_cache_release();
 	cache_release(&ctx->cache);
 	nft_ctx_clear_include_paths(ctx);
+	scope_free(ctx->top_scope);
 	xfree(ctx->state);
 	nft_exit(ctx);
 	xfree(ctx);
@@ -368,7 +370,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 +386,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;
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 6f525d5b85240..3f2832564036e 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -42,13 +42,13 @@
 #include "parser_bison.h"
 
 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)
 {
 	memset(state, 0, sizeof(*state));
-	init_list_head(&state->top_scope.symbols);
 	state->msgs = msgs;
 	state->cmds = cmds;
-	state->scopes[0] = scope_init(&state->top_scope, NULL);
+	state->scopes[0] = scope_init(top_scope, NULL);
 	init_list_head(&state->indesc_list);
 }
 
diff --git a/src/rule.c b/src/rule.c
index ff9e8e6c0e57c..ef6a14751af5c 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -646,6 +646,15 @@ struct rule *rule_lookup_by_index(const struct chain *chain, uint64_t index)
 	return NULL;
 }
 
+struct scope *scope_alloc(void)
+{
+	struct scope *scope = xzalloc(sizeof(struct scope));
+
+	init_list_head(&scope->symbols);
+
+	return scope;
+}
+
 struct scope *scope_init(struct scope *scope, const struct scope *parent)
 {
 	scope->parent = parent;
@@ -665,6 +674,12 @@ void scope_release(const struct scope *scope)
 	}
 }
 
+void scope_free(struct scope *scope)
+{
+	scope_release(scope);
+	xfree(scope);
+}
+
 void symbol_bind(struct scope *scope, const char *identifier, struct expr *expr)
 {
 	struct symbol *sym;
diff --git a/tests/shell/testcases/nft-i/0001define_0 b/tests/shell/testcases/nft-i/0001define_0
new file mode 100755
index 0000000000000..62e1b6dede21d
--- /dev/null
+++ b/tests/shell/testcases/nft-i/0001define_0
@@ -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
-- 
2.24.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [nft PATCH v2] libnftables: Store top_scope in struct nft_ctx
  2019-11-06 14:00 [nft PATCH v2] libnftables: Store top_scope in struct nft_ctx Phil Sutter
@ 2019-11-06 14:22 ` Phil Sutter
  2019-11-07  9:41   ` Pablo Neira Ayuso
  0 siblings, 1 reply; 6+ messages in thread
From: Phil Sutter @ 2019-11-06 14:22 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

On Wed, Nov 06, 2019 at 03:00:01PM +0100, Phil Sutter wrote:
> 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
> | define goodports = { 22, 23, 80, 443 }
> | add rule inet t c tcp dport $goodports accept
> | add rule inet t c tcp sport $goodports accept
> 
> While being at it, introduce scope_alloc() and scope_free().
> 
> Signed-off-by: Phil Sutter <phil@nwl.cc>
> ---
> Changes since v1:
> - Fix usage example in commit message.
> - Add scope_{alloc,free} functions.

Minor correction, this is actually v3 and above are the changes since
v2. /o\

Sorry for the mess,

Phil

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [nft PATCH v2] libnftables: Store top_scope in struct nft_ctx
  2019-11-06 14:22 ` Phil Sutter
@ 2019-11-07  9:41   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 6+ messages in thread
From: Pablo Neira Ayuso @ 2019-11-07  9:41 UTC (permalink / raw)
  To: Phil Sutter, netfilter-devel

On Wed, Nov 06, 2019 at 03:22:32PM +0100, Phil Sutter wrote:
> On Wed, Nov 06, 2019 at 03:00:01PM +0100, Phil Sutter wrote:
> > 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
> > | define goodports = { 22, 23, 80, 443 }
> > | add rule inet t c tcp dport $goodports accept
> > | add rule inet t c tcp sport $goodports accept
> > 
> > While being at it, introduce scope_alloc() and scope_free().
> > 
> > Signed-off-by: Phil Sutter <phil@nwl.cc>
> > ---
> > Changes since v1:
> > - Fix usage example in commit message.
> > - Add scope_{alloc,free} functions.
> 
> Minor correction, this is actually v3 and above are the changes since
> v2. /o\

For this v3.

Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [nft PATCH v2] libnftables: Store top_scope in struct nft_ctx
  2019-11-06 12:40 ` Pablo Neira Ayuso
@ 2019-11-06 14:00   ` Phil Sutter
  0 siblings, 0 replies; 6+ messages in thread
From: Phil Sutter @ 2019-11-06 14:00 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

Hi Pablo,

On Wed, Nov 06, 2019 at 01:40:17PM +0100, Pablo Neira Ayuso wrote:
> On Wed, Oct 30, 2019 at 10:28:54PM +0100, Phil Sutter wrote:
> > 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 }
>    ^
> 'define' is missing here, right?

Oh yes, of course.

> > | 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>
> 
> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
> 
> One more comment, possible follow up, just an idea.

Added those, sent v2 just to be sure.

Thanks, Phil

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [nft PATCH v2] libnftables: Store top_scope in struct nft_ctx
  2019-10-30 21:28 Phil Sutter
@ 2019-11-06 12:40 ` Pablo Neira Ayuso
  2019-11-06 14:00   ` Phil Sutter
  0 siblings, 1 reply; 6+ messages in thread
From: Pablo Neira Ayuso @ 2019-11-06 12:40 UTC (permalink / raw)
  To: Phil Sutter; +Cc: netfilter-devel

On Wed, Oct 30, 2019 at 10:28:54PM +0100, Phil Sutter wrote:
> 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 }
   ^
'define' is missing here, right?

> | 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>

Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>

One more comment, possible follow up, just an idea.

> diff --git a/src/libnftables.c b/src/libnftables.c
> index e20372438db62..7c35e898d87ab 100644
> --- a/src/libnftables.c
> +++ b/src/libnftables.c
> @@ -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);

Probably add scope_alloc()

>  	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);

and scope_free().

>  	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;
> diff --git a/src/parser_bison.y b/src/parser_bison.y
> index 7f9b1752f41d4..b73cf3bcfb209 100644
> --- a/src/parser_bison.y
> +++ b/src/parser_bison.y
> @@ -42,13 +42,13 @@
>  #include "parser_bison.h"
>  
>  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)
>  {
>  	memset(state, 0, sizeof(*state));
> -	init_list_head(&state->top_scope.symbols);
>  	state->msgs = msgs;
>  	state->cmds = cmds;
> -	state->scopes[0] = scope_init(&state->top_scope, NULL);
> +	state->scopes[0] = scope_init(top_scope, NULL);
>  	init_list_head(&state->indesc_list);
>  }
>  
> diff --git a/tests/shell/testcases/nft-i/0001define_0 b/tests/shell/testcases/nft-i/0001define_0
> new file mode 100755
> index 0000000000000..62e1b6dede21d
> --- /dev/null
> +++ b/tests/shell/testcases/nft-i/0001define_0
> @@ -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
> -- 
> 2.23.0
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [nft PATCH v2] libnftables: Store top_scope in struct nft_ctx
@ 2019-10-30 21:28 Phil Sutter
  2019-11-06 12:40 ` Pablo Neira Ayuso
  0 siblings, 1 reply; 6+ messages in thread
From: Phil Sutter @ 2019-10-30 21:28 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

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>
---
Changes since v1:
- Add missing chunk in src/parser_bison.y. Apparently I managed to edit
  src/parser_bison.c which works perfectly fine until one calls 'make
  clean'.
---
 include/nftables.h                       |  2 ++
 include/parser.h                         |  4 ++--
 src/libnftables.c                        |  8 ++++++--
 src/parser_bison.y                       |  6 +++---
 tests/shell/testcases/nft-i/0001define_0 | 22 ++++++++++++++++++++++
 5 files changed, 35 insertions(+), 7 deletions(-)
 create mode 100755 tests/shell/testcases/nft-i/0001define_0

diff --git a/include/nftables.h b/include/nftables.h
index 21553c6bb3a52..90d331960ef29 100644
--- a/include/nftables.h
+++ b/include/nftables.h
@@ -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];
 };
diff --git a/include/parser.h b/include/parser.h
index 39a752121a6b8..949284d9466c6 100644
--- a/include/parser.h
+++ b/include/parser.h
@@ -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);
diff --git a/src/libnftables.c b/src/libnftables.c
index e20372438db62..7c35e898d87ab 100644
--- a/src/libnftables.c
+++ b/src/libnftables.c
@@ -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;
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 7f9b1752f41d4..b73cf3bcfb209 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -42,13 +42,13 @@
 #include "parser_bison.h"
 
 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)
 {
 	memset(state, 0, sizeof(*state));
-	init_list_head(&state->top_scope.symbols);
 	state->msgs = msgs;
 	state->cmds = cmds;
-	state->scopes[0] = scope_init(&state->top_scope, NULL);
+	state->scopes[0] = scope_init(top_scope, NULL);
 	init_list_head(&state->indesc_list);
 }
 
diff --git a/tests/shell/testcases/nft-i/0001define_0 b/tests/shell/testcases/nft-i/0001define_0
new file mode 100755
index 0000000000000..62e1b6dede21d
--- /dev/null
+++ b/tests/shell/testcases/nft-i/0001define_0
@@ -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
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2019-11-07  9:41 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-06 14:00 [nft PATCH v2] libnftables: Store top_scope in struct nft_ctx Phil Sutter
2019-11-06 14:22 ` Phil Sutter
2019-11-07  9:41   ` Pablo Neira Ayuso
  -- strict thread matches above, loose matches on Subject: below --
2019-10-30 21:28 Phil Sutter
2019-11-06 12:40 ` Pablo Neira Ayuso
2019-11-06 14:00   ` Phil Sutter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).