summaryrefslogtreecommitdiffstats
path: root/src/parser_bison.y
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2016-08-26 11:19:18 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2016-08-29 20:30:28 +0200
commit1ed9a3726c01fda218f37b7f4555c8b7106521ef (patch)
tree6bfab3347d55dceb89f1f1845a63de6c3f4160bd /src/parser_bison.y
parentd089630ecbc783d7f0c6df972033694b1671c009 (diff)
src: add quota statement
This new statement is stateful, so it can be used from flow tables, eg. # nft add rule filter input \ flow table http { ip saddr timeout 60s quota over 50 mbytes } drop This basically sets a quota per source IP address of 50 mbytes after which packets are dropped. Note that the timeout releases the entry if no traffic is seen from this IP after 60 seconds. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/parser_bison.y')
-rw-r--r--src/parser_bison.y38
1 files changed, 33 insertions, 5 deletions
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 8c0f625c..6b58fe77 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -376,6 +376,8 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%token OVER "over"
%token UNTIL "until"
+%token QUOTA "quota"
+
%token NANOSECOND "nanosecond"
%token MICROSECOND "microsecond"
%token MILLISECOND "millisecond"
@@ -431,8 +433,8 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%destructor { handle_free(&$$); } set_spec set_identifier
%type <val> family_spec family_spec_explicit chain_policy prio_spec
-%type <string> dev_spec
-%destructor { xfree($$); } dev_spec
+%type <string> dev_spec quota_unit
+%destructor { xfree($$); } dev_spec quota_unit
%type <table> table_block_alloc table_block
%destructor { close_scope(state); table_free($$); } table_block_alloc
@@ -466,9 +468,9 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%type <stmt> log_stmt log_stmt_alloc
%destructor { stmt_free($$); } log_stmt log_stmt_alloc
%type <val> level_type
-%type <stmt> limit_stmt
-%destructor { stmt_free($$); } limit_stmt
-%type <val> limit_burst limit_mode time_unit
+%type <stmt> limit_stmt quota_stmt
+%destructor { stmt_free($$); } limit_stmt quota_stmt
+%type <val> limit_burst limit_mode time_unit quota_mode
%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
@@ -1373,6 +1375,7 @@ stmt : verdict_stmt
| meta_stmt
| log_stmt
| limit_stmt
+ | quota_stmt
| reject_stmt
| nat_stmt
| queue_stmt
@@ -1542,6 +1545,31 @@ limit_stmt : LIMIT RATE limit_mode NUM SLASH time_unit limit_burst
}
;
+quota_mode : OVER { $$ = NFT_QUOTA_F_INV; }
+ | UNTIL { $$ = 0; }
+ | /* empty */ { $$ = 0; }
+ ;
+
+quota_unit : BYTES { $$ = xstrdup("bytes"); }
+ | STRING { $$ = $1; }
+ ;
+
+quota_stmt : QUOTA quota_mode NUM quota_unit
+ {
+ struct error_record *erec;
+ uint64_t rate;
+
+ erec = data_unit_parse(&@$, $4, &rate);
+ if (erec != NULL) {
+ erec_queue(erec, state->msgs);
+ YYERROR;
+ }
+ $$ = quota_stmt_alloc(&@$);
+ $$->quota.bytes = $3 * rate;
+ $$->quota.flags = $2;
+ }
+ ;
+
limit_mode : OVER { $$ = NFT_LIMIT_F_INV; }
| UNTIL { $$ = 0; }
| /* empty */ { $$ = 0; }