diff options
author | Florian Westphal <fw@strlen.de> | 2016-01-04 20:53:43 +0100 |
---|---|---|
committer | Florian Westphal <fw@strlen.de> | 2016-01-04 20:53:43 +0100 |
commit | 7ad9e1f8ad4ba637be841d0573bdfdcf397f0815 (patch) | |
tree | 1c700561baa465690fb3eb41e1abeab9ac13367d /src/ct.c | |
parent | b99ec85e32947e337681aef8a29eae1c4c10f14e (diff) |
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 <fw@strlen.de>
Diffstat (limited to 'src/ct.c')
-rw-r--r-- | src/ct.c | 40 |
1 files changed, 37 insertions, 3 deletions
@@ -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: |