--- zzzz-none-000/linux-4.4.271/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c 2021-06-03 06:22:09.000000000 +0000 +++ hawkeye-5590-750/linux-4.4.271/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c 2023-04-19 10:22:30.000000000 +0000 @@ -25,6 +25,9 @@ #include #include #include +#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) +#include +#endif static const struct nf_nat_l3proto nf_nat_l3proto_ipv4; @@ -297,6 +300,32 @@ } /* Fall thru... (Only ICMPs can be IP_CT_IS_REPLY) */ 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. */ @@ -307,7 +336,7 @@ if (ret != NF_ACCEPT) return ret; - if (nf_nat_initialized(ct, HOOK2MANIP(state->hook))) + if (nf_nat_initialized(ct, maniptype)) break; ret = nf_nat_alloc_null_binding(ct, state->hook);