]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: allow burst 0 for byte ratelimit and use it as default
authorPablo Neira Ayuso <pablo@netfilter.org>
Tue, 30 Aug 2022 14:51:35 +0000 (16:51 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 31 Aug 2022 11:57:26 +0000 (13:57 +0200)
Packet-based limit burst is set to 5, as in iptables. However,
byte-based limit burst adds to the rate to calculate the bucket size,
and this is also sets this to 5 (... bytes in this case). Update it to
use zero byte burst by default instead.

This patch also updates manpage to describe how the burst value
influences the kernel module's token bucket in each of the two modes.
This documentation update is based on original text by Phil Sutter.

Adjust tests/py to silence warnings due to mismatching byte burst.

Fixes: 285baccfea46 ("src: disallow burst 0 in ratelimits")
Acked-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
doc/statements.txt
src/parser_bison.y
src/parser_json.c
src/statement.c
tests/py/any/limit.t.json
tests/py/any/limit.t.json.output
tests/py/any/limit.t.payload

index 6aaf806bcff25a6024e3ccfecec11d8ea223853b..6c6b1d8712d4781a52e2d74081741a281d147416 100644 (file)
@@ -332,8 +332,13 @@ ____
 A limit statement matches at a limited rate using a token bucket filter. A rule
 using this statement will match until this limit is reached. It can be used in
 combination with the log statement to give limited logging. The optional
-*over* keyword makes it match over the specified rate. Default *burst* is 5.
-if you specify *burst*, it must be non-zero value.
+*over* keyword makes it match over the specified rate.
+
+The *burst* value influences the bucket size, i.e. jitter tolerance. With
+packet-based *limit*, the bucket holds exactly *burst* packets, by default
+five. If you specify packet *burst*, it must be a non-zero value. With
+byte-based *limit*, the bucket's minimum size is the given rate's byte value
+and the *burst* value adds to that, by default zero bytes.
 
 .limit statement values
 [options="header"]
index ae14eb1a690be0b1db02f86f8833f628aec1353b..0266819a779b6bd8d0696df59771aa2e9cbbf8f0 100644 (file)
@@ -3203,7 +3203,7 @@ log_flag_tcp              :       SEQUENCE
 limit_stmt             :       LIMIT   RATE    limit_mode      limit_rate_pkts limit_burst_pkts        close_scope_limit
                        {
                                if ($5 == 0) {
-                                       erec_queue(error(&@5, "limit burst must be > 0"),
+                                       erec_queue(error(&@5, "packet limit burst must be > 0"),
                                                   state->msgs);
                                        YYERROR;
                                }
@@ -3216,11 +3216,6 @@ limit_stmt               :       LIMIT   RATE    limit_mode      limit_rate_pkts limit_burst_pkts        close_scope
                        }
                        |       LIMIT   RATE    limit_mode      limit_rate_bytes        limit_burst_bytes       close_scope_limit
                        {
-                               if ($5 == 0) {
-                                       erec_queue(error(&@5, "limit burst must be > 0"),
-                                                  state->msgs);
-                                       YYERROR;
-                               }
                                $$ = limit_stmt_alloc(&@$);
                                $$->limit.rate  = $4.rate;
                                $$->limit.unit  = $4.unit;
@@ -3301,7 +3296,7 @@ limit_rate_pkts           :       NUM     SLASH   time_unit
                        }
                        ;
 
-limit_burst_bytes      :       /* empty */                     { $$ = 5; }
+limit_burst_bytes      :       /* empty */                     { $$ = 0; }
                        |       BURST   limit_bytes             { $$ = $2; }
                        ;
 
index 9e93927a9a2b853d39cdeb5bfc020fbf3a12217b..2437b1bae178eaae882fb80bb5d944b9fe16b030 100644 (file)
@@ -1826,7 +1826,7 @@ static struct stmt *json_parse_limit_stmt(struct json_ctx *ctx,
                                          const char *key, json_t *value)
 {
        struct stmt *stmt;
-       uint64_t rate, burst = 5;
+       uint64_t rate, burst = 0;
        const char *rate_unit = "packets", *time, *burst_unit = "bytes";
        int inv = 0;
 
@@ -1840,6 +1840,9 @@ static struct stmt *json_parse_limit_stmt(struct json_ctx *ctx,
                stmt = limit_stmt_alloc(int_loc);
 
                if (!strcmp(rate_unit, "packets")) {
+                       if (burst == 0)
+                               burst = 5;
+
                        stmt->limit.type = NFT_LIMIT_PKTS;
                        stmt->limit.rate = rate;
                        stmt->limit.burst = burst;
index 30caf9c7f6e1f2dff2bf00dfb1c36a9f835840dd..327d00f99200a8c5aa3335a8e5be627998218425 100644 (file)
@@ -465,7 +465,7 @@ static void limit_stmt_print(const struct stmt *stmt, struct output_ctx *octx)
                nft_print(octx, "limit rate %s%" PRIu64 " %s/%s",
                          inv ? "over " : "", rate, data_unit,
                          get_unit(stmt->limit.unit));
-               if (stmt->limit.burst != 5) {
+               if (stmt->limit.burst != 0) {
                        uint64_t burst;
 
                        data_unit = get_rate(stmt->limit.burst, &burst);
index b41ae60a3bd65c89cf9bcf019fc8247f0ac6f4a7..e001ba0fe9ac3c049767b61fa4168d00c33af8d8 100644 (file)
 [
     {
         "limit": {
-            "burst": 5,
+            "burst": 0,
             "burst_unit": "bytes",
             "per": "second",
             "rate": 1,
 [
     {
         "limit": {
-            "burst": 5,
+            "burst": 0,
             "burst_unit": "bytes",
             "per": "second",
             "rate": 1,
 [
     {
         "limit": {
-            "burst": 5,
+            "burst": 0,
             "burst_unit": "bytes",
             "per": "second",
             "rate": 1,
index e6f26496e01cbea89970a1570abc5d74e45097be..5a95f5e10a86a6f0c771246f6c25dd5d396a88a2 100644 (file)
@@ -57,7 +57,7 @@
 [
     {
         "limit": {
-            "burst": 5,
+            "burst": 0,
             "burst_unit": "bytes",
             "per": "second",
             "rate": 1,
@@ -70,7 +70,7 @@
 [
     {
         "limit": {
-            "burst": 5,
+            "burst": 0,
             "burst_unit": "bytes",
             "per": "second",
             "rate": 2,
@@ -83,7 +83,7 @@
 [
     {
         "limit": {
-            "burst": 5,
+            "burst": 0,
             "burst_unit": "bytes",
             "per": "second",
             "rate": 1025,
@@ -96,7 +96,7 @@
 [
     {
         "limit": {
-            "burst": 5,
+            "burst": 0,
             "burst_unit": "bytes",
             "per": "second",
             "rate": 1023,
 [
     {
         "limit": {
-            "burst": 5,
+            "burst": 0,
             "burst_unit": "bytes",
             "per": "second",
             "rate": 10230,
 [
     {
         "limit": {
-            "burst": 5,
+            "burst": 0,
             "burst_unit": "bytes",
             "per": "second",
             "rate": 1023000,
 [
     {
         "limit": {
-            "burst": 5,
+            "burst": 0,
             "burst_unit": "bytes",
             "inv": true,
             "per": "second",
 [
     {
         "limit": {
-            "burst": 5,
+            "burst": 0,
             "burst_unit": "bytes",
             "inv": true,
             "per": "second",
 [
     {
         "limit": {
-            "burst": 5,
+            "burst": 0,
             "burst_unit": "bytes",
             "inv": true,
             "per": "second",
 [
     {
         "limit": {
-            "burst": 5,
+            "burst": 0,
             "burst_unit": "bytes",
             "inv": true,
             "per": "second",
 [
     {
         "limit": {
-            "burst": 5,
+            "burst": 0,
             "burst_unit": "bytes",
             "inv": true,
             "per": "second",
 [
     {
         "limit": {
-            "burst": 5,
+            "burst": 0,
             "burst_unit": "bytes",
             "inv": true,
             "per": "second",
index 3bd85f4ebf45adc884d72b2ac717c6e3afe63389..0c7ee942927d2c6f5e0060e082af05376e0cd7bf 100644 (file)
@@ -24,39 +24,39 @@ ip test-ip4 output
 
 # limit rate 1 kbytes/second
 ip test-ip4 output
-  [ limit rate 1024/second burst 5 type bytes flags 0x0 ]
+  [ limit rate 1024/second burst 0 type bytes flags 0x0 ]
 
 # limit rate 2 kbytes/second
 ip test-ip4 output
-  [ limit rate 2048/second burst 5 type bytes flags 0x0 ]
+  [ limit rate 2048/second burst 0 type bytes flags 0x0 ]
 
 # limit rate 1025 kbytes/second
 ip test-ip4 output
-  [ limit rate 1049600/second burst 5 type bytes flags 0x0 ]
+  [ limit rate 1049600/second burst 0 type bytes flags 0x0 ]
 
 # limit rate 1023 mbytes/second
 ip test-ip4 output
-  [ limit rate 1072693248/second burst 5 type bytes flags 0x0 ]
+  [ limit rate 1072693248/second burst 0 type bytes flags 0x0 ]
 
 # limit rate 10230 mbytes/second
 ip test-ip4 output
-  [ limit rate 10726932480/second burst 5 type bytes flags 0x0 ]
+  [ limit rate 10726932480/second burst 0 type bytes flags 0x0 ]
 
 # limit rate 1023000 mbytes/second
 ip test-ip4 output
-  [ limit rate 1072693248000/second burst 5 type bytes flags 0x0 ]
+  [ limit rate 1072693248000/second burst 0 type bytes flags 0x0 ]
 
 # limit rate 1 bytes / second
 ip
-  [ limit rate 1/second burst 5 type bytes flags 0x0 ]
+  [ limit rate 1/second burst 0 type bytes flags 0x0 ]
 
 # limit rate 1 kbytes / second
 ip
-  [ limit rate 1024/second burst 5 type bytes flags 0x0 ]
+  [ limit rate 1024/second burst 0 type bytes flags 0x0 ]
 
 # limit rate 1 mbytes / second
 ip
-  [ limit rate 1048576/second burst 5 type bytes flags 0x0 ]
+  [ limit rate 1048576/second burst 0 type bytes flags 0x0 ]
 
 
 # limit rate 1025 bytes/second burst 512 bytes
@@ -101,27 +101,27 @@ ip test-ip4 output
 
 # limit rate over 1 kbytes/second
 ip test-ip4 output
-  [ limit rate 1024/second burst 5 type bytes flags 0x1 ]
+  [ limit rate 1024/second burst 0 type bytes flags 0x1 ]
 
 # limit rate over 2 kbytes/second
 ip test-ip4 output
-  [ limit rate 2048/second burst 5 type bytes flags 0x1 ]
+  [ limit rate 2048/second burst 0 type bytes flags 0x1 ]
 
 # limit rate over 1025 kbytes/second
 ip test-ip4 output
-  [ limit rate 1049600/second burst 5 type bytes flags 0x1 ]
+  [ limit rate 1049600/second burst 0 type bytes flags 0x1 ]
 
 # limit rate over 1023 mbytes/second
 ip test-ip4 output
-  [ limit rate 1072693248/second burst 5 type bytes flags 0x1 ]
+  [ limit rate 1072693248/second burst 0 type bytes flags 0x1 ]
 
 # limit rate over 10230 mbytes/second
 ip test-ip4 output
-  [ limit rate 10726932480/second burst 5 type bytes flags 0x1 ]
+  [ limit rate 10726932480/second burst 0 type bytes flags 0x1 ]
 
 # limit rate over 1023000 mbytes/second
 ip test-ip4 output
-  [ limit rate 1072693248000/second burst 5 type bytes flags 0x1 ]
+  [ limit rate 1072693248000/second burst 0 type bytes flags 0x1 ]
 
 # limit rate over 1025 bytes/second burst 512 bytes
 ip test-ip4 output