From 90a0f8c443bbe33676aeff4e9782aa6b0e6c0894 Mon Sep 17 00:00:00 2001 From: Arturo Borrero Date: Tue, 23 Sep 2014 14:05:15 +0200 Subject: src: add set optimization options 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 } } In this approach the parser accepts default options such as 'performance', given they are a valid configurations, but aren't sent to the kernel. Signed-off-by: Arturo Borrero Gonzalez Signed-off-by: Pablo Neira Ayuso --- include/rule.h | 6 ++++++ src/netlink.c | 20 ++++++++++++++++++++ src/parser.y | 24 ++++++++++++++++++++++++ src/rule.c | 28 ++++++++++++++++++++++++++++ src/scanner.l | 5 +++++ 5 files changed, 83 insertions(+) diff --git a/include/rule.h b/include/rule.h index 88aefc69..a1d58900 100644 --- a/include/rule.h +++ b/include/rule.h @@ -180,6 +180,8 @@ enum set_flags { * @datatype: mapping data type * @datalen: mapping data len * @init: initializer + * @policy: set mechanism policy + * @desc: set mechanism desc */ struct set { struct list_head list; @@ -192,6 +194,10 @@ struct set { const struct datatype *datatype; unsigned int datalen; struct expr *init; + 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 17b82ee8..64960ad9 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -1050,6 +1050,13 @@ 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); + + 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); + return set; } @@ -1108,6 +1115,19 @@ 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->flags & (SET_F_CONSTANT))) { + if (set->policy != NFT_SET_POL_PERFORMANCE) { + nft_set_attr_set_u32(nls, NFT_SET_ATTR_POLICY, + set->policy); + } + + if (set->desc.size != 0) { + 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 32d5455d..db120a06 100644 --- a/src/parser.y +++ b/src/parser.y @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -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 NUM "number" %token STRING "string" %token QUOTED_STRING @@ -401,6 +407,8 @@ static void location_update(struct location *loc, struct location *rhs, int n) %type set_flag_list set_flag +%type set_policy_spec + %type set_block_alloc set_block %destructor { set_free($$); } set_block_alloc @@ -967,6 +975,7 @@ set_block : /* empty */ { $$ = $-1; } $1->init = $4; $$ = $1; } + | set_block set_mechanism stmt_seperator ; set_flag_list : set_flag_list COMMA set_flag @@ -1020,6 +1029,21 @@ map_block : /* empty */ { $$ = $-1; } $1->init = $4; $$ = $1; } + | map_block set_mechanism stmt_seperator + ; + +set_mechanism : POLICY set_policy_spec + { + $0->policy = $2; + } + | SIZE NUM + { + $0->desc.size = $2; + } + ; + +set_policy_spec : PERFORMANCE { $$ = NFT_SET_POL_PERFORMANCE; } + | MEMORY { $$ = NFT_SET_POL_MEMORY; } ; hook_spec : TYPE STRING HOOK STRING PRIORITY NUM diff --git a/src/rule.c b/src/rule.c index 80deb1b9..2fe25206 100644 --- a/src/rule.c +++ b/src/rule.c @@ -90,6 +90,8 @@ struct set *set_clone(const struct set *set) newset->datatype = set->datatype; newset->datalen = set->datalen; newset->init = expr_clone(set->init); + newset->policy = set->policy; + newset->desc.size = set->desc.size; return newset; } @@ -134,6 +136,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 +167,22 @@ 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->flags & (SET_F_CONSTANT))) { + if (set->policy != NFT_SET_POL_PERFORMANCE) { + printf("%s%spolicy %s%s", opts->tab, opts->tab, + set_policy2str(set->policy), + opts->stmt_separator); + } + + if (set->desc.size > 0) { + 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 772f658d..35c9446f 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; } -- cgit v1.2.3