]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: add set optimization options
authorArturo Borrero <arturo.borrero.glez@gmail.com>
Tue, 23 Sep 2014 12:05:15 +0000 (14:05 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 29 Sep 2014 10:33:37 +0000 (12:33 +0200)
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 <arturo.borrero.glez@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/rule.h
src/netlink.c
src/parser.y
src/rule.c
src/scanner.l

index 88aefc69eef564d26c669b40041c6868f770475b..a1d589002fcdb48df2d973bdf5ac82dce2108d32 100644 (file)
@@ -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);
index 17b82ee88d650be8508ab56a72ea04d7e1ebd1a6..64960ad9cb3eef0bbd05ee7716ab761a75a2e2ac 100644 (file)
@@ -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);
index 32d5455d1ef62966dc2260e8d43827462b7ff274..db120a06bfb8f56b5ec6f023abf846e87ddb36a3 100644 (file)
@@ -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,8 @@ 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 <set>                    set_block_alloc set_block
 %destructor { set_free($$); }  set_block_alloc
 
@@ -967,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
@@ -1020,6 +1029,21 @@ map_block                :       /* empty */     { $$ = $<set>-1; }
                                $1->init = $4;
                                $$ = $1;
                        }
+                       |       map_block       set_mechanism   stmt_seperator
+                       ;
+
+set_mechanism          :       POLICY          set_policy_spec
+                       {
+                               $<set>0->policy = $2;
+                       }
+                       |       SIZE            NUM
+                       {
+                               $<set>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
index 80deb1b9524ca6f23b38aca7a55905307c4cdaaa..2fe25206111a995e2c06c1ed60406a07e75d3017 100644 (file)
@@ -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) {
index 772f658d98be7cca9a5d1a426a5fa5c717ca77af..35c9446fbd33a5ae5121bf6b76651bf782f464eb 100644 (file)
@@ -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; }