From 7ad9e1f8ad4ba637be841d0573bdfdcf397f0815 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Mon, 4 Jan 2016 20:53:43 +0100 Subject: ct: add support for directional keys A few keys in the ct expression are directional, i.e. we need to tell kernel if it should fetch REPLY or ORIGINAL direction. Split ct_keys into ct_keys & ct_keys_dir, the latter are those keys that the kernel rejects unless also given a direction. During postprocessing we also need to invoke ct_expr_update_type, problem is that e.g. ct saddr can be any family (ip, ipv6) so we need to update the expected data type based on the network base. Signed-off-by: Florian Westphal --- src/ct.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) (limited to 'src/ct.c') diff --git a/src/ct.c b/src/ct.c index aa801388..07e7077b 100644 --- a/src/ct.c +++ b/src/ct.c @@ -207,17 +207,34 @@ static const struct ct_template ct_templates[] = { static void ct_expr_print(const struct expr *expr) { + const struct symbolic_constant *s; + printf("ct %s", ct_templates[expr->ct.key].token); + + if (expr->ct.direction < 0) + return; + + for (s = ct_dir_tbl.symbols; s->identifier != NULL; s++) { + if (expr->ct.direction == (int) s->value) { + printf(" %s", s->identifier); + return; + } + } + + printf(" %d", expr->ct.direction); } static bool ct_expr_cmp(const struct expr *e1, const struct expr *e2) { - return e1->ct.key == e2->ct.key; + if (e1->ct.key != e2->ct.key) + return false; + + return e1->ct.direction == e2->ct.direction; } static void ct_expr_clone(struct expr *new, const struct expr *expr) { - new->ct.key = expr->ct.key; + new->ct = expr->ct; } static void ct_expr_pctx_update(struct proto_ctx *ctx, const struct expr *expr) @@ -249,7 +266,23 @@ static const struct expr_ops ct_expr_ops = { .pctx_update = ct_expr_pctx_update, }; -struct expr *ct_expr_alloc(const struct location *loc, enum nft_ct_keys key) +struct error_record *ct_dir_parse(const struct location *loc, const char *str, + int8_t *direction) +{ + const struct symbolic_constant *s; + + for (s = ct_dir_tbl.symbols; s->identifier != NULL; s++) { + if (!strcmp(str, s->identifier)) { + *direction = s->value; + return NULL; + } + } + + return error(loc, "Could not parse direction %s", str); +} + +struct expr *ct_expr_alloc(const struct location *loc, enum nft_ct_keys key, + int8_t direction) { const struct ct_template *tmpl = &ct_templates[key]; struct expr *expr; @@ -257,6 +290,7 @@ struct expr *ct_expr_alloc(const struct location *loc, enum nft_ct_keys key) expr = expr_alloc(loc, &ct_expr_ops, tmpl->dtype, tmpl->byteorder, tmpl->len); expr->ct.key = key; + expr->ct.direction = direction; switch (key) { case NFT_CT_PROTOCOL: -- cgit v1.2.3