[PATCH net-next v1 1/2] ipv6: make IPV6_FREEBIND setsockopt lockless
From: Xuanqiang Luo
Date: Fri Sep 11 2026 - 06:31:59 EST
From: Xuanqiang Luo <luoxuanqiang@xxxxxxxxxx>
IPV6_FREEBIND still takes the socket lock despite using
inet_assign_bit() to update the flag shared with IP_FREEBIND.
IPv6 TCP and UDP sockets can already update this flag without the
lock through SOL_IP/IP_FREEBIND.
Move IPV6_FREEBIND to the lockless setsockopt path.
Signed-off-by: Xuanqiang Luo <luoxuanqiang@xxxxxxxxxx>
---
net/ipv6/ipv6_sockglue.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 1f68fb64a43ef..4124084c3cd79 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -398,6 +398,12 @@ int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
/* Handle options that can be set without locking the socket. */
switch (optname) {
+ case IPV6_FREEBIND:
+ if (optlen < sizeof(int))
+ return -EINVAL;
+ /* Shared with IP_FREEBIND. */
+ inet_assign_bit(FREEBIND, sk, valbool);
+ return 0;
case IPV6_UNICAST_HOPS:
if (optlen < sizeof(int))
return -EINVAL;
@@ -679,14 +685,6 @@ int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
retv = 0;
break;
- case IPV6_FREEBIND:
- if (optlen < sizeof(int))
- goto e_inval;
- /* we also don't have a separate freebind bit for IPV6 */
- inet_assign_bit(FREEBIND, sk, valbool);
- retv = 0;
- break;
-
case IPV6_RECVORIGDSTADDR:
if (optlen < sizeof(int))
goto e_inval;
--
2.43.0