[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20191203021137.26809-1-liuhangbin@gmail.com>
Date: Tue, 3 Dec 2019 10:11:37 +0800
From: Hangbin Liu <liuhangbin@...il.com>
To: netdev@...r.kernel.org
Cc: Julian Anastasov <ja@....bg>,
Marcelo Ricardo Leitner <marcelo.leitner@...il.com>,
David Ahern <dsahern@...il.com>,
Eric Dumazet <edumazet@...gle.com>,
David Miller <davem@...emloft.net>,
Hangbin Liu <liuhangbin@...il.com>
Subject: [PATCHv2 net] ipv6/route: should not update neigh confirm time during PMTU update
When we setup a pair of gretap, ping each other and create neighbour cache.
Then delete and recreate one side. We will never be able to ping6 to the new
created gretap.
The reason is when we ping6 remote via gretap, we will call like
gre_tap_xmit()
- ip_tunnel_xmit()
- tnl_update_pmtu()
- skb_dst_update_pmtu()
- ip6_rt_update_pmtu()
- __ip6_rt_update_pmtu()
- dst_confirm_neigh()
- ip6_confirm_neigh()
- __ipv6_confirm_neigh()
- n->confirmed = now
As the confirmed time updated, in neigh_timer_handler() the check for
NUD_DELAY confirm time will pass and the neigh state will back to
NUD_REACHABLE. So the old/wrong mac address will be used again.
If we do not update the confirmed time, the neigh state will go to
neigh->nud_state = NUD_PROBE; then go to NUD_FAILED and re-create the
neigh later, which is what IPv4 does.
Fix it by removing the dst_confirm_neigh() in __ip6_rt_update_pmtu() as
there is no two-way communication during PMTU update.
v2: remove dst_confirm_neigh directly as David Miller pointed out.
Fixes: 0dec879f636f ("net: use dst_confirm_neigh for UDP, RAW, ICMP, L2TP")
Reported-by: Jianlin Shi <jishi@...hat.com>
Suggested-by: David Miller <davem@...emloft.net>
Signed-off-by: Hangbin Liu <liuhangbin@...il.com>
---
net/ipv6/route.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index b59940416cb5..335ed36a5c78 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2710,7 +2710,6 @@ static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk,
daddr = NULL;
saddr = NULL;
}
- dst_confirm_neigh(dst, daddr);
mtu = max_t(u32, mtu, IPV6_MIN_MTU);
if (mtu >= dst_mtu(dst))
return;
--
2.19.2
Powered by blists - more mailing lists