Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: nat: restore default DNAT behavior

When a DNAT rule is configured via iptables with different port ranges,

iptables -t nat -A PREROUTING -p tcp -d 10.0.0.2 -m tcp --dport 32000:32010
-j DNAT --to-destination 192.168.0.10:21000-21010

we seem to be DNATing to some random port on the LAN side. While this is
expected if --random is passed to the iptables command, it is not
expected without passing --random. The expected behavior (and the
observed behavior prior to the commit in the "Fixes" tag) is the traffic
will be DNAT'd to 192.168.0.10:21000 unless there is a tuple collision
with that destination. In that case, we expect the traffic to be
instead DNAT'd to 192.168.0.10:21001, so on so forth until the end of
the range.

This patch intends to restore the behavior observed prior to the "Fixes"
tag.

Fixes: 6ed5943f8735 ("netfilter: nat: remove l4 protocol port rovers")
Signed-off-by: Kyle Swenson <kyle.swenson@est.tech>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Kyle Swenson and committed by
Pablo Neira Ayuso
0f1ae282 f6374a82

+4 -1
+4 -1
net/netfilter/nf_nat_core.c
··· 551 551 find_free_id: 552 552 if (range->flags & NF_NAT_RANGE_PROTO_OFFSET) 553 553 off = (ntohs(*keyptr) - ntohs(range->base_proto.all)); 554 - else 554 + else if ((range->flags & NF_NAT_RANGE_PROTO_RANDOM_ALL) || 555 + maniptype != NF_NAT_MANIP_DST) 555 556 off = get_random_u16(); 557 + else 558 + off = 0; 556 559 557 560 attempts = range_size; 558 561 if (attempts > NF_NAT_MAX_ATTEMPTS)