public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
From: Stefano Brivio <sbrivio@redhat.com>
To: David Gibson <david@gibson.dropbear.id.au>
Cc: passt-dev@passt.top
Subject: Re: [PATCH v3 6/8] util: Fix setting of IPV6_V6ONLY socket option
Date: Thu, 13 Nov 2025 07:33:35 +0100	[thread overview]
Message-ID: <20251113073335.3a73f9b9@elisabeth> (raw)
In-Reply-To: <20251029062628.1647051-7-david@gibson.dropbear.id.au>

On Wed, 29 Oct 2025 17:26:26 +1100
David Gibson <david@gibson.dropbear.id.au> wrote:

> Currently we only call setsockopt() on IPV6_V6ONLY when we want to set it
> to 1, which we typically do on all IPv6 sockets except those explicitly for
> dual stack listening.  That's not quite right in two ways:
> 
>  * Although IPV6_V6ONLY==0 is normally the default on Linux, that can be
>    changed with the net.ipv6.bindv6only sysctl.  It may also have different
>    defaults on other OSes if we ever support them.  We know we need it off
>    for dual stack sockets, so explicitly set it to 0 in that case.
> 
>  * At the same time setting IPV6_V6ONLY to 1 for IPv6 sockets bound to a
>    specific address is harmless but pointless.  Don't set the option at all
>    in this case, saving a syscall.

I haven't checked the implications of this but __inet6_bind() handles
address "types" IPV6_ADDR_ANY and IPV6_ADDR_MAPPED in the same way, for
IPV6_V6ONLY purposes. I'm not sure if this has any influence on
functionality though.

> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  util.c | 27 +++++++++++++++++++++------
>  1 file changed, 21 insertions(+), 6 deletions(-)
> 
> diff --git a/util.c b/util.c
> index c94efae4..62f43895 100644
> --- a/util.c
> +++ b/util.c
> @@ -45,14 +45,14 @@
>   * @type:	epoll type
>   * @sa:		Socket address to bind to
>   * @ifname:	Interface for binding, NULL for any
> - * @v6only:	Set IPV6_V6ONLY socket option
> + * @v6only:	If >= 0, set IPV6_V6ONLY socket option to this value
>   * @data:	epoll reference portion for protocol handlers
>   *
>   * Return: newly created socket, negative error code on failure
>   */
>  static int sock_l4_(const struct ctx *c, enum epoll_type type,
>  		    const union sockaddr_inany *sa, const char *ifname,
> -		    bool v6only, uint32_t data)
> +		    int v6only, uint32_t data)
>  {
>  	sa_family_t af = sa->sa_family;
>  	union epoll_ref ref = { .type = type, .data = data };
> @@ -101,9 +101,11 @@ static int sock_l4_(const struct ctx *c, enum epoll_type type,
>  
>  	ref.fd = fd;
>  
> -	if (v6only)
> -		if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &y, sizeof(y)))
> -			debug("Failed to set IPV6_V6ONLY on socket %i", fd);
> +	if (v6only >= 0)
> +		if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
> +			       &v6only, sizeof(v6only)))
> +			debug("Failed to set IPV6_V6ONLY to %d on socket %i",
> +			      v6only, fd);

Nit: curly brackets (two pairs) for consistency.

>  
>  	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &y, sizeof(y)))
>  		debug("Failed to set SO_REUSEADDR on socket %i", fd);
> @@ -186,7 +188,16 @@ int sock_l4(const struct ctx *c, enum epoll_type type,
>  	    const union sockaddr_inany *sa, const char *ifname,
>  	    uint32_t data)
>  {
> -	return sock_l4_(c, type, sa, ifname, sa->sa_family == AF_INET6, data);
> +	int v6only = -1;
> +
> +	/* The option doesn't exist for IPv4 sockets, and is irrelevant for IPv6
> +	 * sockets with a non-wildcard address.

Same as above: I don't think this is true, strictly speaking, but I
didn't check whether this inaccuracy is in any way relevant.

> +	 */
> +	if (sa->sa_family == AF_INET6 &&
> +	    IN6_IS_ADDR_UNSPECIFIED(&sa->sa6.sin6_addr))
> +		v6only = 1;
> +
> +	return sock_l4_(c, type, sa, ifname, v6only, data);
>  }
>  
>  int sock_l4_dualstack(const struct ctx *c, enum epoll_type type,
> @@ -198,6 +209,10 @@ int sock_l4_dualstack(const struct ctx *c, enum epoll_type type,
>  		.sa6.sin6_port = htons(port),
>  	};
>  
> +	/* Dual stack sockets require IPV6_V6ONLY == 0.  Usually that's the
> +	 * default, but sysctl net.ipv6.bindv6only can change that, so set the
> +	 * sockopt explicitly.
> +	 */
>  	return sock_l4_(c, type, &sa, ifname, 0, data);
>  }
>  

The rest of the series looks good to me, including 8/8, but it's not
clear to me what the "secondary reasons" to consider 8/8 at this stage
might be, so I'm not actually sure what to do with it.

Is it because it drops some code?

-- 
Stefano


  reply	other threads:[~2025-11-13  6:33 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-29  6:26 [PATCH v3 0/8] Reduce differences between inbound and outbound socket binding David Gibson
2025-10-29  6:26 ` [PATCH v3 1/8] inany: Let length of sockaddr_inany be implicit from the family David Gibson
2025-11-13  6:33   ` Stefano Brivio
2025-11-13 22:53     ` David Gibson
2025-10-29  6:26 ` [PATCH v3 2/8] util, flow, pif: Simplify sock_l4_sa() interface David Gibson
2025-11-13  6:33   ` Stefano Brivio
2025-11-13 23:21     ` David Gibson
2025-11-18  0:19       ` Stefano Brivio
2025-11-18  3:34         ` David Gibson
2025-11-19 11:42           ` Stefano Brivio
2025-11-20  0:05             ` David Gibson
2025-11-20  2:22               ` David Gibson
2025-10-29  6:26 ` [PATCH v3 3/8] tcp: Merge tcp_ns_sock_init[46]() into tcp_sock_init_one() David Gibson
2025-10-29  6:26 ` [PATCH v3 4/8] udp: Unify some more inbound/outbound parts of udp_sock_init() David Gibson
2025-11-13  6:33   ` Stefano Brivio
2025-11-13 23:33     ` David Gibson
2025-10-29  6:26 ` [PATCH v3 5/8] udp: Move udp_sock_init() special case to its caller David Gibson
2025-10-29  6:26 ` [PATCH v3 6/8] util: Fix setting of IPV6_V6ONLY socket option David Gibson
2025-11-13  6:33   ` Stefano Brivio [this message]
2025-11-14  0:24     ` David Gibson
2025-11-18  0:19       ` Stefano Brivio
2025-10-29  6:26 ` [PATCH v3 7/8] tcp, udp: Remove fallback if creating dual stack socket fails David Gibson
2025-10-29  6:26 ` [PATCH v3 8/8] [RFC, DO NOT APPLY] tcp, udp: Bind outbound listening sockets by interface instead of address David Gibson
2025-10-30  3:58 ` [PATCH v3 0/8] Reduce differences between inbound and outbound socket binding David Gibson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251113073335.3a73f9b9@elisabeth \
    --to=sbrivio@redhat.com \
    --cc=david@gibson.dropbear.id.au \
    --cc=passt-dev@passt.top \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).