]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
parser_bison: allow to restore limit from dynamic set
authorPablo Neira Ayuso <pablo@netfilter.org>
Wed, 2 Dec 2020 17:31:00 +0000 (18:31 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 4 Dec 2020 11:53:00 +0000 (12:53 +0100)
Update parser to allow to restore limit per set element in dynamic set.

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1477
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/parser_bison.y
tests/shell/testcases/sets/0056dynamic_limit_0 [new file with mode: 0755]

index a88844661af5837d08f5144ca1ff89c6cdae3da4..fb329919ea955941b3616214e7f97c65e7f62c71 100644 (file)
@@ -4097,6 +4097,38 @@ set_elem_expr_option     :       TIMEOUT                 time_spec
                                stmt->counter.bytes = $5;
                                $<expr>0->stmt = stmt;
                        }
+                       |       LIMIT   RATE    limit_mode      NUM     SLASH   time_unit       limit_burst_pkts
+                       {
+                               struct stmt *stmt;
+
+                               stmt = limit_stmt_alloc(&@$);
+                               stmt->limit.rate  = $4;
+                               stmt->limit.unit  = $6;
+                               stmt->limit.burst = $7;
+                               stmt->limit.type  = NFT_LIMIT_PKTS;
+                               stmt->limit.flags = $3;
+                               $<expr>0->stmt = stmt;
+                       }
+                       |       LIMIT   RATE    limit_mode      NUM     STRING  limit_burst_bytes
+                       {
+                               struct error_record *erec;
+                               uint64_t rate, unit;
+                               struct stmt *stmt;
+
+                               erec = rate_parse(&@$, $5, &rate, &unit);
+                               xfree($5);
+                               if (erec != NULL) {
+                                       erec_queue(erec, state->msgs);
+                                       YYERROR;
+                               }
+
+                               stmt = limit_stmt_alloc(&@$);
+                               stmt->limit.rate  = rate * $4;
+                               stmt->limit.unit  = unit;
+                               stmt->limit.burst = $6;
+                               stmt->limit.type  = NFT_LIMIT_PKT_BYTES;
+                               stmt->limit.flags = $3;
+                        }
                        |       comment_spec
                        {
                                if (already_set($<expr>0->comment, &@1, state)) {
diff --git a/tests/shell/testcases/sets/0056dynamic_limit_0 b/tests/shell/testcases/sets/0056dynamic_limit_0
new file mode 100755 (executable)
index 0000000..21fa0bf
--- /dev/null
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+RULESET="table inet filter {
+        set ssh_meter {
+                type ipv4_addr
+                size 65535
+                flags dynamic,timeout
+                timeout 1m
+                elements = { 127.0.0.1 expires 52s44ms limit rate over 1/minute }
+        }
+
+        chain output {
+                type filter hook output priority filter; policy accept;
+                ip protocol icmp add @ssh_meter { ip saddr timeout 1m limit rate over 1/minute }
+        }
+}"
+
+set -e
+$NFT -f - <<< $EXPECTED