]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
set: add timeout support for sets
authorPatrick McHardy <kaber@trash.net>
Mon, 23 Mar 2015 21:34:57 +0000 (21:34 +0000)
committerPatrick McHardy <kaber@trash.net>
Sun, 12 Apr 2015 18:59:27 +0000 (19:59 +0100)
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 <interval>;

Signed-off-by: Patrick McHardy <kaber@trash.net>
include/linux/netfilter/nf_tables.h
include/rule.h
src/evaluate.c
src/netlink.c
src/parser_bison.y
src/rule.c
src/scanner.l

index 832bc46db78bc3498e8ab18b6e7a50ba12c86acd..8671505eea8b3c03c874961fd60709d3a096650e 100644 (file)
@@ -207,12 +207,14 @@ enum nft_rule_compat_attributes {
  * @NFT_SET_CONSTANT: set contents may not change while bound
  * @NFT_SET_INTERVAL: set contains intervals
  * @NFT_SET_MAP: set is used as a dictionary
+ * @NFT_SET_TIMEOUT: set uses timeouts
  */
 enum nft_set_flags {
        NFT_SET_ANONYMOUS               = 0x1,
        NFT_SET_CONSTANT                = 0x2,
        NFT_SET_INTERVAL                = 0x4,
        NFT_SET_MAP                     = 0x8,
+       NFT_SET_TIMEOUT                 = 0x10,
 };
 
 /**
@@ -251,6 +253,8 @@ enum nft_set_desc_attributes {
  * @NFTA_SET_POLICY: selection policy (NLA_U32)
  * @NFTA_SET_DESC: set description (NLA_NESTED)
  * @NFTA_SET_ID: uniquely identifies a set in a transaction (NLA_U32)
+ * @NFTA_SET_TIMEOUT: default timeout value (NLA_U64)
+ * @NFTA_SET_GC_INTERVAL: garbage collection interval (NLA_U32)
  */
 enum nft_set_attributes {
        NFTA_SET_UNSPEC,
@@ -264,6 +268,8 @@ enum nft_set_attributes {
        NFTA_SET_POLICY,
        NFTA_SET_DESC,
        NFTA_SET_ID,
+       NFTA_SET_TIMEOUT,
+       NFTA_SET_GC_INTERVAL,
        __NFTA_SET_MAX
 };
 #define NFTA_SET_MAX           (__NFTA_SET_MAX - 1)
index 97959f7b36fb79b6838c6c6de73dbb3922eafa86..5d4459932775e3c45da46439b061315f28e586d0 100644 (file)
@@ -173,6 +173,7 @@ enum set_flags {
        SET_F_CONSTANT          = 0x2,
        SET_F_INTERVAL          = 0x4,
        SET_F_MAP               = 0x8,
+       SET_F_TIMEOUT           = 0x10,
 };
 
 /**
@@ -183,6 +184,8 @@ enum set_flags {
  * @location:  location the set was defined/declared at
  * @refcnt:    reference count
  * @flags:     bitmask of set flags
+ * @gc_int:    garbage collection interval
+ * @timeout:   default timeout value
  * @keytype:   key data type
  * @keylen:    key length
  * @datatype:  mapping data type
@@ -197,6 +200,8 @@ struct set {
        struct location         location;
        unsigned int            refcnt;
        uint32_t                flags;
+       uint32_t                gc_int;
+       uint64_t                timeout;
        const struct datatype   *keytype;
        unsigned int            keylen;
        const struct datatype   *datatype;
index 37db107b93c7e8549bf2a95948857233192b5bd1..04ca08dffa7ee0a2ac2444c56f0b6585cd270147 100644 (file)
@@ -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;
 
index 0827034e597dbe05c96cb3a036632dc237b6d26a..e1d6421fbd88f2d6704faa50fdf3b2c1a85bf3f9 100644 (file)
@@ -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);
 
index 9fbc590c1963c9eb9e3c5d50e08c6eb1081195b2..8083187854645740c38a85b3679896232b39320c 100644 (file)
@@ -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 */     { $$ = $<set>-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 */
index 71143807f49ed62800c2d2aea211593d17e4baec..b2090dddaae84355422771f971632eed1ab04493 100644 (file)
@@ -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);
        }
 
index 27d95bfc3ff9d2f89fd3c89e96a9fc7b3f27699a..4231d27037ca4f3a1ab91ce2fc5e027fee2e95e4 100644 (file)
@@ -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; }