summaryrefslogtreecommitdiffstats
path: root/src/expression.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2018-03-03 22:52:35 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2018-03-04 00:22:50 +0100
commit3b20f47277c0cb4ea07ad30f94496c9f383035e7 (patch)
treec5b0b1fc569dd64cd3fdcedaecfacf22b0abe6dd /src/expression.c
parent8162d2b96718041dadc52ab127db9d91a2c223cc (diff)
src: add variable expression and use it to allow redefinitions
Add new variable expression that we can use to attach symbols in runtime, this allows us to redefine variables via new keyword, eg. table ip x { chain y { define address = { 1.1.1.1, 2.2.2.2 } ip saddr $address redefine address = { 3.3.3.3 } ip saddr $address } } # nft list ruleset table ip x { chain y { ip saddr { 1.1.1.1, 2.2.2.2 } ip saddr { 3.3.3.3 } } } Note that redefinition just places a new symbol version before the existing one, so symbol lookups always find the latest version. The undefine keyword decrements the reference counter and removes the symbol from the list, so it cannot be used anymore. Still, previous references to this symbol via variable expression are still valid. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/expression.c')
-rw-r--r--src/expression.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/expression.c b/src/expression.c
index 393c1b2b..ee75284e 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -254,6 +254,45 @@ struct expr *symbol_expr_alloc(const struct location *loc,
return expr;
}
+static void variable_expr_print(const struct expr *expr,
+ struct output_ctx *octx)
+{
+ nft_print(octx, "$%s", expr->sym->identifier);
+}
+
+static void variable_expr_clone(struct expr *new, const struct expr *expr)
+{
+ new->scope = expr->scope;
+ new->sym = expr->sym;
+
+ expr->sym->refcnt++;
+}
+
+static void variable_expr_destroy(struct expr *expr)
+{
+ expr->sym->refcnt--;
+}
+
+static const struct expr_ops variable_expr_ops = {
+ .type = EXPR_VARIABLE,
+ .name = "variable",
+ .print = variable_expr_print,
+ .clone = variable_expr_clone,
+ .destroy = variable_expr_destroy,
+};
+
+struct expr *variable_expr_alloc(const struct location *loc,
+ struct scope *scope, struct symbol *sym)
+{
+ struct expr *expr;
+
+ expr = expr_alloc(loc, &variable_expr_ops, &invalid_type,
+ BYTEORDER_INVALID, 0);
+ expr->scope = scope;
+ expr->sym = sym;
+ return expr;
+}
+
static void constant_expr_print(const struct expr *expr,
struct output_ctx *octx)
{