Skip to content

Commit 4f858c5

Browse files
akodanevdavem330
authored andcommitted
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 commit 33c162a ("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: 33c162a ("ipv6: datagram: Update dst cache of a connected datagram sk during pmtu update") Fixes: 45e4fd2 ("ipv6: Only create RTF_CACHE routes after encountering pmtu exception") Signed-off-by: Alexey Kodanev <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 9f542f6 commit 4f858c5

File tree

1 file changed

+2
-19
lines changed

1 file changed

+2
-19
lines changed

net/ipv6/udp.c

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,7 +1308,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
13081308

13091309
fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);
13101310

1311-
dst = ip6_sk_dst_lookup_flow(sk, &fl6, final_p, false);
1311+
dst = ip6_sk_dst_lookup_flow(sk, &fl6, final_p, connected);
13121312
if (IS_ERR(dst)) {
13131313
err = PTR_ERR(dst);
13141314
dst = NULL;
@@ -1333,7 +1333,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
13331333
err = PTR_ERR(skb);
13341334
if (!IS_ERR_OR_NULL(skb))
13351335
err = udp_v6_send_skb(skb, &fl6);
1336-
goto release_dst;
1336+
goto out;
13371337
}
13381338

13391339
lock_sock(sk);
@@ -1367,23 +1367,6 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
13671367
err = np->recverr ? net_xmit_errno(err) : 0;
13681368
release_sock(sk);
13691369

1370-
release_dst:
1371-
if (dst) {
1372-
if (connected) {
1373-
ip6_dst_store(sk, dst,
1374-
ipv6_addr_equal(&fl6.daddr, &sk->sk_v6_daddr) ?
1375-
&sk->sk_v6_daddr : NULL,
1376-
#ifdef CONFIG_IPV6_SUBTREES
1377-
ipv6_addr_equal(&fl6.saddr, &np->saddr) ?
1378-
&np->saddr :
1379-
#endif
1380-
NULL);
1381-
} else {
1382-
dst_release(dst);
1383-
}
1384-
dst = NULL;
1385-
}
1386-
13871370
out:
13881371
dst_release(dst);
13891372
fl6_sock_release(flowlabel);

0 commit comments

Comments
 (0)