From 52532335290457cc449564b7e011f73bef3a83e2 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sat, 11 Apr 2015 17:02:13 +0100 Subject: expr: add set_elem_expr as container for set element attributes Add a new expression type "set_elem_expr" that is used as container for the key in order to attach different attributes, such as timeout values, to the key. The expression hierarchy is as follows: Sets: elem | key Maps: mapping / \ elem data | key Signed-off-by: Patrick McHardy --- src/evaluate.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/evaluate.c') diff --git a/src/evaluate.c b/src/evaluate.c index 7ecb7939..37db107b 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -675,6 +675,19 @@ static int expr_evaluate_list(struct eval_ctx *ctx, struct expr **expr) return 0; } +static int expr_evaluate_set_elem(struct eval_ctx *ctx, struct expr **expr) +{ + struct expr *elem = *expr; + + if (expr_evaluate(ctx, &elem->key) < 0) + return -1; + + elem->dtype = elem->key->dtype; + elem->len = elem->key->len; + elem->flags = elem->key->flags; + return 0; +} + static int expr_evaluate_set(struct eval_ctx *ctx, struct expr **expr) { struct expr *set = *expr, *i, *next; @@ -1100,6 +1113,8 @@ static int expr_evaluate(struct eval_ctx *ctx, struct expr **expr) return expr_evaluate_list(ctx, expr); case EXPR_SET: return expr_evaluate_set(ctx, expr); + case EXPR_SET_ELEM: + return expr_evaluate_set_elem(ctx, expr); case EXPR_MAP: return expr_evaluate_map(ctx, expr); case EXPR_MAPPING: -- cgit v1.2.3 From 38a077f7af8a2151b565e3cb324901b48afd299e Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 23 Mar 2015 21:34:57 +0000 Subject: set: add timeout support for sets Timeout support can be enabled in one of two ways: 1. Using a default timeout value: set test { type ipv4_addr; timeout 1h; } 2. Using the timeout flag without a default: set test { type ipv4_addr; flags timeout; } Optionally a garbage collection interval can be specified using gc-interval ; Signed-off-by: Patrick McHardy --- src/evaluate.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/evaluate.c') diff --git a/src/evaluate.c b/src/evaluate.c index 37db107b..04ca08df 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -1737,6 +1737,10 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set) return -1; } + /* Default timeout value implies timeout support */ + if (set->timeout) + set->flags |= SET_F_TIMEOUT; + if (!(set->flags & SET_F_MAP)) return 0; -- cgit v1.2.3 From a9467e55973b10c2e8fe37525514c961580f8506 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Thu, 19 Mar 2015 13:34:18 +0000 Subject: nftables: add set statemet The set statement is used to dynamically add or update elements in a set. Syntax: # nft filter input set add tcp dport @myset # nft filter input set add ip saddr timeout 10s @myset # nft filter input set update ip saddr timeout 10s @myset Signed-off-by: Patrick McHardy --- src/evaluate.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'src/evaluate.c') diff --git a/src/evaluate.c b/src/evaluate.c index 04ca08df..e260a803 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -614,7 +614,7 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr) struct expr *i, *next; list_for_each_entry_safe(i, next, &(*expr)->expressions, list) { - if (dtype && off == 0) + if (expr_is_constant(*expr) && dtype && off == 0) return expr_binary_error(ctx->msgs, i, *expr, "unexpected concat component, " "expecting %s", @@ -1661,6 +1661,30 @@ static int stmt_evaluate_log(struct eval_ctx *ctx, struct stmt *stmt) return 0; } +static int stmt_evaluate_set(struct eval_ctx *ctx, struct stmt *stmt) +{ + expr_set_context(&ctx->ectx, NULL, 0); + if (expr_evaluate(ctx, &stmt->set.set) < 0) + return -1; + if (stmt->set.set->ops->type != EXPR_SET_REF) + return expr_error(ctx->msgs, stmt->set.set, + "Expression does not refer to a set"); + + if (stmt_evaluate_arg(ctx, stmt, + stmt->set.set->set->keytype, + stmt->set.set->set->keylen, + &stmt->set.key) < 0) + return -1; + if (expr_is_constant(stmt->set.key)) + return expr_error(ctx->msgs, stmt->set.key, + "Key expression can not be constant"); + if (stmt->set.key->comment != NULL) + return expr_error(ctx->msgs, stmt->set.key, + "Key expression comments are not supported"); + + return 0; +} + int stmt_evaluate(struct eval_ctx *ctx, struct stmt *stmt) { #ifdef DEBUG @@ -1695,6 +1719,8 @@ int stmt_evaluate(struct eval_ctx *ctx, struct stmt *stmt) return stmt_evaluate_redir(ctx, stmt); case STMT_QUEUE: return stmt_evaluate_queue(ctx, stmt); + case STMT_SET: + return stmt_evaluate_set(ctx, stmt); default: BUG("unknown statement type %s\n", stmt->ops->name); } -- cgit v1.2.3