After route cache is flushed via ipv4_sysctl_rtcache_flush(), we forget
to reset fnhe_mtu_locked in rt_bind_exception(). When pmtu is updated
in __ip_rt_update_pmtu(), it will return directly since the pmtu is
still locked. e.g.

+ ip netns exec client ping 10.10.1.1 -c 1 -s 1400 -M do
PING 10.10.1.1 (10.10.1.1) 1400(1428) bytes of data.
>From 10.10.0.254 icmp_seq=1 Frag needed and DF set (mtu = 0)

--- 10.10.1.1 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

+ ip netns exec client ip route get 10.10.1.1
10.10.1.1 via 10.10.0.254 dev veth0_c src 10.10.0.1 uid 0
    cache expires 599sec mtu lock 552
+ ip netns exec client ip route flush cache
+ ip netns exec client ip route get 10.10.1.1
10.10.1.1 via 10.10.0.254 dev veth0_c src 10.10.0.1 uid 0
    cache
+ ip netns exec client ping 10.10.1.1 -c 1 -s 1400 -M do
PING 10.10.1.1 (10.10.1.1) 1400(1428) bytes of data.
ping: local error: Message too long, mtu=576

--- 10.10.1.1 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

+ ip netns exec client ip route get 10.10.1.1
10.10.1.1 via 10.10.0.254 dev veth0_c src 10.10.0.1 uid 0
    cache

Fixes: d52e5a7e7ca49 ("ipv4: lock mtu in fnhe when received PMTU < 
net.ipv4.route.min_pmtu")
Reported-by: Jianlin Shi <[email protected]>
Reviewed-by: Stefano Brivio <[email protected]>
Signed-off-by: Hangbin Liu <[email protected]>
---
 net/ipv4/route.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 1412a7b..29268ef 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1375,6 +1375,7 @@ static bool rt_bind_exception(struct rtable *rt, struct 
fib_nh_exception *fnhe,
                        fnhe->fnhe_gw = 0;
                        fnhe->fnhe_pmtu = 0;
                        fnhe->fnhe_expires = 0;
+                       fnhe->fnhe_mtu_locked = false;
                        fnhe_flush_routes(fnhe);
                        orig = NULL;
                }
-- 
2.5.5

Reply via email to