On Fri, May 30, 2025 at 7:21 AM Florian Westphal <fw@xxxxxxxxx> wrote: > > Shaun Brady <brady.1345@xxxxxxxxx> wrote: > > On Wed, May 28, 2025 at 05:03:56PM +0800, Yafang Shao wrote: > > > diff --git a/net/netfilter/nf_conntrack_core.c > > > b/net/netfilter/nf_conntrack_core.c > > > index 7bee5bd22be2..3481e9d333b0 100644 > > > --- a/net/netfilter/nf_conntrack_core.c > > > +++ b/net/netfilter/nf_conntrack_core.c > > > @@ -1245,9 +1245,9 @@ __nf_conntrack_confirm(struct sk_buff *skb) > > > > > > chainlen = 0; > > > hlist_nulls_for_each_entry(h, n, > > > &nf_conntrack_hash[reply_hash], hnnode) { > > > - if (nf_ct_key_equal(h, &ct->tuplehash[IP_CT_DIR_REPLY].tuple, > > > - zone, net)) > > > - goto out; > > > + //if (nf_ct_key_equal(h, &ct->tuplehash[IP_CT_DIR_REPLY].tuple, > > > + // zone, net)) > > > + // goto out; > > > if (chainlen++ > max_chainlen) { > > > chaintoolong: > > > NF_CT_STAT_INC(net, chaintoolong); > > > > Forgive me for jumping in with very little information, but on a hunch I > > tried something. I applied the above patch to another bug I've been > > investigating: > > > > https://bugzilla.netfilter.org/show_bug.cgi?id=1795 > > and Ubuntu reference > > https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2109889 > > > > The Ubuntu reproduction steps where easier to follow, so I mimicked > > them: > > > > # cat add_ip.sh > > ip addr add 10.0.1.200/24 dev enp1s0 > > # cat nft.sh > > nft -f - <<EOF > > table ip dnat-test { > > chain prerouting { > > type nat hook prerouting priority dstnat; policy accept; > > ip daddr 10.0.1.200 udp dport 1234 counter dnat to 10.0.1.180:1234 > > } > > } > > EOF > > # cat listen.sh > > echo pong|nc -l -u 10.0.1.180 1234 > > # ./add_ip.sh ; ./nft.sh ; listen.sh (and then just ./listen.sh again) > > We don't have a selftest for this, I'll add one. > > Following patch should help, we fail to check for reverse collision > before concluding we don't need PAT to handle this. > > diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c > --- a/net/netfilter/nf_nat_core.c > +++ b/net/netfilter/nf_nat_core.c > @@ -248,7 +248,7 @@ static noinline bool > nf_nat_used_tuple_new(const struct nf_conntrack_tuple *tuple, > const struct nf_conn *ignored_ct) > { > - static const unsigned long uses_nat = IPS_NAT_MASK | IPS_SEQ_ADJUST_BIT; > + static const unsigned long uses_nat = IPS_NAT_MASK | IPS_SEQ_ADJUST; > const struct nf_conntrack_tuple_hash *thash; > const struct nf_conntrack_zone *zone; > struct nf_conn *ct; > @@ -287,8 +287,14 @@ nf_nat_used_tuple_new(const struct nf_conntrack_tuple *tuple, > zone = nf_ct_zone(ignored_ct); > > thash = nf_conntrack_find_get(net, zone, tuple); > - if (unlikely(!thash)) /* clashing entry went away */ > - return false; > + if (unlikely(!thash)) { > + struct nf_conntrack_tuple reply; > + > + nf_ct_invert_tuple(&reply, tuple); > + thash = nf_conntrack_find_get(net, zone, &reply); > + if (!thash) /* clashing entry went away */ > + return false; > + } > > ct = nf_ct_tuplehash_to_ctrack(thash); > JFYI After applying this additional patch, the NAT source port is reallocated to a new random port again in my case. -- Regards Yafang