diff options
-rw-r--r-- | include/statement.h | 2 | ||||
-rw-r--r-- | src/ct.c | 7 | ||||
-rw-r--r-- | src/netlink_delinearize.c | 6 | ||||
-rw-r--r-- | src/netlink_linearize.c | 4 | ||||
-rw-r--r-- | src/parser_bison.y | 17 |
5 files changed, 31 insertions, 5 deletions
diff --git a/include/statement.h b/include/statement.h index 8f874c88..317d53e2 100644 --- a/include/statement.h +++ b/include/statement.h @@ -127,10 +127,12 @@ struct ct_stmt { enum nft_ct_keys key; const struct ct_template *tmpl; struct expr *expr; + int8_t direction; }; extern struct stmt *ct_stmt_alloc(const struct location *loc, enum nft_ct_keys key, + int8_t direction, struct expr *expr); struct dup_stmt { struct expr *to; @@ -404,7 +404,8 @@ void ct_expr_update_type(struct proto_ctx *ctx, struct expr *expr) static void ct_stmt_print(const struct stmt *stmt) { - printf("ct %s set ", ct_templates[stmt->ct.key].token); + ct_print(stmt->ct.key, stmt->ct.direction); + printf(" set "); expr_print(stmt->ct.expr); } @@ -415,7 +416,7 @@ static const struct stmt_ops ct_stmt_ops = { }; struct stmt *ct_stmt_alloc(const struct location *loc, enum nft_ct_keys key, - struct expr *expr) + int8_t direction, struct expr *expr) { struct stmt *stmt; @@ -423,6 +424,8 @@ struct stmt *ct_stmt_alloc(const struct location *loc, enum nft_ct_keys key, stmt->ct.key = key; stmt->ct.tmpl = &ct_templates[key]; stmt->ct.expr = expr; + stmt->ct.direction = direction; + return stmt; } diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 57b8fa51..39347e01 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -659,6 +659,7 @@ static void netlink_parse_ct_stmt(struct netlink_parse_ctx *ctx, uint32_t key; struct stmt *stmt; struct expr *expr; + int8_t dir = -1; sreg = netlink_parse_register(nle, NFTNL_EXPR_CT_SREG); expr = netlink_get_register(ctx, loc, sreg); @@ -666,8 +667,11 @@ static void netlink_parse_ct_stmt(struct netlink_parse_ctx *ctx, return netlink_error(ctx, loc, "ct statement has no expression"); + if (nftnl_expr_is_set(nle, NFTNL_EXPR_CT_DIR)) + dir = nftnl_expr_get_u8(nle, NFTNL_EXPR_CT_DIR); + key = nftnl_expr_get_u32(nle, NFTNL_EXPR_CT_KEY); - stmt = ct_stmt_alloc(loc, key, expr); + stmt = ct_stmt_alloc(loc, key, dir, expr); expr_set_type(expr, stmt->ct.tmpl->dtype, stmt->ct.tmpl->byteorder); ctx->stmt = stmt; diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c index 8849b0e4..48f34c25 100644 --- a/src/netlink_linearize.c +++ b/src/netlink_linearize.c @@ -1151,6 +1151,10 @@ static void netlink_gen_ct_stmt(struct netlink_linearize_ctx *ctx, nle = alloc_nft_expr("ct"); netlink_put_register(nle, NFTNL_EXPR_CT_SREG, sreg); nftnl_expr_set_u32(nle, NFTNL_EXPR_CT_KEY, stmt->ct.key); + if (stmt->ct.direction >= 0) + nftnl_expr_set_u8(nle, NFTNL_EXPR_CT_DIR, + stmt->ct.direction); + nftnl_rule_add_expr(ctx->nlr, nle); } diff --git a/src/parser_bison.y b/src/parser_bison.y index 80ac2bd0..36d46050 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -2977,7 +2977,7 @@ ct_key_dir_optional : BYTES { $$ = NFT_CT_BYTES; } ct_stmt : CT ct_key SET expr { - $$ = ct_stmt_alloc(&@$, $2, $4); + $$ = ct_stmt_alloc(&@$, $2, -1, $4); } | CT STRING SET expr { @@ -2990,7 +2990,20 @@ ct_stmt : CT ct_key SET expr YYERROR; } - $$ = ct_stmt_alloc(&@$, key, $4); + $$ = ct_stmt_alloc(&@$, key, -1, $4); + } + | CT STRING ct_key_dir_optional SET expr + { + struct error_record *erec; + int8_t direction; + + erec = ct_dir_parse(&@$, $2, &direction); + if (erec != NULL) { + erec_queue(erec, state->msgs); + YYERROR; + } + + $$ = ct_stmt_alloc(&@$, $3, direction, $5); } ; |