aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/route.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 132737a7c83a..a0fcc47fee73 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -985,6 +985,7 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
985 struct flowi4 fl4; 985 struct flowi4 fl4;
986 struct rtable *rt; 986 struct rtable *rt;
987 struct dst_entry *dst; 987 struct dst_entry *dst;
988 bool new = false;
988 989
989 bh_lock_sock(sk); 990 bh_lock_sock(sk);
990 rt = (struct rtable *) __sk_dst_get(sk); 991 rt = (struct rtable *) __sk_dst_get(sk);
@@ -1000,20 +1001,26 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
1000 rt = ip_route_output_flow(sock_net(sk), &fl4, sk); 1001 rt = ip_route_output_flow(sock_net(sk), &fl4, sk);
1001 if (IS_ERR(rt)) 1002 if (IS_ERR(rt))
1002 goto out; 1003 goto out;
1004
1005 new = true;
1003 } 1006 }
1004 1007
1005 __ip_rt_update_pmtu((struct rtable *) rt->dst.path, &fl4, mtu); 1008 __ip_rt_update_pmtu((struct rtable *) rt->dst.path, &fl4, mtu);
1006 1009
1007 dst = dst_check(&rt->dst, 0); 1010 dst = dst_check(&rt->dst, 0);
1008 if (!dst) { 1011 if (!dst) {
1012 if (new)
1013 dst_release(&rt->dst);
1014
1009 rt = ip_route_output_flow(sock_net(sk), &fl4, sk); 1015 rt = ip_route_output_flow(sock_net(sk), &fl4, sk);
1010 if (IS_ERR(rt)) 1016 if (IS_ERR(rt))
1011 goto out; 1017 goto out;
1012 1018
1013 dst = &rt->dst; 1019 new = true;
1014 } 1020 }
1015 1021
1016 __sk_dst_set(sk, dst); 1022 if (new)
1023 __sk_dst_set(sk, &rt->dst);
1017 1024
1018out: 1025out:
1019 bh_unlock_sock(sk); 1026 bh_unlock_sock(sk);