Introduce scoped tokens for "kbytes" and "mbytes", completing already existing "bytes" one. Then generalize the unit for byte values and replace both quota_unit and limit_bytes by a combination of NUM and bytes_unit. With this in place, data_unit_parse() is not called outside of datatype.c, so make it static. Signed-off-by: Phil Sutter Reviewed-by: Florian Westphal --- include/datatype.h | 3 -- src/datatype.c | 4 +-- src/parser_bison.y | 75 +++++++++++----------------------------------- src/scanner.l | 2 ++ 4 files changed, 22 insertions(+), 62 deletions(-) diff --git a/include/datatype.h b/include/datatype.h index 4fb47f158fc2f..63dba330137a0 100644 --- a/include/datatype.h +++ b/include/datatype.h @@ -313,9 +313,6 @@ extern struct error_record *rate_parse(const struct location *loc, const char *str, uint64_t *rate, uint64_t *unit); -extern struct error_record *data_unit_parse(const struct location *loc, - const char *str, uint64_t *rate); - struct limit_rate { uint64_t rate, unit; }; diff --git a/src/datatype.c b/src/datatype.c index fac4eb9cdcecd..1950a2f3757b8 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -1507,8 +1507,8 @@ static struct error_record *time_unit_parse(const struct location *loc, return NULL; } -struct error_record *data_unit_parse(const struct location *loc, - const char *str, uint64_t *rate) +static struct error_record *data_unit_parse(const struct location *loc, + const char *str, uint64_t *rate) { if (strcmp(str, "bytes") == 0) *rate = 1ULL; diff --git a/src/parser_bison.y b/src/parser_bison.y index 8e07671cb80e9..9639352a4b47d 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -617,6 +617,8 @@ int nft_lex(void *, void *, void *); %token NAME "name" %token PACKETS "packets" %token BYTES "bytes" +%token KBYTES "kbytes" +%token MBYTES "mbytes" %token AVGPKT "avgpkt" %token LAST "last" @@ -774,8 +776,8 @@ int nft_lex(void *, void *, void *); %type extended_prio_spec prio_spec %destructor { expr_free($$.expr); } extended_prio_spec prio_spec -%type extended_prio_name quota_unit basehook_device_name -%destructor { free_const($$); } extended_prio_name quota_unit basehook_device_name +%type extended_prio_name basehook_device_name +%destructor { free_const($$); } extended_prio_name basehook_device_name %type dev_spec %destructor { free($$); } dev_spec @@ -828,7 +830,7 @@ int nft_lex(void *, void *, void *); %type level_type log_flags log_flags_tcp log_flag_tcp %type limit_stmt quota_stmt connlimit_stmt %destructor { stmt_free($$); } limit_stmt quota_stmt connlimit_stmt -%type limit_burst_pkts limit_burst_bytes limit_mode limit_bytes time_unit quota_mode +%type limit_burst_pkts limit_burst_bytes limit_mode bytes_unit time_unit quota_mode %type reject_stmt reject_stmt_alloc %destructor { stmt_free($$); } reject_stmt reject_stmt_alloc %type nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc redir_stmt redir_stmt_alloc @@ -3596,23 +3598,15 @@ quota_mode : OVER { $$ = NFT_QUOTA_F_INV; } | /* empty */ { $$ = 0; } ; -quota_unit : BYTES { $$ = xstrdup("bytes"); } - | STRING { $$ = $1; } +bytes_unit : BYTES { $$ = 1; } + | KBYTES { $$ = 1024; } + | MBYTES { $$ = 1024 * 1024; } ; quota_used : /* empty */ { $$ = 0; } - | USED NUM quota_unit + | USED NUM bytes_unit { - struct error_record *erec; - uint64_t rate; - - erec = data_unit_parse(&@$, $3, &rate); - free_const($3); - if (erec != NULL) { - erec_queue(erec, state->msgs); - YYERROR; - } - $$ = $2 * rate; + $$ = $2 * $3; } ; @@ -3625,22 +3619,14 @@ quota_stmt_alloc : QUOTA quota_stmt : quota_stmt_alloc quota_args ; -quota_args : quota_mode NUM quota_unit quota_used +quota_args : quota_mode NUM bytes_unit quota_used { - struct error_record *erec; struct quota_stmt *quota; - uint64_t rate; assert($0->type == STMT_QUOTA); - erec = data_unit_parse(&@$, $3, &rate); - free_const($3); - if (erec != NULL) { - erec_queue(erec, state->msgs); - YYERROR; - } quota = &$0->quota; - quota->bytes = $2 * rate; + quota->bytes = $2 * $3; quota->used = $4; quota->flags = $1; } @@ -3663,7 +3649,7 @@ limit_rate_pkts : NUM SLASH time_unit ; limit_burst_bytes : /* empty */ { $$ = 0; } - | BURST limit_bytes { $$ = $2; } + | BURST NUM bytes_unit { $$ = $2 * $3; } ; limit_rate_bytes : NUM STRING @@ -3680,26 +3666,10 @@ limit_rate_bytes : NUM STRING $$.rate = rate * $1; $$.unit = unit; } - | limit_bytes SLASH time_unit + | NUM bytes_unit SLASH time_unit { - $$.rate = $1; - $$.unit = $3; - } - ; - -limit_bytes : NUM BYTES { $$ = $1; } - | NUM STRING - { - struct error_record *erec; - uint64_t rate; - - erec = data_unit_parse(&@$, $2, &rate); - free_const($2); - if (erec != NULL) { - erec_queue(erec, state->msgs); - YYERROR; - } - $$ = $1 * rate; + $$.rate = $1 * $2; + $$.unit = $4; } ; @@ -4767,21 +4737,12 @@ counter_obj : /* empty */ } ; -quota_config : quota_mode NUM quota_unit quota_used +quota_config : quota_mode NUM bytes_unit quota_used { - struct error_record *erec; struct quota *quota; - uint64_t rate; - - erec = data_unit_parse(&@$, $3, &rate); - free_const($3); - if (erec != NULL) { - erec_queue(erec, state->msgs); - YYERROR; - } quota = &$0->quota; - quota->bytes = $2 * rate; + quota->bytes = $2 * $3; quota->used = $4; quota->flags = $1; } diff --git a/src/scanner.l b/src/scanner.l index ca570e2bfe066..4cbc8a44c89c8 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -414,6 +414,8 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) "name" { return NAME; } "packets" { return PACKETS; } "bytes" { return BYTES; } +"kbytes" { return KBYTES; } +"mbytes" { return MBYTES; } "last" { scanner_push_start_cond(yyscanner, SCANSTATE_LAST); return LAST; } { -- 2.51.0