Thread (12 messages) 12 messages, 3 authors, 2026-04-01
STALE66d

[PATCH net-next v3 3/4] udp: Preserve destination address info after abort

From: Jordan Rife <hidden>
Date: 2026-03-30 21:57:15
Also in: bpf
Subsystem: networking [general], the rest, user datagram protocol (udp) · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds, Willem de Bruijn

For explicit disconnections using connect(AF_UNSPEC) behavior remains
unchanged while udp_abort now avoids clearing inet_daddr and inet_dport.
This is safe to do without changing behavior elsewhere, since lookups
only consult these fields if the socket is currently connected (sk_state
== TCP_ESTABLISHED). The behavior of getpeername doesn't change w.r.t.
aborted sockets, since it returns -ENOTCONN as long as sk_state ==
TCP_CLOSE. Behavior of BPF socket iterators and /proc/net/udp /do/
change with both now seeing the non-cleared daddr+dport pair after
an abort. Behavior of BPF socket lookup helpers which invoke
__udp*_lib_lookup don't change, since the result of compute_score should
be the same as before.

Reported-by: Yusuke Suzuki <redacted>
Signed-off-by: Jordan Rife <redacted>
---
 net/ipv4/udp.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 6e5ba2ce9314..043496a249ca 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2207,7 +2207,7 @@ static int udp_connect(struct sock *sk, struct sockaddr_unsized *uaddr,
 	return res;
 }
 
-int __udp_disconnect(struct sock *sk, int flags)
+static int ___udp_disconnect(struct sock *sk, int flags, bool clear_dest)
 {
 	struct inet_sock *inet = inet_sk(sk);
 	/*
@@ -2215,8 +2215,10 @@ int __udp_disconnect(struct sock *sk, int flags)
 	 */
 
 	sk->sk_state = TCP_CLOSE;
-	inet->inet_daddr = 0;
-	inet->inet_dport = 0;
+	if (clear_dest) {
+		inet->inet_daddr = 0;
+		inet->inet_dport = 0;
+	}
 	sock_rps_reset_rxhash(sk);
 	sk->sk_bound_dev_if = 0;
 	if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) {
@@ -2233,14 +2235,19 @@ int __udp_disconnect(struct sock *sk, int flags)
 	sk_dst_reset(sk);
 	return 0;
 }
+
+int __udp_disconnect(struct sock *sk, int flags)
+{
+	return ___udp_disconnect(sk, flags, true);
+}
 EXPORT_SYMBOL(__udp_disconnect);
 
-static int udp_disconnect_unhash4(struct sock *sk, int flags)
+static int udp_disconnect_unhash4(struct sock *sk, int flags, bool clear_dest)
 {
 	struct udp_table *udptable = udp_get_table_prot(sk);
 
 	udp_unhash4(udptable, sk);
-	__udp_disconnect(sk, flags);
+	___udp_disconnect(sk, flags, clear_dest);
 
 	return 0;
 }
@@ -2248,7 +2255,7 @@ static int udp_disconnect_unhash4(struct sock *sk, int flags)
 int udp_disconnect(struct sock *sk, int flags)
 {
 	lock_sock(sk);
-	udp_disconnect_unhash4(sk, flags);
+	udp_disconnect_unhash4(sk, flags, true);
 	release_sock(sk);
 	return 0;
 }
@@ -3264,7 +3271,7 @@ int udp_abort(struct sock *sk, int err)
 
 	sk->sk_err = err;
 	sk_error_report(sk);
-	udp_disconnect_unhash4(sk, 0);
+	udp_disconnect_unhash4(sk, 0, false);
 
 out:
 	if (!has_current_bpf_ctx())
-- 
2.53.0.1118.gaef5881109-goog
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help