Thread (2 messages) 2 messages, 2 authors, 7d ago
COOLING7d

[PATCH] ipv6: tcp: restore ipv6_specific icsk_af_ops when reconnecting IPv6 after v4-mapped

From: Hui Peng <hidden>
Date: 2026-09-19 21:52:39
Also in: lkml
Subsystem: networking [general], networking [tcp], the rest · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Neal Cardwell, Linus Torvalds

When an AF_INET6 TCP socket connects to an IPv4-mapped IPv6 address
(::ffff:a.b.c.d), tcp_v6_connect() switches icsk->icsk_af_ops to
&ipv6_mapped, sk->sk_backlog_rcv to tcp_v4_do_rcv, and tp->af_specific to
&tcp_sock_ipv4_specific. If the connection fails or is disconnected with
AF_UNSPEC and the socket subsequently connects to a native IPv6 address,
tcp_v6_connect() leaves icsk_af_ops set to &ipv6_mapped, causing IPv4
operations (such as ip_queue_xmit() and IPv4 setsockopt handlers) to run on
an IPv6 flow and corrupt the socket/routing state.

Restore icsk_af_ops to &ipv6_specific, sk_backlog_rcv to tcp_v6_do_rcv,
tp->af_specific to &tcp_sock_ipv6_specific, and notify MPTCP when
tcp_v6_connect() connects to a native IPv6 destination after ipv6_mapped.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Fixes: 31484d56ca95 ("mptcp: Fix undefined mptcp_handle_ipv6_mapped for modular IPV6")
Assisted-by: LLM
Signed-off-by: Hui Peng <redacted>
---
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 7fa4ed2fd4f1..49a6f89481cb 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -255,6 +255,17 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr_unsized *uaddr,
 		return err;
 	}
 
+	if (icsk->icsk_af_ops == &ipv6_mapped) {
+		/* Paired with READ_ONCE() in tcp_(get|set)sockopt() */
+		WRITE_ONCE(icsk->icsk_af_ops, &ipv6_specific);
+		if (sk_is_mptcp(sk))
+			mptcpv6_handle_mapped(sk, false);
+		sk->sk_backlog_rcv = tcp_v6_do_rcv;
+#if defined(CONFIG_TCP_MD5SIG) || defined(CONFIG_TCP_AO)
+		tp->af_specific = &tcp_sock_ipv6_specific;
+#endif
+	}
+
 	if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr))
 		saddr = &sk->sk_v6_rcv_saddr;
 
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help