This patch adds options to choose set optimization mechanisms. Two new statements are added to the set syntax, and they can be mixed: nft add set filter set1 { type ipv4_addr ; size 1024 ; } nft add set filter set1 { type ipv4_addr ; policy memory ; } nft add set filter set1 { type ipv4_addr ; policy performance ; } nft add set filter set1 { type ipv4_addr ; policy memory ; size 1024 ; } nft add set filter set1 { type ipv4_addr ; size 1024 ; policy memory ; } nft add set filter set1 { type ipv4_addr ; policy performance ; size 1024 ; } nft add set filter set1 { type ipv4_addr ; size 1024 ; policy performance ; } Also valid for maps: nft add map filter map1 { type ipv4_addr : verdict ; policy performace ; } [...] This is the output format, which can be imported later with `nft -f': table filter { set set1 { type ipv4_addr policy memory size 1024 } } Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@xxxxxxxxx> --- include/rule.h | 8 ++++++++ src/netlink.c | 19 +++++++++++++++++++ src/parser.y | 31 +++++++++++++++++++++++++++++++ src/rule.c | 27 +++++++++++++++++++++++++++ src/scanner.l | 5 +++++ 5 files changed, 90 insertions(+) diff --git a/include/rule.h b/include/rule.h index 88aefc6..49a39ea 100644 --- a/include/rule.h +++ b/include/rule.h @@ -180,6 +180,9 @@ enum set_flags { * @datatype: mapping data type * @datalen: mapping data len * @init: initializer + * @attr_flags: set attr flags + * @policy: set mechanism policy + * @desc: set mechanism desc */ struct set { struct list_head list; @@ -192,6 +195,11 @@ struct set { const struct datatype *datatype; unsigned int datalen; struct expr *init; + uint32_t attr_flags; + uint32_t policy; + struct { + uint32_t size; + } desc; }; extern struct set *set_alloc(const struct location *loc); diff --git a/src/netlink.c b/src/netlink.c index 84d5db3..eca4858 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -1045,6 +1045,17 @@ 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_POLICY)) { + set->policy = nft_set_attr_get_u32(nls, NFT_SET_ATTR_POLICY); + set->attr_flags |= (1 << NFT_SET_ATTR_POLICY); + } + + if (nft_set_attr_is_set(nls, NFT_SET_ATTR_DESC_SIZE)) { + set->desc.size = nft_set_attr_get_u32(nls, + NFT_SET_ATTR_DESC_SIZE); + set->attr_flags |= (1 << NFT_SET_ATTR_DESC_SIZE); + } + return set; } @@ -1103,6 +1114,14 @@ static int netlink_add_set_batch(struct netlink_ctx *ctx, } set->handle.set_id = ++set_id; nft_set_attr_set_u32(nls, NFT_SET_ATTR_ID, set->handle.set_id); + + if (set->attr_flags & (1 << NFT_SET_ATTR_POLICY)) + nft_set_attr_set_u32(nls, NFT_SET_ATTR_POLICY, set->policy); + + if (set->attr_flags & (1 << NFT_SET_ATTR_DESC_SIZE)) + nft_set_attr_set_u32(nls, NFT_SET_ATTR_DESC_SIZE, + set->desc.size); + netlink_dump_set(nls); err = mnl_nft_set_batch_add(nf_sock, nls, NLM_F_EXCL, ctx->seqnum); diff --git a/src/parser.y b/src/parser.y index c9b22f0..8c8f94a 100644 --- a/src/parser.y +++ b/src/parser.y @@ -20,6 +20,7 @@ #include <linux/netfilter/nf_tables.h> #include <linux/netfilter/nf_conntrack_tuple_common.h> #include <libnftnl/common.h> +#include <libnftnl/set.h> #include <rule.h> #include <statement.h> @@ -201,6 +202,11 @@ static void location_update(struct location *loc, struct location *rhs, int n) %token INTERVAL "interval" %token ELEMENTS "elements" +%token POLICY "policy" +%token MEMORY "memory" +%token PERFORMANCE "performance" +%token SIZE "size" + %token <val> NUM "number" %token <string> STRING "string" %token <string> QUOTED_STRING @@ -401,6 +407,9 @@ static void location_update(struct location *loc, struct location *rhs, int n) %type <val> set_flag_list set_flag +%type <val> set_policy_spec +%type <val> set_size_spec + %type <set> set_block_alloc set_block %destructor { set_free($$); } set_block_alloc @@ -953,6 +962,7 @@ set_block : /* empty */ { $$ = $<set>-1; } state->msgs); YYERROR; } + $$ = $1; } | set_block FLAGS set_flag_list stmt_seperator @@ -965,6 +975,7 @@ set_block : /* empty */ { $$ = $<set>-1; } $1->init = $4; $$ = $1; } + | set_block set_mechanism stmt_seperator ; set_flag_list : set_flag_list COMMA set_flag @@ -1018,6 +1029,26 @@ map_block : /* empty */ { $$ = $<set>-1; } $1->init = $4; $$ = $1; } + | map_block set_mechanism stmt_seperator + ; + +set_mechanism : set_policy_spec + { + $<set>0->attr_flags |= (1 << NFT_SET_ATTR_POLICY); + $<set>0->policy = $1; + } + | set_size_spec + { + $<set>0->attr_flags |= (1 << NFT_SET_ATTR_DESC_SIZE); + $<set>0->desc.size = $1; + } + ; + +set_policy_spec : POLICY PERFORMANCE { $$ = NFT_SET_POL_PERFORMANCE; } + | POLICY MEMORY { $$ = NFT_SET_POL_MEMORY; } + ; + +set_size_spec : SIZE NUM { $$ = $2; } ; hook_spec : TYPE STRING HOOK STRING PRIORITY NUM diff --git a/src/rule.c b/src/rule.c index 80deb1b..e2290d7 100644 --- a/src/rule.c +++ b/src/rule.c @@ -75,6 +75,7 @@ void set_free(struct set *set) if (--set->refcnt > 0) return; handle_free(&set->handle); + xfree(set); } @@ -90,6 +91,9 @@ struct set *set_clone(const struct set *set) newset->datatype = set->datatype; newset->datalen = set->datalen; newset->init = expr_clone(set->init); + newset->attr_flags = set->attr_flags; + newset->policy = set->policy; + newset->desc.size = set->desc.size; return newset; } @@ -134,6 +138,18 @@ struct print_fmt_options { const char *stmt_separator; }; +static const char *set_policy2str(uint32_t policy) +{ + switch (policy) { + case NFT_SET_POL_PERFORMANCE: + return "performance"; + case NFT_SET_POL_MEMORY: + return "memory"; + default: + return "unknown"; + } +} + static void do_set_print(const struct set *set, struct print_fmt_options *opts) { const char *delim = ""; @@ -153,8 +169,19 @@ static void do_set_print(const struct set *set, struct print_fmt_options *opts) printf("%s%stype %s", opts->tab, opts->tab, set->keytype->name); if (set->flags & SET_F_MAP) printf(" : %s", set->datatype->name); + printf("%s", opts->stmt_separator); + if (set->attr_flags & (1 << NFT_SET_ATTR_POLICY)) { + printf("%s%spolicy %s%s", opts->tab, opts->tab, + set_policy2str(set->policy), opts->stmt_separator); + } + + if (set->attr_flags & (1 << NFT_SET_ATTR_DESC_SIZE)) { + printf("%s%ssize %u%s", opts->tab, opts->tab, + set->desc.size, opts->stmt_separator); + } + if (set->flags & (SET_F_CONSTANT | SET_F_INTERVAL)) { printf("%s%sflags ", opts->tab, opts->tab); if (set->flags & SET_F_CONSTANT) { diff --git a/src/scanner.l b/src/scanner.l index 8aab38f..6458d09 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -271,6 +271,11 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) "interval" { return INTERVAL; } "elements" { return ELEMENTS; } +"policy" { return POLICY; } +"size" { return SIZE; } +"performance" { return PERFORMANCE; } +"memory" { return MEMORY; } + "counter" { return COUNTER; } "packets" { return PACKETS; } "bytes" { return BYTES; } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html