[nftables] Add support for scoping and symbol binding

Patrick McHardy netfilter-cvslog-bounces at lists.netfilter.org
Fri Mar 20 08:26:05 CET 2009


Gitweb:		http://git.netfilter.org/cgi-bin/gitweb.cgi?p=nftables.git;a=commit;h=5c40780440c0e8661fc7cfcec72dab48b934631d
commit 5c40780440c0e8661fc7cfcec72dab48b934631d
Author:     Patrick McHardy <kaber at trash.net>
AuthorDate: Fri Mar 20 08:12:18 2009 +0100
Commit:     Patrick McHardy <kaber at trash.net>
CommitDate: Fri Mar 20 08:12:18 2009 +0100

    Add support for scoping and symbol binding
    
    As a first step towards stand-alone sets, add support for scoping and
    binding symbols. This will be used for user-defined constants, as well
    as declarations of modifiable (stand-alone) sets once the kernel side
    is ready.
    
    Scopes are currently limited to three nesting levels: the global scope,
    table block scopes and chain block scopes.
    
    Signed-off-by: Patrick McHardy <kaber at trash.net>
       via  5c40780440c0e8661fc7cfcec72dab48b934631d (commit)
      from  2ae0ab5fb3eabc149bad1250c681a7a5f2aea694 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 5c40780440c0e8661fc7cfcec72dab48b934631d
Author: Patrick McHardy <kaber at trash.net>
Date:   Fri Mar 20 08:12:18 2009 +0100

    Add support for scoping and symbol binding
    
    As a first step towards stand-alone sets, add support for scoping and
    binding symbols. This will be used for user-defined constants, as well
    as declarations of modifiable (stand-alone) sets once the kernel side
    is ready.
    
    Scopes are currently limited to three nesting levels: the global scope,
    table block scopes and chain block scopes.
    
    Signed-off-by: Patrick McHardy <kaber at trash.net>

-----------------------------------------------------------------------

 include/parser.h |    8 ++++++++
 include/rule.h   |   33 +++++++++++++++++++++++++++++++++
 src/parser.y     |   32 ++++++++++++++++++++++++++++++--
 src/rule.c       |   32 ++++++++++++++++++++++++++++++++
 4 files changed, 103 insertions(+), 2 deletions(-)
As a first step towards stand-alone sets, add support for scoping and
binding symbols. This will be used for user-defined constants, as well
as declarations of modifiable (stand-alone) sets once the kernel side
is ready.

Scopes are currently limited to three nesting levels: the global scope,
table block scopes and chain block scopes.

Signed-off-by: Patrick McHardy <kaber at trash.net>

diff --git a/include/parser.h b/include/parser.h
index a47bd0f..f5dd6f4 100644
--- a/include/parser.h
+++ b/include/parser.h
@@ -2,6 +2,7 @@
 #define NFTABLES_PARSER_H
 
 #include <list.h>
+#include <rule.h> // FIXME
 
 #define MAX_INCLUDE_DEPTH		16
 #define TABSIZE				8
@@ -10,12 +11,19 @@
 #define YYLTYPE_IS_TRIVIAL		0
 #define YYENABLE_NLS			0
 
+#define SCOPE_NEST_MAX			3
+
 struct parser_state {
 	struct input_descriptor		*indesc;
 	struct input_descriptor		indescs[MAX_INCLUDE_DEPTH];
 	unsigned int			indesc_idx;
 
 	struct list_head		*msgs;
+
+	struct scope			top_scope;
+	struct scope			*scopes[SCOPE_NEST_MAX];
+	unsigned int			scope;
+
 	struct list_head		cmds;
 };
 
