summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2022-08-30 16:51:35 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2022-08-31 13:57:26 +0200
commit702eff5b5b748842d27811dfb22ed0c7e7003a97 (patch)
tree8a3afdcf81ad3ec05e0819d9682deb7a895a10a3
parent7284e79fcafe76ada4c73761bde125e836a5e3fa (diff)
src: allow burst 0 for byte ratelimit and use it as default
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>
-rw-r--r--doc/statements.txt9
-rw-r--r--src/parser_bison.y9
-rw-r--r--src/parser_json.c5
-rw-r--r--src/statement.c2
-rw-r--r--tests/py/any/limit.t.json6
-rw-r--r--tests/py/any/limit.t.json.output24
-rw-r--r--tests/py/any/limit.t.payload30
7 files changed, 44 insertions, 41 deletions
diff --git a/doc/statements.txt b/doc/statements.txt
index 6aaf806b..6c6b1d87 100644
--- a/doc/statements.txt
+++ b/doc/statements.txt
@@ -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"]
diff --git a/src/parser_bison.y b/src/parser_bison.y
index ae14eb1a..0266819a 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -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; }
;
diff --git a/src/parser_json.c b/src/parser_json.c
index 9e93927a..2437b1ba 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -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;
diff --git a/src/statement.c b/src/statement.c
index 30caf9c7..327d00f9 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -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);
diff --git a/tests/py/any/limit.t.json b/tests/py/any/limit.t.json
index b41ae60a..e001ba0f 100644
--- a/tests/py/any/limit.t.json
+++ b/tests/py/any/limit.t.json
@@ -129,7 +129,7 @@
[
{
"limit": {
- "burst": 5,
+ "burst": 0,
"burst_unit": "bytes",
"per": "second",
"rate": 1,
@@ -142,7 +142,7 @@
[
{
"limit": {
- "burst": 5,
+ "burst": 0,
"burst_unit": "bytes",
"per": "second",
"rate": 1,
@@ -155,7 +155,7 @@
[
{
"limit": {
- "burst": 5,
+ "burst": 0,
"burst_unit": "bytes",
"per": "second",
"rate": 1,
diff --git a/tests/py/any/limit.t.json.output b/tests/py/any/limit.t.json.output
index e6f26496..5a95f5e1 100644
--- a/tests/py/any/limit.t.json.output
+++ b/tests/py/any/limit.t.json.output
@@ -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,
@@ -109,7 +109,7 @@
[
{
"limit": {
- "burst": 5,
+ "burst": 0,
"burst_unit": "bytes",
"per": "second",
"rate": 10230,
@@ -122,7 +122,7 @@
[
{
"limit": {
- "burst": 5,
+ "burst": 0,
"burst_unit": "bytes",
"per": "second",
"rate": 1023000,
@@ -195,7 +195,7 @@
[
{
"limit": {
- "burst": 5,
+ "burst": 0,
"burst_unit": "bytes",
"inv": true,
"per": "second",
@@ -209,7 +209,7 @@
[
{
"limit": {
- "burst": 5,
+ "burst": 0,
"burst_unit": "bytes",
"inv": true,
"per": "second",
@@ -223,7 +223,7 @@
[
{
"limit": {
- "burst": 5,
+ "burst": 0,
"burst_unit": "bytes",
"inv": true,
"per": "second",
@@ -237,7 +237,7 @@
[
{
"limit": {
- "burst": 5,
+ "burst": 0,
"burst_unit": "bytes",
"inv": true,
"per": "second",
@@ -251,7 +251,7 @@
[
{
"limit": {
- "burst": 5,
+ "burst": 0,
"burst_unit": "bytes",
"inv": true,
"per": "second",
@@ -265,7 +265,7 @@
[
{
"limit": {
- "burst": 5,
+ "burst": 0,
"burst_unit": "bytes",
"inv": true,
"per": "second",
diff --git a/tests/py/any/limit.t.payload b/tests/py/any/limit.t.payload
index 3bd85f4e..0c7ee942 100644
--- a/tests/py/any/limit.t.payload
+++ b/tests/py/any/limit.t.payload
@@ -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