]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
Add support for user-defined symbolic constants
authorPatrick McHardy <kaber@trash.net>
Fri, 20 Mar 2009 07:34:59 +0000 (08:34 +0100)
committerPatrick McHardy <kaber@trash.net>
Fri, 20 Mar 2009 07:34:59 +0000 (08:34 +0100)
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@trash.net>
include/expression.h
src/evaluate.c
src/expression.c
src/parser.y
src/scanner.l

index e9d21cfc7f755d64be1e1fe9c2957254722e6b9a..d422206033dea29e6a4f22cbfaa0ac695a270ad4 100644 (file)
@@ -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 {
index 0deff9ad033859382df1e7e4610837aafcbec5a8..706ec2e58a38152f9bedd5311e87415c58dbdfda 100644 (file)
@@ -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 */
index 66a8793f5286e3a4ce90d7aa64db29ce91be9e6b..4b3e1e0475d23824cf04fbef1988b8063f321dd0 100644 (file)
@@ -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)
index 1ca5981b3c715bb3626610642011e1a66680cac4..d9da115ad4365811d30c6da19e1084e3e2957493 100644 (file)
@@ -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
                        {
index 3b22bb9ebc6fd47b8b2e48b0a03836bbd0e2f783..7fc01f77e2dd347605d95b1fe438f78ae5455a4a 100644 (file)
@@ -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; }