Commit 9b04f350 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

ipv4: properly update pmtu

Sylvain Munault reported following info :

 - TCP connection get "stuck" with data in send queue when doing
   "large" transfers ( like typing 'ps ax' on a ssh connection )
 - Only happens on path where the PMTU is lower than the MTU of
   the interface
 - Is not present right after boot, it only appears 10-20min after
   boot or so. (and that's inside the _same_ TCP connection, it works
   fine at first and then in the same ssh session, it'll get stuck)
 - Definitely seems related to fragments somehow since I see a router
   sending ICMP message saying fragmentation is needed.
 - Exact same setup works fine with kernel 3.5.1

Problem happens when the 10 minutes (ip_rt_mtu_expires) expiration
period is over.

ip_rt_update_pmtu() calls dst_set_expires() to rearm a new expiration,
but dst_set_expires() does nothing because dst.expires is already set.

It seems we want to set the expires field to a new value, regardless
of prior one.

With help from Julian Anastasov.
Reported-by: default avatarSylvain Munaut <s.munaut@whatever-company.com>
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
CC: Julian Anastasov <ja@ssi.bg>
Tested-by: default avatarSylvain Munaut <s.munaut@whatever-company.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fea7a08a
...@@ -956,7 +956,7 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, ...@@ -956,7 +956,7 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
dst->obsolete = DST_OBSOLETE_KILL; dst->obsolete = DST_OBSOLETE_KILL;
} else { } else {
rt->rt_pmtu = mtu; rt->rt_pmtu = mtu;
dst_set_expires(&rt->dst, ip_rt_mtu_expires); rt->dst.expires = max(1UL, jiffies + ip_rt_mtu_expires);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment