[nftables] Add support for user-defined symbolic constants

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


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

    Add support for user-defined symbolic constants
    
    User-defined constants can be used like this:
    
     define allowed_hosts	= { 192.168.0.0/24, 10.0.0.20-10.0.0.30 }
     define udp_services	= domain
     define tcp_services	= { ssh, domain }
    
     ip saddr $allowed_hosts udp dport $udp_services counter accept
     ip saddr $allowed_hosts tcp dport $tcp_services counter accept
    
    Recursive definitions are possible, but currently not fully handled.
    Anything requiring transformations (sets using ranges) can not be
    used more than once currently since the expressions need to be COW'ed
    previously.
    
    Signed-off-by: Patrick McHardy <kaber at trash.net>
       via  878cc0e4e863e6b2c9fa71f791d35245b3ddbdb2 (commit)
      from  5c40780440c0e8661fc7cfcec72dab48b934631d (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 878cc0e4e863e6b2c9fa71f791d35245b3ddbdb2
Author: Patrick McHardy <kaber at trash.net>
Date:   Fri Mar 20 08:34:59 2009 +0100

    Add support for user-defined symbolic constants
    
    User-defined constants can be used like this:
    
     define allowed_hosts	= { 192.168.0.0/24, 10.0.0.20-10.0.0.30 }
     define udp_services	= domain
     define tcp_services	= { ssh, domain }
    
     ip saddr $allowed_hosts udp dport $udp_services counter accept
     ip saddr $allowed_hosts tcp dport $tcp_services counter accept
    
    Recursive definitions are possible, but currently not fully handled.
    Anything requiring transformations (sets using ranges) can not be
    used more than once currently since the expressions need to be COW'ed
    previously.
    
    Signed-off-by: Patrick McHardy <kaber at trash.net>

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

 include/expression.h |    2 ++
 src/evaluate.c       |   37 +++++++++++++++++++++++++++++++++----
 src/expression.c     |    2 +-
 src/parser.y         |   27 ++++++++++++++++++++-------
 src/scanner.l        |    3 +++
 5 files changed, 59 insertions(+), 12 deletions(-)
User-defined constants can be used like this:

 define allowed_hosts	= { 192.168.0.0/24, 10.0.0.20-10.0.0.30 }
 define udp_services	= domain
 define tcp_services	= { ssh, domain }

 ip saddr $allowed_hosts udp dport $udp_services counter accept
 ip saddr $allowed_hosts tcp dport $tcp_services counter accept

Recursive definitions are possible, but currently not fully handled.
Anything requiring transformations (sets using ranges) can not be
used more than once currently since the expressions need to be COW'ed
previously.

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

diff --git a/include/expression.h b/include/expression.h
index e9d21cf..d422206 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -55,6 +55,7 @@ enum expr_types {
 
 enum ops {
 	OP_INVALID,
+	OP_IMPLICIT,
 	/* Unary operations */
 	OP_HTON,
 	OP_NTOH,
@@ -172,6 +173,7 @@ struct expr {
 		struct {
 			/* EXPR_SYMBOL */
 			const struct datatype	*sym_type;
+			const struct scope	*scope;
 			const char		*identifier;
 		};
 		struct {
diff --git a/src/evaluate.c b/src/evaluate.c
index 0deff9a..706ec2e 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -102,13 +102,25 @@ static int byteorder_conversion(struct eval_ctx *ctx, struct expr **expr,
 static int expr_evaluate_symbol(struct eval_ctx *ctx, struct expr **expr)
 {
 	struct error_record *erec;
+	struct symbol *sym;
 	struct expr *new;
 
 	(*expr)->sym_type = ctx->ectx.dtype;
-	erec = symbol_parse(*expr, &new);
-	if (erec != NULL) {
-		erec_queue(erec, ctx->msgs);
-		return -1;
+
+	if ((*expr)->scope != NULL) {
+		sym = symbol_lookup((*expr)->scope, (*expr)->identifier);
+		if (sym == NULL)
+			return expr_error(ctx, *expr,
+					  "undefined identifier '%s'",
+					  (*expr)->identifier);
+		// FIXME: need to copy (on write)
+		new = expr_get(sym->expr);
+	} else {
+		erec = symbol_parse(*expr, &new);
+		if (erec != NULL) {
+			erec_queue(erec, ctx->msgs);
+			return -1;
+		}
 	}
 
 	expr_free(*expr);
@@ -702,6 +714,23 @@ static int expr_evaluate_relational(struct eval_ctx *ctx, struct expr **expr)
 					 "constant value",
 					 expr_op_symbols[rel->op]);
 
+	if (rel->op == OP_IMPLICIT) {
+		switch (right->ops->type) {
+		case EXPR_RANGE:
+			rel->op = OP_RANGE;
+			break;
+		case EXPR_SET:
+			rel->op = OP_LOOKUP;
+			break;
+		case EXPR_LIST:
+			rel->op = OP_FLAGCMP;
+			break;
+		default:
+			rel->op = OP_EQ;
+			break;
+		}
+	}
+
 	switch (rel->op) {
 	case OP_LOOKUP:
 		/* Data for range lookups needs to be in big endian order */
diff --git a/src/expression.c b/src/expression.c
index 66a8793..4b3e1e0 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -162,7 +162,7 @@ struct expr *verdict_expr_alloc(const struct location *loc,
 
 static void symbol_expr_print(const struct expr *expr)
 {
-	printf("%s", expr->identifier);
+	printf("%s%s", expr->scope != NULL ? "$" : "", expr->identifier);
 }
 
 static void symbol_expr_destroy(struct expr *expr)
diff --git a/src/parser.y b/src/parser.y
index 1ca5981..d9da115 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -151,6 +151,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
 %token SET			"set"
 
 %token INCLUDE			"include"
+%token DEFINE			"define"
 
 %token HOOK			"hook"
 %token <val> HOOKNUM		"hooknum"
@@ -379,8 +380,8 @@ static void location_update(struct location *loc, struct location *rhs, int n)
 %type <expr>			set_expr set_list_expr set_list_member_expr
 %destructor { expr_free($$); }	set_expr set_list_expr set_list_member_expr
 
-%type <expr>			expr
-%destructor { expr_free($$); }	expr
+%type <expr>			expr initializer_expr
+%destructor { expr_free($$); }	expr initializer_expr
 
 %type <expr>			match_expr
 %destructor { expr_free($$); }	match_expr
@@ -461,6 +462,11 @@ common_block		:	INCLUDE		QUOTED_STRING	stmt_seperator
 				}
 				xfree($2);
 			}
+			|	DEFINE		identifier	'='	initializer_expr	stmt_seperator
+			{
+				symbol_bind(current_scope(state), $2, $4);
+				xfree($2);
+			}
 			;
 
 line			:	common_block			{ $$ = NULL; }
@@ -809,6 +815,12 @@ symbol_expr		:	string
 				$$ = symbol_expr_alloc(&@$, $1);
 				xfree($1);
 			}
+			|	'$'	identifier
+			{
+				$$ = symbol_expr_alloc(&@$, $2);
+				$$->scope = current_scope(state);
+				xfree($2);
+			}
 			;
 
 integer_expr		:	NUM
@@ -985,17 +997,18 @@ expr			:	concat_expr
 			|	multiton_expr
 			;
 
+initializer_expr	:	expr
+			|	set_expr
+			|	list_expr
+			;
+
 match_expr		:	relational_expr
 			|	membership_expr
 			;
 
 relational_expr		:	expr	/* implicit */	expr
 			{
-				enum ops op;
-
-				/* RHS determines operation */
-				op = ($2->ops->type == EXPR_RANGE) ? OP_RANGE : OP_EQ;
-				$$ = relational_expr_alloc(&@$, op, $1, $2);
+				$$ = relational_expr_alloc(&@$, OP_IMPLICIT, $1, $2);
 			}
 			|	expr	/* implicit */	list_expr
 			{
diff --git a/src/scanner.l b/src/scanner.l
index 3b22bb9..7fc01f7 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -207,6 +207,8 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 "-"			{ return DASH; }
 "*"			{ return ASTERISK; }
 "@"			{ return AT; }
+"$"			{ return '$'; }
+"="			{ return '='; }
 "=>"			{ return ARROW; }
 "map"			{ return MAP; }
 "vmap"			{ return VMAP; }
@@ -219,6 +221,7 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 "NF_INET_POST_ROUTING"	{ yylval->val = NF_INET_POST_ROUTING;	return HOOKNUM; }
 
 "include"		{ return INCLUDE; }
+"define"		{ return DEFINE; }
 
 "describe"		{ return DESCRIBE; }
 



More information about the netfilter-cvslog mailing list