summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Fabian <david.fabian@bosson.cz>2018-01-22 14:02:11 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2018-02-26 18:50:37 +0100
commit5a5cdd5d42f0aa8fc78ac1ff81a423fc40072fea (patch)
treef923979c1d84e13e40d8cfdc929804d6fab89e47 /src
parentd3d2c4bd782368e9024d88795659325372b99ed8 (diff)
Added undefine/redefine keywords
This is a small patch to nft which adds two new keywords - undefine and redefine. undefine simply undefines a variable from the current scope. redefine allows one to change a variable definition. We have a firewall written in bash (using iptables) that is organized by customer VLANs. Each VLAN has its own set of bash variables holding things like uplink iface names, gateway IPs, etc. We want to rewrite the firewall to nftables but are stuck on the fact that nft variables cannot be overridden in the same scope. We have each VLAN configuration in a separate file containing pre/post-routing, input, output and forward rules,and we include those files to a master firewall configuration. One solution is to rename all the variables with some VLAN specific (pre/su)ffix. But that is cumbersome. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r--src/parser_bison.y22
-rw-r--r--src/rule.c15
-rw-r--r--src/scanner.l2
3 files changed, 39 insertions, 0 deletions
diff --git a/src/parser_bison.y b/src/parser_bison.y
index ec8b0dd8..df672b1e 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -185,6 +185,8 @@ int nft_lex(void *, void *, void *);
%token INCLUDE "include"
%token DEFINE "define"
+%token REDEFINE "redefine"
+%token UNDEFINE "undefine"
%token FIB "fib"
@@ -763,6 +765,26 @@ common_block : INCLUDE QUOTED_STRING stmt_separator
symbol_bind(scope, $2, $4);
xfree($2);
}
+ | REDEFINE identifier '=' initializer_expr stmt_separator
+ {
+ struct scope *scope = current_scope(state);
+
+ /* ignore missing identifier */
+ symbol_unbind(scope, $2);
+ symbol_bind(scope, $2, $4);
+ xfree($2);
+ }
+ | UNDEFINE identifier stmt_separator
+ {
+ struct scope *scope = current_scope(state);
+
+ if (symbol_unbind(scope, $2) < 0) {
+ erec_queue(error(&@2, "undefined symbol '%s'", $2),
+ state->msgs);
+ YYERROR;
+ }
+ xfree($2);
+ }
| error stmt_separator
{
if (++state->nerrs == nft->parser_max_errors)
diff --git a/src/rule.c b/src/rule.c
index c7b4b498..5b7219e8 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -485,6 +485,21 @@ void symbol_bind(struct scope *scope, const char *identifier, struct expr *expr)
list_add_tail(&sym->list, &scope->symbols);
}
+int symbol_unbind(struct scope *scope, const char *identifier)
+{
+ struct symbol *sym;
+
+ sym = symbol_lookup(scope, identifier);
+ if (!sym)
+ return -1;
+
+ list_del(&sym->list);
+ xfree(sym->identifier);
+ expr_free(sym->expr);
+ xfree(sym);
+ return 0;
+}
+
struct symbol *symbol_lookup(const struct scope *scope, const char *identifier)
{
struct symbol *sym;
diff --git a/src/scanner.l b/src/scanner.l
index c3992a78..05c70afe 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -233,6 +233,8 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"include" { return INCLUDE; }
"define" { return DEFINE; }
+"redefine" { return REDEFINE; }
+"undefine" { return UNDEFINE; }
"describe" { return DESCRIBE; }