ipv6: udp: set dst cache for a connected sk if current not valid
A new RTF_CACHE route can be created between ip6_sk_dst_lookup_flow() and ip6_dst_store() calls in udpv6_sendmsg(), when datagram sending results to ICMPV6_PKT_TOOBIG error: udp_v6_send_skb(), for example with vti6 tunnel: vti6_xmit(), get ICMPV6_PKT_TOOBIG error skb_dst_update_pmtu(), can create a RTF_CACHE clone icmpv6_send() ... udpv6_err() ip6_sk_update_pmtu() ip6_update_pmtu(), can create a RTF_CACHE clone ... ip6_datagram_dst_update() ip6_dst_store() And after commit33c162a980
("ipv6: datagram: Update dst cache of a connected datagram sk during pmtu update"), the UDPv6 error handler can update socket's dst cache, but it can happen before the update in the end of udpv6_sendmsg(), preventing getting the new dst cache on the next udpv6_sendmsg() calls. In order to fix it, save dst in a connected socket only if the current socket's dst cache is invalid. The previous patch prepared ip6_sk_dst_lookup_flow() to do that with the new argument, and this patch enables it in udpv6_sendmsg(). Fixes:33c162a980
("ipv6: datagram: Update dst cache of a connected datagram sk during pmtu update") Fixes:45e4fd2668
("ipv6: Only create RTF_CACHE routes after encountering pmtu exception") Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
9f542f616c
commit
4f858c56bd
|
@ -1308,7 +1308,7 @@ do_udp_sendmsg:
|
|||
|
||||
fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);
|
||||
|
||||
dst = ip6_sk_dst_lookup_flow(sk, &fl6, final_p, false);
|
||||
dst = ip6_sk_dst_lookup_flow(sk, &fl6, final_p, connected);
|
||||
if (IS_ERR(dst)) {
|
||||
err = PTR_ERR(dst);
|
||||
dst = NULL;
|
||||
|
@ -1333,7 +1333,7 @@ back_from_confirm:
|
|||
err = PTR_ERR(skb);
|
||||
if (!IS_ERR_OR_NULL(skb))
|
||||
err = udp_v6_send_skb(skb, &fl6);
|
||||
goto release_dst;
|
||||
goto out;
|
||||
}
|
||||
|
||||
lock_sock(sk);
|
||||
|
@ -1367,23 +1367,6 @@ do_append_data:
|
|||
err = np->recverr ? net_xmit_errno(err) : 0;
|
||||
release_sock(sk);
|
||||
|
||||
release_dst:
|
||||
if (dst) {
|
||||
if (connected) {
|
||||
ip6_dst_store(sk, dst,
|
||||
ipv6_addr_equal(&fl6.daddr, &sk->sk_v6_daddr) ?
|
||||
&sk->sk_v6_daddr : NULL,
|
||||
#ifdef CONFIG_IPV6_SUBTREES
|
||||
ipv6_addr_equal(&fl6.saddr, &np->saddr) ?
|
||||
&np->saddr :
|
||||
#endif
|
||||
NULL);
|
||||
} else {
|
||||
dst_release(dst);
|
||||
}
|
||||
dst = NULL;
|
||||
}
|
||||
|
||||
out:
|
||||
dst_release(dst);
|
||||
fl6_sock_release(flowlabel);
|
||||
|
|
Loading…
Reference in a new issue