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/netlink_delinearize.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/netlink_delinearize.c')
-rw-r--r-- | src/netlink_delinearize.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index f68fca09..769321aa 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -536,12 +536,16 @@ static void netlink_parse_ct_expr(struct netlink_parse_ctx *ctx, const struct location *loc, const struct nftnl_expr *nle) { + struct expr *expr = NULL; enum nft_registers dreg; + int8_t dir = -1; uint32_t key; - struct expr *expr; + + 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); - expr = ct_expr_alloc(loc, key); + expr = ct_expr_alloc(loc, key, dir); dreg = netlink_parse_register(nle, NFTNL_EXPR_CT_DREG); netlink_set_register(ctx, dreg, expr); @@ -1117,6 +1121,12 @@ static void meta_match_postprocess(struct rule_pp_ctx *ctx, } } +static void ct_match_postprocess(struct rule_pp_ctx *ctx, + const struct expr *expr) +{ + return meta_match_postprocess(ctx, expr); +} + /* Convert a bitmask to a prefix length */ static unsigned int expr_mask_to_prefix(const struct expr *expr) { @@ -1394,6 +1404,9 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp) expr_postprocess(ctx, &expr->right); switch (expr->left->ops->type) { + case EXPR_CT: + ct_match_postprocess(ctx, expr); + break; case EXPR_META: meta_match_postprocess(ctx, expr); break; @@ -1431,9 +1444,11 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp) case EXPR_SET_REF: case EXPR_EXTHDR: case EXPR_META: - case EXPR_CT: case EXPR_VERDICT: break; + case EXPR_CT: + ct_expr_update_type(&ctx->pctx, expr); + break; default: BUG("unknown expression type %s\n", expr->ops->name); } |