summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/statement.h2
-rw-r--r--src/ct.c7
-rw-r--r--src/netlink_delinearize.c6
-rw-r--r--src/netlink_linearize.c4
-rw-r--r--src/parser_bison.y17
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;
diff --git a/src/ct.c b/src/ct.c
index 3a6a4e57..83fceff6 100644
--- a/src/ct.c
+++ b/src/ct.c
@@ -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);
}
;