diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2019-06-21 10:28:37 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2019-06-21 18:49:07 +0200 |
commit | 7f742d0a9071f932836b4f8525a6d3f7261ae083 (patch) | |
tree | cd972674de9ea2efbd6e39747acd435b100bf154 /src/evaluate.c | |
parent | fb5a36ad5c1032244cf76171648fdefbbe571519 (diff) |
ct: support for NFT_CT_{SRC,DST}_{IP,IP6}
These keys are available since kernel >= 4.17.
You can still use NFT_CT_{SRC,DST}, however, you need to specify 'meta
protocol' in first place to provide layer 3 context.
Note that NFT_CT_{SRC,DST} are broken with set, maps and concatenations.
This patch is implicitly fixing these cases.
If your kernel is < 4.17, you can still use address matching via
explicit meta nfproto:
meta nfproto ipv4 ct original saddr 1.2.3.4
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/evaluate.c')
-rw-r--r-- | src/evaluate.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/src/evaluate.c b/src/evaluate.c index dfdd3c24..19c2d4c6 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -782,7 +782,7 @@ static int ct_gen_nh_dependency(struct eval_ctx *ctx, struct expr *ct) return 0; } - left = ct_expr_alloc(&ct->location, NFT_CT_L3PROTOCOL, ct->ct.direction, ct->ct.nfproto); + left = ct_expr_alloc(&ct->location, NFT_CT_L3PROTOCOL, ct->ct.direction); right = constant_expr_alloc(&ct->location, left->dtype, left->dtype->byteorder, left->len, @@ -803,13 +803,30 @@ static int ct_gen_nh_dependency(struct eval_ctx *ctx, struct expr *ct) */ static int expr_evaluate_ct(struct eval_ctx *ctx, struct expr **expr) { + const struct proto_desc *base, *error; struct expr *ct = *expr; + base = ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc; + switch (ct->ct.key) { case NFT_CT_SRC: case NFT_CT_DST: ct_gen_nh_dependency(ctx, ct); break; + case NFT_CT_SRC_IP: + case NFT_CT_DST_IP: + if (base == &proto_ip6) { + error = &proto_ip; + goto err_conflict; + } + break; + case NFT_CT_SRC_IP6: + case NFT_CT_DST_IP6: + if (base == &proto_ip) { + error = &proto_ip6; + goto err_conflict; + } + break; default: break; } @@ -817,6 +834,12 @@ static int expr_evaluate_ct(struct eval_ctx *ctx, struct expr **expr) ct_expr_update_type(&ctx->pctx, ct); return expr_evaluate_primary(ctx, expr); + +err_conflict: + return stmt_binary_error(ctx, ct, + &ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR], + "conflicting protocols specified: %s vs. %s", + base->name, error->name); } /* |