Factor the `N / time-unit` and `N byte-unit / time-unit` expressions from limit expressions out into separate `limit_rate_pkts` and `limit_rate_bytes` rules respectively. Signed-off-by: Jeremy Sowden <jeremy@xxxxxxxxxx> --- include/datatype.h | 4 ++ src/parser_bison.y | 121 ++++++++++++++++++++++----------------------- 2 files changed, 63 insertions(+), 62 deletions(-) diff --git a/include/datatype.h b/include/datatype.h index 448be57fbc7f..7ddd3566d459 100644 --- a/include/datatype.h +++ b/include/datatype.h @@ -309,6 +309,10 @@ extern struct error_record *rate_parse(const struct location *loc, extern struct error_record *data_unit_parse(const struct location *loc, const char *str, uint64_t *rate); +struct limit_rate { + uint64_t rate, unit; +}; + extern void expr_chain_export(const struct expr *e, char *chain); #endif /* NFTABLES_DATATYPE_H */ diff --git a/src/parser_bison.y b/src/parser_bison.y index 3acd80317456..cf1e139d42f3 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -186,6 +186,7 @@ int nft_lex(void *, void *, void *); struct handle_spec handle_spec; struct position_spec position_spec; struct prio_spec prio_spec; + struct limit_rate limit_rate; } %token TOKEN_EOF 0 "end of file" @@ -607,6 +608,9 @@ int nft_lex(void *, void *, void *); %token IN "in" %token OUT "out" +%type <limit_rate> limit_rate_pkts +%type <limit_rate> limit_rate_bytes + %type <string> identifier type_identifier string comment_spec %destructor { xfree($$); } identifier type_identifier string comment_spec @@ -3145,42 +3149,31 @@ log_flag_tcp : SEQUENCE } ; -limit_stmt : LIMIT RATE limit_mode NUM SLASH time_unit limit_burst_pkts close_scope_limit +limit_stmt : LIMIT RATE limit_mode limit_rate_pkts limit_burst_pkts close_scope_limit { - if ($7 == 0) { - erec_queue(error(&@7, "limit burst must be > 0"), + if ($5 == 0) { + erec_queue(error(&@5, "limit burst must be > 0"), state->msgs); YYERROR; } $$ = limit_stmt_alloc(&@$); - $$->limit.rate = $4; - $$->limit.unit = $6; - $$->limit.burst = $7; + $$->limit.rate = $4.rate; + $$->limit.unit = $4.unit; + $$->limit.burst = $5; $$->limit.type = NFT_LIMIT_PKTS; $$->limit.flags = $3; } - | LIMIT RATE limit_mode NUM STRING limit_burst_bytes close_scope_limit + | LIMIT RATE limit_mode limit_rate_bytes limit_burst_bytes close_scope_limit { - struct error_record *erec; - uint64_t rate, unit; - - if ($6 == 0) { - erec_queue(error(&@6, "limit burst must be > 0"), + if ($5 == 0) { + erec_queue(error(&@5, "limit burst must be > 0"), state->msgs); YYERROR; } - - erec = rate_parse(&@$, $5, &rate, &unit); - xfree($5); - if (erec != NULL) { - erec_queue(erec, state->msgs); - YYERROR; - } - $$ = limit_stmt_alloc(&@$); - $$->limit.rate = rate * $4; - $$->limit.unit = unit; - $$->limit.burst = $6; + $$->limit.rate = $4.rate; + $$->limit.unit = $4.unit; + $$->limit.burst = $5; $$->limit.type = NFT_LIMIT_PKT_BYTES; $$->limit.flags = $3; } @@ -3250,10 +3243,33 @@ limit_burst_pkts : /* empty */ { $$ = 5; } | BURST NUM PACKETS { $$ = $2; } ; +limit_rate_pkts : NUM SLASH time_unit + { + $$.rate = $1; + $$.unit = $3; + } + ; + limit_burst_bytes : /* empty */ { $$ = 5; } | BURST limit_bytes { $$ = $2; } ; +limit_rate_bytes : NUM STRING + { + struct error_record *erec; + uint64_t rate, unit; + + erec = rate_parse(&@$, $2, &rate, &unit); + xfree($2); + if (erec != NULL) { + erec_queue(erec, state->msgs); + YYERROR; + } + $$.rate = rate * $1; + $$.unit = unit; + } + ; + limit_bytes : NUM BYTES { $$ = $1; } | NUM STRING { @@ -4283,44 +4299,34 @@ set_elem_stmt : COUNTER close_scope_counter $$->counter.packets = $3; $$->counter.bytes = $5; } - | LIMIT RATE limit_mode NUM SLASH time_unit limit_burst_pkts close_scope_limit + | LIMIT RATE limit_mode limit_rate_pkts limit_burst_pkts close_scope_limit { - if ($7 == 0) { - erec_queue(error(&@7, "limit burst must be > 0"), + if ($5 == 0) { + erec_queue(error(&@5, "limit burst must be > 0"), state->msgs); YYERROR; } $$ = limit_stmt_alloc(&@$); - $$->limit.rate = $4; - $$->limit.unit = $6; - $$->limit.burst = $7; + $$->limit.rate = $4.rate; + $$->limit.unit = $4.unit; + $$->limit.burst = $5; $$->limit.type = NFT_LIMIT_PKTS; $$->limit.flags = $3; } - | LIMIT RATE limit_mode NUM STRING limit_burst_bytes close_scope_limit + | LIMIT RATE limit_mode limit_rate_bytes limit_burst_bytes close_scope_limit { - struct error_record *erec; - uint64_t rate, unit; - - if ($6 == 0) { + if ($5 == 0) { erec_queue(error(&@6, "limit burst must be > 0"), state->msgs); YYERROR; } - erec = rate_parse(&@$, $5, &rate, &unit); - xfree($5); - if (erec != NULL) { - erec_queue(erec, state->msgs); - YYERROR; - } - $$ = limit_stmt_alloc(&@$); - $$->limit.rate = rate * $4; - $$->limit.unit = unit; - $$->limit.burst = $6; + $$->limit.rate = $4.rate; + $$->limit.unit = $4.unit; + $$->limit.burst = $5; $$->limit.type = NFT_LIMIT_PKT_BYTES; $$->limit.flags = $3; - } + } | CT COUNT NUM close_scope_ct { $$ = connlimit_stmt_alloc(&@$); @@ -4553,34 +4559,25 @@ ct_obj_alloc : /* empty */ } ; -limit_config : RATE limit_mode NUM SLASH time_unit limit_burst_pkts +limit_config : RATE limit_mode limit_rate_pkts limit_burst_pkts { struct limit *limit; limit = &$<obj>0->limit; - limit->rate = $3; - limit->unit = $5; - limit->burst = $6; + limit->rate = $3.rate; + limit->unit = $3.unit; + limit->burst = $4; limit->type = NFT_LIMIT_PKTS; limit->flags = $2; } - | RATE limit_mode NUM STRING limit_burst_bytes + | RATE limit_mode limit_rate_bytes limit_burst_bytes { struct limit *limit; - struct error_record *erec; - uint64_t rate, unit; - - erec = rate_parse(&@$, $4, &rate, &unit); - xfree($4); - if (erec != NULL) { - erec_queue(erec, state->msgs); - YYERROR; - } limit = &$<obj>0->limit; - limit->rate = rate * $3; - limit->unit = unit; - limit->burst = $5; + limit->rate = $3.rate; + limit->unit = $3.unit; + limit->burst = $4; limit->type = NFT_LIMIT_PKT_BYTES; limit->flags = $2; } -- 2.33.0