diff --git a/include/rule.h b/include/rule.h
index 991d112..4e5da06 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -24,6 +24,37 @@ extern void handle_merge(struct handle *dst, const struct handle *src);
 extern void handle_free(struct handle *h);
 
 /**
+ * struct scope
+ *
+ * @parent:	pointer to parent scope
+ * @symbols:	symbols bound in the scope
+ */
+struct scope {
+	const struct scope	*parent;
+	struct list_head	symbols;
+};
+
+extern struct scope *scope_init(struct scope *scope, const struct scope *parent);
+
+/**
+ * struct symbol
+ *
+ * @list:	scope symbol list node
+ * @identifier:	identifier
+ * @expr:	initializer
+ */
+struct symbol {
+	struct list_head	list;
+	const char		*identifier;
+	struct expr		*expr;
+};
+
+extern void symbol_bind(struct scope *scope, const char *identifier,
+			struct expr *expr);
+extern struct symbol *symbol_lookup(const struct scope *scope,
+				    const char *identifier);
+
+/**
  * struct table - nftables table
  *
  * @list:	list node
@@ -33,6 +64,7 @@ extern void handle_free(struct handle *h);
 struct table {
 	struct list_head	list;
 	struct handle		handle;
+	struct scope		scope;
 	struct list_head	chains;
 };
 
@@ -55,6 +87,7 @@ struct chain {
 	struct handle		handle;
 	unsigned int		hooknum;
 	unsigned int		priority;
+	struct scope		scope;
 	struct list_head	rules;
 };
 
diff --git a/src/parser.y b/src/parser.y
index b13e932..1ca5981 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -33,6 +33,7 @@ void parser_init(struct parser_state *state, struct list_head *msgs)
 	memset(state, 0, sizeof(*state));
 	init_list_head(&state->cmds);
 	state->msgs = msgs;
+	state->scopes[0] = scope_init(&state->top_scope, NULL);
 }
 
 static void yyerror(struct location *loc, void *scanner,
@@ -41,6 +42,22 @@ static void yyerror(struct location *loc, void *scanner,
 	erec_queue(error(loc, "%s", s), state->msgs);
 }
 
+static struct scope *current_scope(const struct parser_state *state)
+{
+	return state->scopes[state->scope];
+}
+
+static void open_scope(struct parser_state *state, struct scope *scope)
+{
+	scope_init(scope, current_scope(state));
+	state->scopes[++state->scope] = scope;
+}
+
+static void close_scope(struct parser_state *state)
+{
+	state->scope--;
+}
+
 static void location_init(void *scanner, struct parser_state *state,
 			  struct location *loc)
 {
@@ -474,6 +491,7 @@ add_cmd			:	TABLE		table_spec
 						'{'	table_block	'}'
 			{
 				handle_merge(&$3->handle, &$2);
+				close_scope(state);
 				$$ = cmd_alloc(CMD_ADD, CMD_OBJ_TABLE, &$2, $5);
 			}
 			|	CHAIN		chain_spec
@@ -484,6 +502,7 @@ add_cmd			:	TABLE		table_spec
 						'{'	chain_block	'}'
 			{
 				handle_merge(&$3->handle, &$2);
+				close_scope(state);
 				$$ = cmd_alloc(CMD_ADD, CMD_OBJ_CHAIN, &$2, $5);
 			}
 			|	RULE		ruleid_spec	rule
@@ -530,7 +549,11 @@ flush_cmd		:	TABLE		table_spec
 			}
 			;
 
-table_block_alloc	:	/* empty */	{ $$ = table_alloc(); }
+table_block_alloc	:	/* empty */
+			{
+				$$ = table_alloc();
+				open_scope(state, &$$->scope);
+			}
 			;
 
 table_block		:	/* empty */	{ $$ = $<table>-1; }
@@ -547,11 +570,16 @@ table_line		:	CHAIN		chain_identifier	chain_block_alloc
 	    					'{' 	chain_block	'}'
 	    		{
 				handle_merge(&$3->handle, &$2);
+				close_scope(state);
 				$$ = $3;
 			}
 			;
 
-chain_block_alloc	:	/* empty */	{ $$ = chain_alloc(NULL); }
+chain_block_alloc	:	/* empty */
+			{
+				$$ = chain_alloc(NULL);
+				open_scope(state, &$$->scope);
+			}
 			;
 
 chain_block		:	/* empty */	{ $$ = $<chain>-1; }
diff --git a/src/rule.c b/src/rule.c
index e86c78a..8efbd88 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -68,6 +68,38 @@ void rule_print(const struct rule *rule)
 	printf("\n");
 }
 
+struct scope *scope_init(struct scope *scope, const struct scope *parent)
+{
+	scope->parent = parent;
+	init_list_head(&scope->symbols);
+	return scope;
+}
+
+void symbol_bind(struct scope *scope, const char *identifier, struct expr *expr)
+{
+	struct symbol *sym;
+
+	sym = xzalloc(sizeof(*sym));
+	sym->identifier = xstrdup(identifier);
+	sym->expr = expr;
+
+	list_add_tail(&sym->list, &scope->symbols);
+}
+
+struct symbol *symbol_lookup(const struct scope *scope, const char *identifier)
+{
+	struct symbol *sym;
+
+	while (scope != NULL) {
+		list_for_each_entry(sym, &scope->symbols, list) {
+			if (!strcmp(sym->identifier, identifier))
+				return sym;
+		}
+		scope = scope->parent;
+	}
+	return NULL;
+}
+
 struct chain *chain_alloc(const char *name)
 {
 	struct chain *chain;



More information about the netfilter-cvslog mailing list