Given following setup: -modprobe br_netfilter -echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables -brctl addbr br0 -brctl addif br0 enp2s0 -brctl addif br0 enp3s0 -brctl addif br0 enp6s0 -ifconfig enp2s0 mtu 1300 -ifconfig enp3s0 mtu 1500 -ifconfig enp6s0 mtu 1500 -ifconfig br0 up multi-port mtu1500 - mtu1500|bridge|1500 - mtu1500 A | B mtu1300 With netfilter defragmentation/conntrack enabled, fragmented packets from A will be defragmented in prerouting, and refragmented at postrouting. But in this scenario the bridge found the frag_max_size(1500) is larger than the dst mtu stored in the fake_rtable whitch is always equal to the bridge's mtu 1300, then packets will be dopped. This modifies ip_skb_dst_mtu to use the out dev's mtu instead of bridge's mtu in bridge refragment. Signed-off-by: Rundong Ge <rdong.ge@xxxxxxxxx> --- include/net/ip.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/net/ip.h b/include/net/ip.h index 29d89de..0512de3 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -450,6 +450,8 @@ static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst, static inline unsigned int ip_skb_dst_mtu(struct sock *sk, const struct sk_buff *skb) { + if ((skb_dst(skb)->flags & DST_FAKE_RTABLE) && skb->dev) + return min(skb->dev->mtu, IP_MAX_MTU); if (!sk || !sk_fullsock(sk) || ip_sk_use_pmtu(sk)) { bool forwarding = IPCB(skb)->flags & IPSKB_FORWARDED; -- 1.8.3.1