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 ++++ src/netlink.c | 10 ++++++++++ src/parser_bison.y | 13 +++++++++++++ src/rule.c | 23 ++++++++++++++++++++++- src/scanner.l | 2 ++ 5 files changed, 51 insertions(+), 1 deletion(-) (limited to 'src') 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; diff --git a/src/netlink.c b/src/netlink.c index 0827034e..e1d6421f 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -1068,6 +1068,11 @@ static struct set *netlink_delinearize_set(struct netlink_ctx *ctx, set->datalen = data_len * BITS_PER_BYTE; } + if (nft_set_attr_is_set(nls, NFT_SET_ATTR_TIMEOUT)) + set->timeout = nft_set_attr_get_u64(nls, NFT_SET_ATTR_TIMEOUT); + if (nft_set_attr_is_set(nls, NFT_SET_ATTR_GC_INTERVAL)) + set->gc_int = nft_set_attr_get_u32(nls, NFT_SET_ATTR_GC_INTERVAL); + if (nft_set_attr_is_set(nls, NFT_SET_ATTR_POLICY)) set->policy = nft_set_attr_get_u32(nls, NFT_SET_ATTR_POLICY); @@ -1131,6 +1136,11 @@ static int netlink_add_set_batch(struct netlink_ctx *ctx, nft_set_attr_set_u32(nls, NFT_SET_ATTR_DATA_LEN, set->datalen / BITS_PER_BYTE); } + if (set->timeout) + nft_set_attr_set_u64(nls, NFT_SET_ATTR_TIMEOUT, set->timeout); + if (set->gc_int) + nft_set_attr_set_u32(nls, NFT_SET_ATTR_GC_INTERVAL, set->gc_int); + set->handle.set_id = ++set_id; nft_set_attr_set_u32(nls, NFT_SET_ATTR_ID, set->handle.set_id); diff --git a/src/parser_bison.y b/src/parser_bison.y index 9fbc590c..80831878 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -201,6 +201,8 @@ static void location_update(struct location *loc, struct location *rhs, int n) %token CONSTANT "constant" %token INTERVAL "interval" +%token TIMEOUT "timeout" +%token GC_INTERVAL "gc-interval" %token ELEMENTS "elements" %token POLICY "policy" @@ -944,6 +946,16 @@ set_block : /* empty */ { $$ = $-1; } $1->flags = $3; $$ = $1; } + | set_block TIMEOUT time_spec stmt_seperator + { + $1->timeout = $3 * 1000; + $$ = $1; + } + | set_block GC_INTERVAL time_spec stmt_seperator + { + $1->gc_int = $3 * 1000; + $$ = $1; + } | set_block ELEMENTS '=' set_expr { $1->init = $4; @@ -961,6 +973,7 @@ set_flag_list : set_flag_list COMMA set_flag set_flag : CONSTANT { $$ = SET_F_CONSTANT; } | INTERVAL { $$ = SET_F_INTERVAL; } + | TIMEOUT { $$ = SET_F_TIMEOUT; } ; map_block_alloc : /* empty */ diff --git a/src/rule.c b/src/rule.c index 71143807..b2090ddd 100644 --- a/src/rule.c +++ b/src/rule.c @@ -136,6 +136,7 @@ static void do_set_print(const struct set *set, struct print_fmt_options *opts) { const char *delim = ""; const char *type; + uint32_t flags; type = set->flags & SET_F_MAP ? "map" : "set"; printf("%s%s", opts->tab, type); @@ -167,7 +168,12 @@ static void do_set_print(const struct set *set, struct print_fmt_options *opts) } } - if (set->flags & (SET_F_CONSTANT | SET_F_INTERVAL)) { + flags = set->flags; + /* "timeout" flag is redundant if a default timeout exists */ + if (set->timeout) + flags &= ~SET_F_TIMEOUT; + + if (flags & (SET_F_CONSTANT | SET_F_INTERVAL | SET_F_TIMEOUT)) { printf("%s%sflags ", opts->tab, opts->tab); if (set->flags & SET_F_CONSTANT) { printf("%sconstant", delim); @@ -177,6 +183,21 @@ static void do_set_print(const struct set *set, struct print_fmt_options *opts) printf("%sinterval", delim); delim = ","; } + if (set->flags & SET_F_TIMEOUT) { + printf("%stimeout", delim); + delim = ","; + } + printf("%s", opts->nl); + } + + if (set->timeout) { + printf("%s%stimeout ", opts->tab, opts->tab); + time_print(set->timeout / 1000); + printf("%s", opts->nl); + } + if (set->gc_int) { + printf("%s%sgc-interval ", opts->tab, opts->tab); + time_print(set->gc_int / 1000); printf("%s", opts->nl); } diff --git a/src/scanner.l b/src/scanner.l index 27d95bfc..4231d270 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -271,6 +271,8 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) "constant" { return CONSTANT; } "interval" { return INTERVAL; } +"timeout" { return TIMEOUT; } +"gc-interval" { return GC_INTERVAL; } "elements" { return ELEMENTS; } "policy" { return POLICY; } -- cgit v1.2.3