This patch introduces the use of nft input files variables in 'jump' statements, e.g. define dest = chainame add rule ip filter input jump $dest Signed-off-by: Fernando Fernandez Mancera <ffmancera@xxxxxxxxxx> --- include/expression.h | 3 ++- src/expression.c | 14 ++++++++++++-- src/netlink.c | 6 +++--- src/parser_bison.y | 16 ++++++++++------ 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/include/expression.h b/include/expression.h index 6416ac0..0379eba 100644 --- a/include/expression.h +++ b/include/expression.h @@ -403,7 +403,8 @@ extern void relational_expr_pctx_update(struct proto_ctx *ctx, const struct expr *expr); extern struct expr *verdict_expr_alloc(const struct location *loc, - int verdict, const char *chain); + int verdict, const char *chain, + struct expr *variable); extern struct expr *symbol_expr_alloc(const struct location *loc, enum symbol_types type, struct scope *scope, diff --git a/src/expression.c b/src/expression.c index eece12e..7956a9c 100644 --- a/src/expression.c +++ b/src/expression.c @@ -236,15 +236,25 @@ static const struct expr_ops verdict_expr_ops = { }; struct expr *verdict_expr_alloc(const struct location *loc, - int verdict, const char *chain) + int verdict, const char *chain, + struct expr *variable) { + struct symbol *sym; struct expr *expr; + char *sym_chain; expr = expr_alloc(loc, EXPR_VERDICT, &verdict_type, BYTEORDER_INVALID, 0); expr->verdict = verdict; - if (chain != NULL) + if (chain != NULL) { expr->chain = chain; + } else if (variable != NULL) { + sym = variable->sym; + if (sym->expr->value) + expr->chain = mpz_get_str(NULL, 10, sym->expr->value); + //printf("%s", expr->chain); + } + printf("%s", expr->chain); expr->flags = EXPR_F_CONSTANT | EXPR_F_SINGLETON; return expr; } diff --git a/src/netlink.c b/src/netlink.c index c051ae6..ce1a8c4 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -265,7 +265,7 @@ static struct expr *netlink_alloc_verdict(const struct location *loc, break; } - return verdict_expr_alloc(loc, nld->verdict, chain); + return verdict_expr_alloc(loc, nld->verdict, chain, NULL); } struct expr *netlink_alloc_data(const struct location *loc, @@ -1160,7 +1160,7 @@ static void trace_print_verdict(const struct nftnl_trace *nlt, verdict = nftnl_trace_get_u32(nlt, NFTNL_TRACE_VERDICT); if (nftnl_trace_is_set(nlt, NFTNL_TRACE_JUMP_TARGET)) chain = xstrdup(nftnl_trace_get_str(nlt, NFTNL_TRACE_JUMP_TARGET)); - expr = verdict_expr_alloc(&netlink_location, verdict, chain); + expr = verdict_expr_alloc(&netlink_location, verdict, chain, NULL); nft_print(octx, "verdict "); expr_print(expr, octx); @@ -1175,7 +1175,7 @@ static void trace_print_policy(const struct nftnl_trace *nlt, policy = nftnl_trace_get_u32(nlt, NFTNL_TRACE_POLICY); - expr = verdict_expr_alloc(&netlink_location, policy, NULL); + expr = verdict_expr_alloc(&netlink_location, policy, NULL, NULL); nft_print(octx, "policy "); expr_print(expr, octx); diff --git a/src/parser_bison.y b/src/parser_bison.y index 9aea652..7f131ad 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -3817,27 +3817,31 @@ relational_op : EQ { $$ = OP_EQ; } verdict_expr : ACCEPT { - $$ = verdict_expr_alloc(&@$, NF_ACCEPT, NULL); + $$ = verdict_expr_alloc(&@$, NF_ACCEPT, NULL, NULL); } | DROP { - $$ = verdict_expr_alloc(&@$, NF_DROP, NULL); + $$ = verdict_expr_alloc(&@$, NF_DROP, NULL, NULL); } | CONTINUE { - $$ = verdict_expr_alloc(&@$, NFT_CONTINUE, NULL); + $$ = verdict_expr_alloc(&@$, NFT_CONTINUE, NULL, NULL); + } + | JUMP variable_expr + { + $$ = verdict_expr_alloc(&@$, NFT_JUMP, NULL, $2); } | JUMP identifier { - $$ = verdict_expr_alloc(&@$, NFT_JUMP, $2); + $$ = verdict_expr_alloc(&@$, NFT_JUMP, $2, NULL); } | GOTO identifier { - $$ = verdict_expr_alloc(&@$, NFT_GOTO, $2); + $$ = verdict_expr_alloc(&@$, NFT_GOTO, $2, NULL); } | RETURN { - $$ = verdict_expr_alloc(&@$, NFT_RETURN, NULL); + $$ = verdict_expr_alloc(&@$, NFT_RETURN, NULL, NULL); } ; -- 2.20.1