diff options
author | Florian Westphal <fw@strlen.de> | 2017-09-29 13:55:54 +0200 |
---|---|---|
committer | Florian Westphal <fw@strlen.de> | 2017-09-29 13:55:54 +0200 |
commit | 54a0c5dc0f4db879ad2f44fc77bcd2568719be42 (patch) | |
tree | 5d5e17e0fca1c3cdd9fd582f17273705f8d6555f /src/netlink_delinearize.c | |
parent | 28180991740e6942adfb12650ff2472d73e89387 (diff) | |
parent | 26589362c1a3a7c3f0fdb5e70e831bcb4077b0d1 (diff) |
Merge branch 'ct_rt_syntax_06'
inet family (and others, e.g. bridge) lack context to figure out the
layer 3 address type.
examples:
ct original saddr $addr
rt nexthop $addr
We can't use $addr, because it might be a set reference, e.g.
ct original saddr @whitelist
currently implemented workaround is to use 'meta nfproto' to provide the
l3 context, e.g.
meta nfproto ip rt nexthop 10.2.3.4
i.e. users need to fill dependency manually.
Pablo suggested to instead specify ip saddr, ip6 saddr:
ct original ip saddr $address
and then let nft handle the dependency injection, these changes do this.
Old syntax is preserved.
Signed-off-by: Florian Westphal <fw@strlen.de>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/netlink_delinearize.c')
-rw-r--r-- | src/netlink_delinearize.c | 52 |
1 files changed, 23 insertions, 29 deletions
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 42206ebc..44328879 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -716,7 +716,7 @@ static void netlink_parse_ct_expr(struct netlink_parse_ctx *ctx, 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, dir); + expr = ct_expr_alloc(loc, key, dir, NFPROTO_UNSPEC); dreg = netlink_parse_register(nle, NFTNL_EXPR_CT_DREG); netlink_set_register(ctx, dreg, expr); @@ -1385,12 +1385,29 @@ static void payload_match_postprocess(struct rule_pp_ctx *ctx, } } -static void ct_meta_common_postprocess(const struct expr *expr) +static void ct_meta_common_postprocess(struct rule_pp_ctx *ctx, + const struct expr *expr, + enum proto_bases base) { const struct expr *left = expr->left; struct expr *right = expr->right; switch (expr->op) { + case OP_EQ: + if (expr->right->ops->type == EXPR_RANGE) + break; + + expr->left->ops->pctx_update(&ctx->pctx, expr); + + if (ctx->pdctx.pbase == PROTO_BASE_INVALID && + left->flags & EXPR_F_PROTOCOL) { + payload_dependency_store(&ctx->pdctx, ctx->stmt, base); + } else if (ctx->pdctx.pbase < PROTO_BASE_TRANSPORT_HDR) { + __payload_dependency_kill(&ctx->pdctx, base); + if (left->flags & EXPR_F_PROTOCOL) + payload_dependency_store(&ctx->pdctx, ctx->stmt, base); + } + break; case OP_NEQ: if (right->ops->type != EXPR_SET && right->ops->type != EXPR_SET_REF) break; @@ -1406,40 +1423,17 @@ static void ct_meta_common_postprocess(const struct expr *expr) static void meta_match_postprocess(struct rule_pp_ctx *ctx, const struct expr *expr) { - struct expr *left = expr->left; - - switch (expr->op) { - case OP_EQ: - if (expr->right->ops->type == EXPR_RANGE) - break; - - expr->left->ops->pctx_update(&ctx->pctx, expr); + const struct expr *left = expr->left; - if (ctx->pdctx.pbase == PROTO_BASE_INVALID && - left->flags & EXPR_F_PROTOCOL) - payload_dependency_store(&ctx->pdctx, ctx->stmt, - left->meta.base); - break; - default: - ct_meta_common_postprocess(expr); - break; - } + ct_meta_common_postprocess(ctx, expr, left->meta.base); } static void ct_match_postprocess(struct rule_pp_ctx *ctx, const struct expr *expr) { - switch (expr->op) { - case OP_EQ: - if (expr->right->ops->type == EXPR_RANGE) - break; + const struct expr *left = expr->left; - expr->left->ops->pctx_update(&ctx->pctx, expr); - break; - default: - ct_meta_common_postprocess(expr); - break; - } + ct_meta_common_postprocess(ctx, expr, left->ct.base); } /* Convert a bitmask to a prefix length */ |