summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2015-08-03 15:56:27 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2015-09-23 12:16:53 +0200
commit174f4a120ec7644531728621cfab5ce7fdb481c3 (patch)
tree4b62dd210a739c7ac067044e63b7d34f6b4901bd /src
parent6615676d825e02d271fe7a9ca78a77ac3773ab93 (diff)
src: add burst parameter to limit
... limit rate 1024 mbytes/second burst 10240 bytes ... limit rate 1/second burst 3 packets This parameter is optional. You need a Linux kernel >= 4.3-rc1. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r--src/datatype.c4
-rw-r--r--src/netlink_delinearize.c1
-rw-r--r--src/netlink_linearize.c4
-rw-r--r--src/parser_bison.y26
-rw-r--r--src/scanner.l1
-rw-r--r--src/statement.c8
6 files changed, 39 insertions, 5 deletions
diff --git a/src/datatype.c b/src/datatype.c
index e5a486fb..f56763b9 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -996,8 +996,8 @@ static struct error_record *time_unit_parse(const struct location *loc,
return NULL;
}
-static struct error_record *data_unit_parse(const struct location *loc,
- const char *str, uint64_t *rate)
+struct error_record *data_unit_parse(const struct location *loc,
+ const char *str, uint64_t *rate)
{
if (strncmp(str, "bytes", strlen("bytes")) == 0)
*rate = 1ULL;
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 4c639a16..2360681d 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -584,6 +584,7 @@ static void netlink_parse_limit(struct netlink_parse_ctx *ctx,
stmt->limit.rate = nftnl_expr_get_u64(nle, NFTNL_EXPR_LIMIT_RATE);
stmt->limit.unit = nftnl_expr_get_u64(nle, NFTNL_EXPR_LIMIT_UNIT);
stmt->limit.type = nftnl_expr_get_u32(nle, NFTNL_EXPR_LIMIT_TYPE);
+ stmt->limit.burst = nftnl_expr_get_u32(nle, NFTNL_EXPR_LIMIT_BURST);
list_add_tail(&stmt->list, &ctx->rule->stmts);
}
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 47092d33..f697ea52 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -709,6 +709,10 @@ static void netlink_gen_limit_stmt(struct netlink_linearize_ctx *ctx,
nftnl_expr_set_u64(nle, NFTNL_EXPR_LIMIT_RATE, stmt->limit.rate);
nftnl_expr_set_u64(nle, NFTNL_EXPR_LIMIT_UNIT, stmt->limit.unit);
nftnl_expr_set_u32(nle, NFTNL_EXPR_LIMIT_TYPE, stmt->limit.type);
+ if (stmt->limit.burst > 0)
+ nftnl_expr_set_u32(nle, NFTNL_EXPR_LIMIT_BURST,
+ stmt->limit.burst);
+
nftnl_rule_add_expr(ctx->nlr, nle);
}
diff --git a/src/parser_bison.y b/src/parser_bison.y
index ec44a2cd..385e2140 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -364,6 +364,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%token LIMIT "limit"
%token RATE "rate"
+%token BURST "burst"
%token NANOSECOND "nanosecond"
%token MICROSECOND "microsecond"
@@ -450,7 +451,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%type <val> level_type
%type <stmt> limit_stmt
%destructor { stmt_free($$); } limit_stmt
-%type <val> time_unit
+%type <val> limit_burst time_unit
%type <stmt> reject_stmt reject_stmt_alloc
%destructor { stmt_free($$); } reject_stmt reject_stmt_alloc
%type <stmt> nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc redir_stmt redir_stmt_alloc
@@ -1441,14 +1442,15 @@ level_type : LEVEL_EMERG { $$ = LOG_EMERG; }
| LEVEL_DEBUG { $$ = LOG_DEBUG; }
;
-limit_stmt : LIMIT RATE NUM SLASH time_unit
+limit_stmt : LIMIT RATE NUM SLASH time_unit limit_burst
{
$$ = limit_stmt_alloc(&@$);
$$->limit.rate = $3;
$$->limit.unit = $5;
+ $$->limit.burst = $6;
$$->limit.type = NFT_LIMIT_PKTS;
}
- | LIMIT RATE NUM STRING
+ | LIMIT RATE NUM STRING limit_burst
{
struct error_record *erec;
uint64_t rate, unit;
@@ -1462,10 +1464,28 @@ limit_stmt : LIMIT RATE NUM SLASH time_unit
$$ = limit_stmt_alloc(&@$);
$$->limit.rate = rate * $3;
$$->limit.unit = unit;
+ $$->limit.burst = $5;
$$->limit.type = NFT_LIMIT_PKT_BYTES;
}
;
+limit_burst : /* empty */ { $$ = 0; }
+ | BURST NUM PACKETS { $$ = $2; }
+ | BURST NUM BYTES { $$ = $2; }
+ | BURST NUM STRING
+ {
+ struct error_record *erec;
+ uint64_t rate;
+
+ erec = data_unit_parse(&@$, $3, &rate);
+ if (erec != NULL) {
+ erec_queue(erec, state->msgs);
+ YYERROR;
+ }
+ $$ = $2 * rate;
+ }
+ ;
+
time_unit : SECOND { $$ = 1ULL; }
| MINUTE { $$ = 1ULL * 60; }
| HOUR { $$ = 1ULL * 60 * 60; }
diff --git a/src/scanner.l b/src/scanner.l
index 2d9871d0..bd8e5726 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -309,6 +309,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"limit" { return LIMIT; }
"rate" { return RATE; }
+"burst" { return BURST; }
"nanosecond" { return NANOSECOND; }
"microsecond" { return MICROSECOND; }
diff --git a/src/statement.c b/src/statement.c
index ba7b8be2..d620d1ba 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -220,12 +220,20 @@ static void limit_stmt_print(const struct stmt *stmt)
case NFT_LIMIT_PKTS:
printf("limit rate %" PRIu64 "/%s",
stmt->limit.rate, get_unit(stmt->limit.unit));
+ if (stmt->limit.burst > 0)
+ printf(" burst %u packets", stmt->limit.burst);
break;
case NFT_LIMIT_PKT_BYTES:
data_unit = get_rate(stmt->limit.rate, &rate);
printf("limit rate %" PRIu64 " %s/%s",
rate, data_unit, get_unit(stmt->limit.unit));
+ if (stmt->limit.burst > 0) {
+ uint64_t burst;
+
+ data_unit = get_rate(stmt->limit.burst, &burst);
+ printf(" burst %"PRIu64" %s", burst, data_unit);
+ }
break;
}
}