On Tue, 2012-08-21 at 20:18 +0300, Julian Anastasov wrote:
Hello,
On Tue, 21 Aug 2012, Eric Dumazet wrote:
quoted
My first patch was :
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index e4ba974..9858714 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -956,6 +956,7 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
dst->obsolete = DST_OBSOLETE_KILL;
} else {
rt->rt_pmtu = mtu;
+ rt->dst.expires = 0;
dst_set_expires(&rt->dst, ip_rt_mtu_expires);
This is better, does not break ipv4_link_failure.
There is a little race some ipv4_mtu() user to see
rt_pmtu != 0 and dst.expires = 0 and to fail in time_after_eq
test. May be that is why dst.expires is never set to 0.
But I still don't understand what both changes fix.
In fact we re-enter ip_rt_update_pmtu() if we receive a second ICMP,
and rt->rt_pmtu is already set, but dst is expired.
Thats why Sylvain said it was not happening in the 10 minutes following
boot.
So calling again dst_set_expires(&rt->dst, ip_rt_mtu_expires) does
nothing : rt_pmtu is ignored because dst.expires is too old.
Maybe we should just do :
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index e4ba974..d0181e2 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -952,7 +952,7 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
ip_rt_build_flow_key(&fl4, sk, skb);
mtu = __ip_rt_update_pmtu(rt, &fl4, mtu);
- if (!rt->rt_pmtu) {
+ if (!rt->rt_pmtu || time_after_eq(jiffies, rt->dst.expires)) {
dst->obsolete = DST_OBSOLETE_KILL;
} else {
rt->rt_pmtu = mtu;