diff options
author | Florian Westphal <fw@strlen.de> | 2021-01-30 19:58:42 +0100 |
---|---|---|
committer | Florian Westphal <fw@strlen.de> | 2021-02-22 14:57:49 +0100 |
commit | 4ab1e5e6077918b5b0b4553daa907a725d4cd0fe (patch) | |
tree | 21bb70c5b86ad2d89372c7a7374637886ae19f02 /src/parser_bison.y | |
parent | b9e871cb6f5bf17376955acff55bce264e8355aa (diff) |
src: allow use of 'verdict' in typeof definitions
'verdict' cannot be used as part of a map typeof-based key definition,
its a datatype and not an expression, e.g.:
typeof iifname . ip protocol . th dport : verdic
... will fail.
Make the parser convert a 'verdict' symbol to a verdict expression
and allow to store its presence as part of the typeof key definition.
Reported-by: Frank Myhr <fmyhr@fhmtech.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'src/parser_bison.y')
-rw-r--r-- | src/parser_bison.y | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/src/parser_bison.y b/src/parser_bison.y index 11e899ff..3c8013b2 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -672,8 +672,8 @@ int nft_lex(void *, void *, void *); %type <expr> symbol_expr verdict_expr integer_expr variable_expr chain_expr policy_expr %destructor { expr_free($$); } symbol_expr verdict_expr integer_expr variable_expr chain_expr policy_expr -%type <expr> primary_expr shift_expr and_expr typeof_expr -%destructor { expr_free($$); } primary_expr shift_expr and_expr typeof_expr +%type <expr> primary_expr shift_expr and_expr typeof_expr typeof_data_expr +%destructor { expr_free($$); } primary_expr shift_expr and_expr typeof_expr typeof_data_expr %type <expr> exclusive_or_expr inclusive_or_expr %destructor { expr_free($$); } exclusive_or_expr inclusive_or_expr %type <expr> basic_expr @@ -1739,6 +1739,29 @@ subchain_block : /* empty */ { $$ = $<chain>-1; } } ; +typeof_data_expr : primary_expr + { + struct expr *e = $1; + + if (e->etype == EXPR_SYMBOL && + strcmp("verdict", e->identifier) == 0) { + struct expr *v = verdict_expr_alloc(&@1, NF_ACCEPT, NULL); + + expr_free(e); + v->flags &= ~EXPR_F_CONSTANT; + e = v; + } + + if (expr_ops(e)->build_udata == NULL) { + erec_queue(error(&@1, "map data type '%s' lacks typeof serialization", expr_ops(e)->name), + state->msgs); + expr_free(e); + YYERROR; + } + $$ = e; + } + ; + typeof_expr : primary_expr { if (expr_ops($1)->build_udata == NULL) { @@ -1878,7 +1901,7 @@ map_block : /* empty */ { $$ = $<set>-1; } $$ = $1; } | map_block TYPEOF - typeof_expr COLON typeof_expr + typeof_expr COLON typeof_data_expr stmt_separator { $1->key = $3; |