summaryrefslogtreecommitdiffstats
path: root/src/netlink_delinearize.c
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2017-09-29 13:55:54 +0200
committerFlorian Westphal <fw@strlen.de>2017-09-29 13:55:54 +0200
commit54a0c5dc0f4db879ad2f44fc77bcd2568719be42 (patch)
tree5d5e17e0fca1c3cdd9fd582f17273705f8d6555f /src/netlink_delinearize.c
parent28180991740e6942adfb12650ff2472d73e89387 (diff)
parent26589362c1a3a7c3f0fdb5e70e831bcb4077b0d1 (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.c52
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 */