--- zzzz-none-000/linux-5.4.213/net/netfilter/nf_nat_core.c 2022-09-15 10:04:56.000000000 +0000 +++ miami-7690-761/linux-5.4.213/net/netfilter/nf_nat_core.c 2024-05-29 11:20:02.000000000 +0000 @@ -24,6 +24,7 @@ #include #include #include +#include #include "nf_internals.h" @@ -604,10 +605,6 @@ struct net *net = nf_ct_net(ct); struct nf_conntrack_tuple curr_tuple, new_tuple; - /* Can't setup nat info for confirmed ct. */ - if (nf_ct_is_confirmed(ct)) - return NF_ACCEPT; - WARN_ON(maniptype != NF_NAT_MANIP_SRC && maniptype != NF_NAT_MANIP_DST); @@ -624,6 +621,13 @@ get_unique_tuple(&new_tuple, &curr_tuple, range, ct, maniptype); +#if IS_ENABLED(CONFIG_NF_NAT_TRY_NEXT_RULE) + if (curr_tuple.src.u.all != 0 && curr_tuple.dst.u.all != 0 && + new_tuple.src.u.all != 0 && new_tuple.dst.u.all != 0 && + nf_nat_used_tuple(&new_tuple, ct)) + return XT_CONTINUE; +#endif + if (!nf_ct_tuple_equal(&new_tuple, &curr_tuple)) { struct nf_conntrack_tuple reply; @@ -745,6 +749,30 @@ case IP_CT_RELATED_REPLY: /* Only ICMPs can be IP_CT_IS_REPLY. Fallthrough */ case IP_CT_NEW: +#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) + /* when skb is forwarding between ports of a bridge,the + * nf_bridge will be set and nf_bridge->physoutdev is not null, + * We can assume that it is not expecting NAT operation. + * when BR_HOOK is enabled, multicast packets will reach + * postrouting twice,the first time is when it is forwarded + * between ports of a bridge, the second time is that it is + * forwarded to upstream port. + * + * It will perform traversing of the NAT table at the first + * time, the next time, it will use the result of first time. + * since forwarding betweeng ports of a bridge, it won't hit + * rules of SNAT, it cause NO NAT operation on this skb when + * forwarding to the upstream port. + * To avoid the scenario above, accept it when it is forwarding + * between ports of a bridge for multicast. + */ + if (skb->pkt_type == PACKET_MULTICAST) { + struct nf_bridge_info *nf_bridge = + nf_bridge_info_get(skb); + if (nf_bridge && nf_bridge->physoutdev) + return NF_ACCEPT; + } +#endif /* Seen it before? This can happen for loopback, retrans, * or local packets. */