]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: support for restoring element counters
authorPablo Neira Ayuso <pablo@netfilter.org>
Wed, 11 Mar 2020 12:00:01 +0000 (13:00 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 18 Mar 2020 18:10:02 +0000 (19:10 +0100)
This patch allows you to restore counters in dynamic sets:

 table ip test {
        set test {
                type ipv4_addr
                size 65535
                flags dynamic,timeout
                timeout 30d
                gc-interval 1d
                elements = { 192.168.10.13 expires 19d23h52m27s576ms counter packets 51 bytes 17265 }
        }
        chain output {
                type filter hook output priority 0;
                update @test { ip saddr }
        }
 }

You can also add counters to elements from the control place, ie.

 table ip test {
        set test {
                type ipv4_addr
                size 65535
                elements = { 192.168.2.1 counter packets 75 bytes 19043 }
        }

        chain output {
                type filter hook output priority filter; policy accept;
                ip daddr @test
        }
 }

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/netlink.h
src/netlink.c
src/netlink_linearize.c
src/parser_bison.y

index c2eb89498d7246a79e1dd0ccab9acdbae612c957..0a5fde3cf08cc3c7b191cdaa134e3dc4f532f094 100644 (file)
@@ -113,6 +113,7 @@ extern void netlink_gen_data(const struct expr *expr,
 extern void netlink_gen_raw_data(const mpz_t value, enum byteorder byteorder,
                                 unsigned int len,
                                 struct nft_data_linearize *data);
+extern struct nftnl_expr *netlink_gen_stmt_stateful(const struct stmt *stmt);
 
 extern struct expr *netlink_alloc_value(const struct location *loc,
                                        const struct nft_data_delinearize *nld);
index 671923f3eebaa3a24fe105149435b4e2155937c7..e10af564bcaceeb6337f23f9056c975a7e851be3 100644 (file)
@@ -138,6 +138,9 @@ static struct nftnl_set_elem *alloc_nftnl_setelem(const struct expr *set,
        if (elem->expiration)
                nftnl_set_elem_set_u64(nlse, NFTNL_SET_ELEM_EXPIRATION,
                                       elem->expiration);
+       if (elem->stmt)
+               nftnl_set_elem_set(nlse, NFTNL_SET_ELEM_EXPR,
+                                  netlink_gen_stmt_stateful(elem->stmt), 0);
        if (elem->comment || expr->elem_flags) {
                udbuf = nftnl_udata_buf_alloc(NFT_USERDATA_MAXLEN);
                if (!udbuf)
index 5b3c43c6c641dad221670c9a4dabc8e18068b423..e70e63b336cdd38e7c4d73f46b5eca96461505d8 100644 (file)
@@ -880,7 +880,7 @@ static struct nftnl_expr *netlink_gen_quota_stmt(const struct stmt *stmt)
        return nle;
 }
 
-static struct nftnl_expr *netlink_gen_stmt_stateful(const struct stmt *stmt)
+struct nftnl_expr *netlink_gen_stmt_stateful(const struct stmt *stmt)
 {
        switch (stmt->ops->type) {
        case STMT_CONNLIMIT:
index 26ce4e089e1e2950ddd7eaf06b955876e6288744..3d65d20816d6dffa8bca3d4992e9285d882760b1 100644 (file)
@@ -3671,7 +3671,7 @@ meter_key_expr_alloc      :       concat_expr
                        ;
 
 set_elem_expr          :       set_elem_expr_alloc
-                       |       set_elem_expr_alloc             set_elem_options
+                       |       set_elem_expr_alloc             set_elem_expr_options
                        ;
 
 set_elem_expr_alloc    :       set_lhs_expr
@@ -3701,6 +3701,40 @@ set_elem_option          :       TIMEOUT                 time_spec
                        }
                        ;
 
+set_elem_expr_options  :       set_elem_expr_option
+                       {
+                               $<expr>$        = $<expr>0;
+                       }
+                       |       set_elem_expr_options   set_elem_expr_option
+                       ;
+
+set_elem_expr_option   :       TIMEOUT                 time_spec
+                       {
+                               $<expr>0->timeout = $2;
+                       }
+                       |       EXPIRES         time_spec
+                       {
+                               $<expr>0->expiration = $2;
+                       }
+                       |       COUNTER
+                       {
+                               $<expr>0->stmt = counter_stmt_alloc(&@$);
+                       }
+                       |       COUNTER PACKETS NUM     BYTES   NUM
+                       {
+                               struct stmt *stmt;
+
+                               stmt = counter_stmt_alloc(&@$);
+                               stmt->counter.packets = $3;
+                               stmt->counter.bytes = $5;
+                               $<expr>0->stmt = stmt;
+                       }
+                       |       comment_spec
+                       {
+                               $<expr>0->comment = $1;
+                       }
+                       ;
+
 set_lhs_expr           :       concat_rhs_expr
                        |       wildcard_expr
                        ;