diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2023-02-15 19:20:22 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2023-02-21 23:57:27 +0100 |
commit | 114ba9606cb5ad85b2215e59f8af8ad97a16cac8 (patch) | |
tree | da264ac99c8972f6e2a2263069b0f7921681f180 /src/optimize.c | |
parent | 2f4935a8d7aeb6b2e019aebb961a579d9950c74a (diff) |
optimize: infer family for nat mapping
Infer family from key in nat mapping, otherwise nat mapping via merge
breaks since family is not specified.
Merging:
fw-test-bug2.nft:4:9-78: iifname enp2s0 ip daddr 72.2.3.66 tcp dport 53122 dnat to 10.1.1.10:22
fw-test-bug2.nft:5:9-77: iifname enp2s0 ip daddr 72.2.3.66 tcp dport 443 dnat to 10.1.1.52:443
fw-test-bug2.nft:6:9-75: iifname enp2s0 ip daddr 72.2.3.70 tcp dport 80 dnat to 10.1.1.52:80
into:
dnat ip to iifname . ip daddr . tcp dport map { enp2s0 . 72.2.3.66 . 53122 : 10.1.1.10 . 22, enp2s0 . 72.2.3.66 . 443 : 10.1.1.52 . 443, enp2s0 . 72.2.3.70 . 80 : 10.1.1.52 . 80 }
Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1657
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/optimize.c')
-rw-r--r-- | src/optimize.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/src/optimize.c b/src/optimize.c index d60aa8f2..35487190 100644 --- a/src/optimize.c +++ b/src/optimize.c @@ -21,6 +21,7 @@ #include <statement.h> #include <utils.h> #include <erec.h> +#include <linux/netfilter.h> #define MAX_STMTS 32 @@ -872,9 +873,9 @@ static void merge_nat(const struct optimize_ctx *ctx, const struct merge *merge) { struct expr *expr, *set, *elem, *nat_expr, *mapping, *left; + int k, family = NFPROTO_UNSPEC; struct stmt *stmt, *nat_stmt; uint32_t i; - int k; k = stmt_nat_find(ctx); assert(k >= 0); @@ -896,9 +897,18 @@ static void merge_nat(const struct optimize_ctx *ctx, stmt = ctx->stmt_matrix[from][merge->stmt[0]]; left = expr_get(stmt->expr->left); + if (left->etype == EXPR_PAYLOAD) { + if (left->payload.desc == &proto_ip) + family = NFPROTO_IPV4; + else if (left->payload.desc == &proto_ip6) + family = NFPROTO_IPV6; + } expr = map_expr_alloc(&internal_location, left, set); nat_stmt = ctx->stmt_matrix[from][k]; + if (nat_stmt->nat.family == NFPROTO_UNSPEC) + nat_stmt->nat.family = family; + expr_free(nat_stmt->nat.addr); nat_stmt->nat.addr = expr; @@ -912,9 +922,9 @@ static void merge_concat_nat(const struct optimize_ctx *ctx, const struct merge *merge) { struct expr *expr, *set, *elem, *nat_expr, *mapping, *left, *concat; + int k, family = NFPROTO_UNSPEC; struct stmt *stmt, *nat_stmt; uint32_t i, j; - int k; k = stmt_nat_find(ctx); assert(k >= 0); @@ -943,11 +953,20 @@ static void merge_concat_nat(const struct optimize_ctx *ctx, for (j = 0; j < merge->num_stmts; j++) { stmt = ctx->stmt_matrix[from][merge->stmt[j]]; left = stmt->expr->left; + if (left->etype == EXPR_PAYLOAD) { + if (left->payload.desc == &proto_ip) + family = NFPROTO_IPV4; + else if (left->payload.desc == &proto_ip6) + family = NFPROTO_IPV6; + } compound_expr_add(concat, expr_get(left)); } expr = map_expr_alloc(&internal_location, concat, set); nat_stmt = ctx->stmt_matrix[from][k]; + if (nat_stmt->nat.family == NFPROTO_UNSPEC) + nat_stmt->nat.family = family; + expr_free(nat_stmt->nat.addr); nat_stmt->nat.addr = expr; |