* [PATCH 0/2 nft WIP] Using variables in chain priority @ 2019-07-16 9:08 Fernando Fernandez Mancera 2019-07-16 9:08 ` [PATCH 1/2 nft WIP] src: introduce prio_expr " Fernando Fernandez Mancera 2019-07-16 9:08 ` [PATCH 2/2 nft WIP] src: allow variables " Fernando Fernandez Mancera 0 siblings, 2 replies; 6+ messages in thread From: Fernando Fernandez Mancera @ 2019-07-16 9:08 UTC (permalink / raw) To: netfilter-devel; +Cc: Fernando Fernandez Mancera I am getting the following error when I try to load the following file using "nft -f" File: define pri = filter table inet global { chain prerouting { type filter hook prerouting priority $pri policy accept } } Error: priority_test:1:14-19: Error: No symbol type information define pri = filter ^^^^^^ priority_test:4:37-49: Error: invalid priority expression symbol in this context. type filter hook prerouting priority $pri ^^^^^^^^^^^^^ The original idea was to evaluate the prio_expr and check the result expression datatype. This way we could use variables with number priority number and also strings. It seems that the symbol does not have symbol type information at the evaluation phase. I have a workaround that consist in allocating a constant expression with the symbol identifier in the parser but then we should check the datatype manually in the evaluation. I don't like that solution at all. Is there any other way to accomplish that? I would like to find a better solution. Thanks! Fernando Fernandez Mancera (2): src: introduce prio_expr in chain priority src: allow variables in chain priority include/rule.h | 8 ++++---- src/evaluate.c | 29 +++++++++++++++++++---------- src/parser_bison.y | 26 ++++++++++++++++++-------- src/rule.c | 4 ++-- 4 files changed, 43 insertions(+), 24 deletions(-) -- 2.20.1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/2 nft WIP] src: introduce prio_expr in chain priority 2019-07-16 9:08 [PATCH 0/2 nft WIP] Using variables in chain priority Fernando Fernandez Mancera @ 2019-07-16 9:08 ` Fernando Fernandez Mancera 2019-07-16 18:06 ` Pablo Neira Ayuso 2019-07-16 9:08 ` [PATCH 2/2 nft WIP] src: allow variables " Fernando Fernandez Mancera 1 sibling, 1 reply; 6+ messages in thread From: Fernando Fernandez Mancera @ 2019-07-16 9:08 UTC (permalink / raw) To: netfilter-devel; +Cc: Fernando Fernandez Mancera Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net> --- include/rule.h | 8 ++++---- src/evaluate.c | 29 +++++++++++++++++++---------- src/parser_bison.y | 25 +++++++++++++++++-------- src/rule.c | 4 ++-- 4 files changed, 42 insertions(+), 24 deletions(-) diff --git a/include/rule.h b/include/rule.h index aefb24d..4d7cec8 100644 --- a/include/rule.h +++ b/include/rule.h @@ -173,13 +173,13 @@ enum chain_flags { * struct prio_spec - extendend priority specification for mixed * textual/numerical parsing. * - * @str: name of the standard priority value - * @num: Numerical value. This MUST contain the parsed value of str after + * @prio_expr: expr of the standard priority value + * @num: Numerical value. This MUST contain the parsed value of prio_expr after * evaluation. */ struct prio_spec { - const char *str; - int num; + struct expr *prio_expr; + int num; struct location loc; }; diff --git a/src/evaluate.c b/src/evaluate.c index 8086f75..cee65cd 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -3181,15 +3181,24 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set) return 0; } -static bool evaluate_priority(struct prio_spec *prio, int family, int hook) +static bool evaluate_priority(struct eval_ctx *ctx, struct prio_spec *prio, + int family, int hook) { int priority; + char prio_str[NFT_NAME_MAXLEN]; /* A numeric value has been used to specify priority. */ - if (prio->str == NULL) + if (prio->prio_expr == NULL) return true; - priority = std_prio_lookup(prio->str, family, hook); + if (expr_evaluate(ctx, &prio->prio_expr) < 0) + return false; + if (prio->prio_expr->etype == EXPR_VALUE) + mpz_export_data(prio_str, prio->prio_expr->value, + BYTEORDER_HOST_ENDIAN, + NFT_NAME_MAXLEN); + + priority = std_prio_lookup(prio_str, family, hook); if (priority == NF_IP_PRI_LAST) return false; prio->num += priority; @@ -3211,10 +3220,10 @@ static int flowtable_evaluate(struct eval_ctx *ctx, struct flowtable *ft) if (ft->hooknum == NF_INET_NUMHOOKS) return chain_error(ctx, ft, "invalid hook %s", ft->hookstr); - if (!evaluate_priority(&ft->priority, NFPROTO_NETDEV, ft->hooknum)) + if (!evaluate_priority(ctx, &ft->priority, NFPROTO_NETDEV, ft->hooknum)) return __stmt_binary_error(ctx, &ft->priority.loc, NULL, - "'%s' is invalid priority.", - ft->priority.str); + "invalid priority expression %s.", + expr_name(ft->priority.prio_expr)); if (!ft->dev_expr) return chain_error(ctx, ft, "Unbound flowtable not allowed (must specify devices)"); @@ -3410,11 +3419,11 @@ static int chain_evaluate(struct eval_ctx *ctx, struct chain *chain) return chain_error(ctx, chain, "invalid hook %s", chain->hookstr); - if (!evaluate_priority(&chain->priority, chain->handle.family, - chain->hooknum)) + if (!evaluate_priority(ctx, &chain->priority, + chain->handle.family, chain->hooknum)) return __stmt_binary_error(ctx, &chain->priority.loc, NULL, - "'%s' is invalid priority in this context.", - chain->priority.str); + "invalid priority expression %s in this context.", + expr_name(chain->priority.prio_expr)); } list_for_each_entry(rule, &chain->rules, list) { diff --git a/src/parser_bison.y b/src/parser_bison.y index a4905f2..c6a43cf 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -626,8 +626,8 @@ int nft_lex(void *, void *, void *); %type <stmt> meter_stmt meter_stmt_alloc flow_stmt_legacy_alloc %destructor { stmt_free($$); } meter_stmt meter_stmt_alloc flow_stmt_legacy_alloc -%type <expr> symbol_expr verdict_expr integer_expr variable_expr chain_expr -%destructor { expr_free($$); } symbol_expr verdict_expr integer_expr variable_expr chain_expr +%type <expr> symbol_expr verdict_expr integer_expr variable_expr chain_expr prio_expr +%destructor { expr_free($$); } symbol_expr verdict_expr integer_expr variable_expr chain_expr prio_expr %type <expr> primary_expr shift_expr and_expr %destructor { expr_free($$); } primary_expr shift_expr and_expr %type <expr> exclusive_or_expr inclusive_or_expr @@ -1926,30 +1926,39 @@ extended_prio_name : OUT | STRING ; +prio_expr : extended_prio_name + { + $$ = constant_expr_alloc(&@$, &string_type, + BYTEORDER_HOST_ENDIAN, + NFT_NAME_MAXLEN * + BITS_PER_BYTE, $1); + } + ; + extended_prio_spec : int_num { struct prio_spec spec = {0}; spec.num = $1; $$ = spec; } - | extended_prio_name + | prio_expr { struct prio_spec spec = {0}; - spec.str = $1; + spec.prio_expr = $1; $$ = spec; } - | extended_prio_name PLUS NUM + | prio_expr PLUS NUM { struct prio_spec spec = {0}; spec.num = $3; - spec.str = $1; + spec.prio_expr = $1; $$ = spec; } - | extended_prio_name DASH NUM + | prio_expr DASH NUM { struct prio_spec spec = {0}; spec.num = -$3; - spec.str = $1; + spec.prio_expr = $1; $$ = spec; } ; diff --git a/src/rule.c b/src/rule.c index 0a91917..59a97ac 100644 --- a/src/rule.c +++ b/src/rule.c @@ -823,7 +823,7 @@ void chain_free(struct chain *chain) xfree(chain->type); if (chain->dev != NULL) xfree(chain->dev); - xfree(chain->priority.str); + expr_free(chain->priority.prio_expr); xfree(chain); } @@ -2020,7 +2020,7 @@ void flowtable_free(struct flowtable *flowtable) if (--flowtable->refcnt > 0) return; handle_free(&flowtable->handle); - xfree(flowtable->priority.str); + expr_free(flowtable->priority.prio_expr); xfree(flowtable); } -- 2.20.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2 nft WIP] src: introduce prio_expr in chain priority 2019-07-16 9:08 ` [PATCH 1/2 nft WIP] src: introduce prio_expr " Fernando Fernandez Mancera @ 2019-07-16 18:06 ` Pablo Neira Ayuso 2019-07-16 22:42 ` Fernando Fernandez Mancera 0 siblings, 1 reply; 6+ messages in thread From: Pablo Neira Ayuso @ 2019-07-16 18:06 UTC (permalink / raw) To: Fernando Fernandez Mancera; +Cc: netfilter-devel On Tue, Jul 16, 2019 at 11:08:12AM +0200, Fernando Fernandez Mancera wrote: > Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net> > --- > include/rule.h | 8 ++++---- > src/evaluate.c | 29 +++++++++++++++++++---------- > src/parser_bison.y | 25 +++++++++++++++++-------- > src/rule.c | 4 ++-- > 4 files changed, 42 insertions(+), 24 deletions(-) > > diff --git a/include/rule.h b/include/rule.h > index aefb24d..4d7cec8 100644 > --- a/include/rule.h > +++ b/include/rule.h > @@ -173,13 +173,13 @@ enum chain_flags { > * struct prio_spec - extendend priority specification for mixed > * textual/numerical parsing. > * > - * @str: name of the standard priority value > - * @num: Numerical value. This MUST contain the parsed value of str after > + * @prio_expr: expr of the standard priority value > + * @num: Numerical value. This MUST contain the parsed value of prio_expr after > * evaluation. > */ > struct prio_spec { > - const char *str; > - int num; > + struct expr *prio_expr; Use: struct expr *expr; instead. > + int num; You could just store this in the expression, no need for this num field. > struct location loc; > }; > > diff --git a/src/evaluate.c b/src/evaluate.c > index 8086f75..cee65cd 100644 > --- a/src/evaluate.c > +++ b/src/evaluate.c > @@ -3181,15 +3181,24 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set) > return 0; > } > > -static bool evaluate_priority(struct prio_spec *prio, int family, int hook) > +static bool evaluate_priority(struct eval_ctx *ctx, struct prio_spec *prio, > + int family, int hook) > { > int priority; > + char prio_str[NFT_NAME_MAXLEN]; > > /* A numeric value has been used to specify priority. */ > - if (prio->str == NULL) > + if (prio->prio_expr == NULL) prio_expr == NULL never happens. > return true; > > - priority = std_prio_lookup(prio->str, family, hook); > + if (expr_evaluate(ctx, &prio->prio_expr) < 0) > + return false; > + if (prio->prio_expr->etype == EXPR_VALUE) You should bail out here with expr_error() is this is not an EXPR_VALUE. > + mpz_export_data(prio_str, prio->prio_expr->value, > + BYTEORDER_HOST_ENDIAN, > + NFT_NAME_MAXLEN); Remove the branch above, expr_evalute() already deals with transforming the symbol to value expression. > + > + priority = std_prio_lookup(prio_str, family, hook); > if (priority == NF_IP_PRI_LAST) > return false; > prio->num += priority; > @@ -3211,10 +3220,10 @@ static int flowtable_evaluate(struct eval_ctx *ctx, struct flowtable *ft) > if (ft->hooknum == NF_INET_NUMHOOKS) > return chain_error(ctx, ft, "invalid hook %s", ft->hookstr); > > - if (!evaluate_priority(&ft->priority, NFPROTO_NETDEV, ft->hooknum)) > + if (!evaluate_priority(ctx, &ft->priority, NFPROTO_NETDEV, ft->hooknum)) > return __stmt_binary_error(ctx, &ft->priority.loc, NULL, Better use expr_error() here? > - "'%s' is invalid priority.", > - ft->priority.str); > + "invalid priority expression %s.", > + expr_name(ft->priority.prio_expr)); > > if (!ft->dev_expr) > return chain_error(ctx, ft, "Unbound flowtable not allowed (must specify devices)"); > @@ -3410,11 +3419,11 @@ static int chain_evaluate(struct eval_ctx *ctx, struct chain *chain) > return chain_error(ctx, chain, "invalid hook %s", > chain->hookstr); > > - if (!evaluate_priority(&chain->priority, chain->handle.family, > - chain->hooknum)) > + if (!evaluate_priority(ctx, &chain->priority, > + chain->handle.family, chain->hooknum)) > return __stmt_binary_error(ctx, &chain->priority.loc, NULL, > - "'%s' is invalid priority in this context.", > - chain->priority.str); > + "invalid priority expression %s in this context.", > + expr_name(chain->priority.prio_expr)); > } > > list_for_each_entry(rule, &chain->rules, list) { > diff --git a/src/parser_bison.y b/src/parser_bison.y > index a4905f2..c6a43cf 100644 > --- a/src/parser_bison.y > +++ b/src/parser_bison.y > @@ -626,8 +626,8 @@ int nft_lex(void *, void *, void *); > %type <stmt> meter_stmt meter_stmt_alloc flow_stmt_legacy_alloc > %destructor { stmt_free($$); } meter_stmt meter_stmt_alloc flow_stmt_legacy_alloc > > -%type <expr> symbol_expr verdict_expr integer_expr variable_expr chain_expr > -%destructor { expr_free($$); } symbol_expr verdict_expr integer_expr variable_expr chain_expr > +%type <expr> symbol_expr verdict_expr integer_expr variable_expr chain_expr prio_expr > +%destructor { expr_free($$); } symbol_expr verdict_expr integer_expr variable_expr chain_expr prio_expr > %type <expr> primary_expr shift_expr and_expr > %destructor { expr_free($$); } primary_expr shift_expr and_expr > %type <expr> exclusive_or_expr inclusive_or_expr > @@ -1926,30 +1926,39 @@ extended_prio_name : OUT > | STRING > ; > > +prio_expr : extended_prio_name > + { > + $$ = constant_expr_alloc(&@$, &string_type, > + BYTEORDER_HOST_ENDIAN, > + NFT_NAME_MAXLEN * this should be strlen($1) * BITS_PER_BYTE > + BITS_PER_BYTE, $1); > + } > + ; ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2 nft WIP] src: introduce prio_expr in chain priority 2019-07-16 18:06 ` Pablo Neira Ayuso @ 2019-07-16 22:42 ` Fernando Fernandez Mancera 0 siblings, 0 replies; 6+ messages in thread From: Fernando Fernandez Mancera @ 2019-07-16 22:42 UTC (permalink / raw) To: Pablo Neira Ayuso; +Cc: netfilter-devel Hi Pablo, thanks for reviewing. Comments below. On 7/16/19 8:06 PM, Pablo Neira Ayuso wrote: > On Tue, Jul 16, 2019 at 11:08:12AM +0200, Fernando Fernandez Mancera wrote: >> Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net> >> --- >> include/rule.h | 8 ++++---- >> src/evaluate.c | 29 +++++++++++++++++++---------- >> src/parser_bison.y | 25 +++++++++++++++++-------- >> src/rule.c | 4 ++-- >> 4 files changed, 42 insertions(+), 24 deletions(-) >> >> diff --git a/include/rule.h b/include/rule.h >> index aefb24d..4d7cec8 100644 >> --- a/include/rule.h >> +++ b/include/rule.h >> @@ -173,13 +173,13 @@ enum chain_flags { >> * struct prio_spec - extendend priority specification for mixed >> * textual/numerical parsing. >> * >> - * @str: name of the standard priority value >> - * @num: Numerical value. This MUST contain the parsed value of str after >> + * @prio_expr: expr of the standard priority value >> + * @num: Numerical value. This MUST contain the parsed value of prio_expr after >> * evaluation. >> */ >> struct prio_spec { >> - const char *str; >> - int num; >> + struct expr *prio_expr; > > Use: > > struct expr *expr; > > instead. > >> + int num; > > You could just store this in the expression, no need for this num > field. > I think that would not be possible. Right now, the priority specification supports combinations of a string and a number. e.g table inet global { chain prerouting { type filter hook prerouting priority filter + 3 policy accept } } or table inet global { chain prerouting { type filter hook prerouting priority filter - 3 policy accept } } I don't think we are going to be able to do that using only a single "struct expr *". >> struct location loc; >> }; >> >> diff --git a/src/evaluate.c b/src/evaluate.c >> index 8086f75..cee65cd 100644 >> --- a/src/evaluate.c >> +++ b/src/evaluate.c >> @@ -3181,15 +3181,24 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set) >> return 0; >> } >> >> -static bool evaluate_priority(struct prio_spec *prio, int family, int hook) >> +static bool evaluate_priority(struct eval_ctx *ctx, struct prio_spec *prio, >> + int family, int hook) >> { >> int priority; >> + char prio_str[NFT_NAME_MAXLEN]; >> >> /* A numeric value has been used to specify priority. */ >> - if (prio->str == NULL) >> + if (prio->prio_expr == NULL) > > prio_expr == NULL never happens. > It never happens if we only have a single field in the "struct prio_spec". Thanks! ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/2 nft WIP] src: allow variables in chain priority 2019-07-16 9:08 [PATCH 0/2 nft WIP] Using variables in chain priority Fernando Fernandez Mancera 2019-07-16 9:08 ` [PATCH 1/2 nft WIP] src: introduce prio_expr " Fernando Fernandez Mancera @ 2019-07-16 9:08 ` Fernando Fernandez Mancera 2019-07-16 18:07 ` Pablo Neira Ayuso 1 sibling, 1 reply; 6+ messages in thread From: Fernando Fernandez Mancera @ 2019-07-16 9:08 UTC (permalink / raw) To: netfilter-devel; +Cc: Fernando Fernandez Mancera Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net> --- src/parser_bison.y | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/parser_bison.y b/src/parser_bison.y index c6a43cf..d55a5fc 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -1926,7 +1926,8 @@ extended_prio_name : OUT | STRING ; -prio_expr : extended_prio_name +prio_expr : variable_expr + | extended_prio_name { $$ = constant_expr_alloc(&@$, &string_type, BYTEORDER_HOST_ENDIAN, -- 2.20.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2 nft WIP] src: allow variables in chain priority 2019-07-16 9:08 ` [PATCH 2/2 nft WIP] src: allow variables " Fernando Fernandez Mancera @ 2019-07-16 18:07 ` Pablo Neira Ayuso 0 siblings, 0 replies; 6+ messages in thread From: Pablo Neira Ayuso @ 2019-07-16 18:07 UTC (permalink / raw) To: Fernando Fernandez Mancera; +Cc: netfilter-devel On Tue, Jul 16, 2019 at 11:08:14AM +0200, Fernando Fernandez Mancera wrote: > Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net> > --- > src/parser_bison.y | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/src/parser_bison.y b/src/parser_bison.y > index c6a43cf..d55a5fc 100644 > --- a/src/parser_bison.y > +++ b/src/parser_bison.y > @@ -1926,7 +1926,8 @@ extended_prio_name : OUT > | STRING > ; > > -prio_expr : extended_prio_name > +prio_expr : variable_expr > + | extended_prio_name This patch is small and I think it belongs to the previous patch, please squash it to 1/2. Thanks Fernando. ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2019-07-16 22:42 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2019-07-16 9:08 [PATCH 0/2 nft WIP] Using variables in chain priority Fernando Fernandez Mancera 2019-07-16 9:08 ` [PATCH 1/2 nft WIP] src: introduce prio_expr " Fernando Fernandez Mancera 2019-07-16 18:06 ` Pablo Neira Ayuso 2019-07-16 22:42 ` Fernando Fernandez Mancera 2019-07-16 9:08 ` [PATCH 2/2 nft WIP] src: allow variables " Fernando Fernandez Mancera 2019-07-16 18:07 ` Pablo Neira Ayuso
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).