Allow to specify elements that never expire in sets with global timeout. set x { typeof ip saddr timeout 1m elements = { 1.1.1.1 timeout never, 2.2.2.2, 3.3.3.3 timeout 2m } } in this example above: - 1.1.1.1 is a permanent element - 2.2.2.2 expires after 1 minute (uses default set timeout) - 3.3.3.3 expires after 2 minutes (uses specified timeout override) Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- This is the userspace dependency for: https://patchwork.ozlabs.org/project/netfilter-devel/list/?series=418393 Note that no updates are required to support for set element timeout updates. src/expression.c | 11 +++++++++-- src/parser_bison.y | 29 ++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/expression.c b/src/expression.c index 992f51064051..54b539be89d5 100644 --- a/src/expression.c +++ b/src/expression.c @@ -25,6 +25,8 @@ #include <erec.h> #include <json.h> +#define NFT_NEVER_EXPIRES UINT64_MAX + extern const struct expr_ops ct_expr_ops; extern const struct expr_ops fib_expr_ops; extern const struct expr_ops hash_expr_ops; @@ -1314,9 +1316,14 @@ static void set_elem_expr_print(const struct expr *expr, } if (expr->timeout) { nft_print(octx, " timeout "); - time_print(expr->timeout, octx); + if (expr->timeout == NFT_NEVER_EXPIRES) + nft_print(octx, "never"); + else + time_print(expr->timeout, octx); } - if (!nft_output_stateless(octx) && expr->expiration) { + if (!nft_output_stateless(octx) && + expr->timeout != NFT_NEVER_EXPIRES && + expr->expiration) { nft_print(octx, " expires "); time_print(expr->expiration, octx); } diff --git a/src/parser_bison.y b/src/parser_bison.y index 10105f153aa0..b5a4588fb675 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -45,6 +45,8 @@ #include "parser_bison.h" +#define NFT_NEVER_EXPIRES UINT64_MAX + void parser_init(struct nft_ctx *nft, struct parser_state *state, struct list_head *msgs, struct list_head *cmds, struct scope *top_scope) @@ -695,7 +697,7 @@ int nft_lex(void *, void *, void *); %type <string> identifier type_identifier string comment_spec %destructor { free_const($$); } identifier type_identifier string comment_spec -%type <val> time_spec time_spec_or_num_s quota_used +%type <val> time_spec time_spec_or_num_s set_elem_time_spec quota_used %type <expr> data_type_expr data_type_atom_expr %destructor { expr_free($$); } data_type_expr data_type_atom_expr @@ -4545,7 +4547,28 @@ set_elem_options : set_elem_option | set_elem_options set_elem_option ; -set_elem_option : TIMEOUT time_spec +set_elem_time_spec : STRING + { + struct error_record *erec; + uint64_t res; + + if (!strcmp("never", $1)) { + free_const($1); + $$ = NFT_NEVER_EXPIRES; + break; + } + + erec = time_parse(&@1, $1, &res); + free_const($1); + if (erec != NULL) { + erec_queue(erec, state->msgs); + YYERROR; + } + $$ = res; + } + ; + +set_elem_option : TIMEOUT time_spec { $<expr>0->timeout = $2; } @@ -4660,7 +4683,7 @@ set_elem_stmt : COUNTER close_scope_counter } ; -set_elem_expr_option : TIMEOUT time_spec +set_elem_expr_option : TIMEOUT set_elem_time_spec { $<expr>0->timeout = $2; } -- 2.30.2