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 1/8] inany: Let length of sockaddr_inany be implicit from the family
Date: Thu, 13 Nov 2025 07:33:04 +0100	[thread overview]
Message-ID: <20251113073304.56859bae@elisabeth> (raw)
In-Reply-To: <20251029062628.1647051-2-david@gibson.dropbear.id.au>

Apologies for the very substantial delay. I have to admit I
procrastinated around 3/8 and 4/8 quite a bit as they look scary (but
much needed, of course).

Nits only, here:

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

> sockaddr_inany can contain either an IPv4 or IPv6 socket address, so the
> relevant length for bind() or connect() can vary.  In pif_sockaddr() we
> return that length, and in sock_l4_sa() we take it as an extra parameter.
> 
> However, sockaddr_inany always contains exactly a sockaddr_in or a
> sockaddr_in6 each with a fixed size.  Therefore we can derive the relevant
> length from the family, and don't need to pass it around separately.
> 
> Make a tiny helper to get the relevant address length, and update all
> interfaces to use that approach instead.
> 
> In the process, fix a buglet in tcp_flow_repair_bind(): we passed
> sizeof(union sockaddr_inany) to bind() instead of the specific length for
> the address family.  Since the sizeof() is always longer than the specific
> length, this is probably fine, but not theoretically correct.

(Whoops.)
 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  flow.c       | 17 +++++++----------
>  icmp.c       |  3 ++-
>  inany.h      | 18 ++++++++++++++++++
>  pif.c        | 14 ++++----------
>  pif.h        |  2 +-
>  tcp.c        | 20 +++++++++-----------
>  tcp_splice.c |  5 ++---
>  udp.c        |  8 +++-----
>  util.c       |  9 ++++-----
>  util.h       |  5 +++--
>  10 files changed, 53 insertions(+), 48 deletions(-)
> 
> diff --git a/flow.c b/flow.c
> index feefda3c..9926f408 100644
> --- a/flow.c
> +++ b/flow.c
> @@ -170,8 +170,7 @@ struct flowside_sock_args {
>  	int fd;
>  	int err;
>  	enum epoll_type type;
> -	const struct sockaddr *sa;
> -	socklen_t sl;

This should be dropped from the struct documentation.

> +	const union sockaddr_inany *sa;
>  	const char *path;
>  	uint32_t data;

Note: you'll get a trivial conflict here with "util: Move epoll
registration out of sock_l4_sa()" if you rebase.

>  };
> @@ -187,7 +186,7 @@ static int flowside_sock_splice(void *arg)
>  
>  	ns_enter(a->c);
>  
> -	a->fd = sock_l4_sa(a->c, a->type, a->sa, a->sl, NULL,
> +	a->fd = sock_l4_sa(a->c, a->type, a->sa, NULL,
>  	                   a->sa->sa_family == AF_INET6, a->data);
>  	a->err = errno;
>  
> @@ -209,11 +208,10 @@ int flowside_sock_l4(const struct ctx *c, enum epoll_type type, uint8_t pif,
>  {
>  	const char *ifname = NULL;
>  	union sockaddr_inany sa;
> -	socklen_t sl;
>  
>  	ASSERT(pif_is_socket(pif));
>  
> -	pif_sockaddr(c, &sa, &sl, pif, &tgt->oaddr, tgt->oport);
> +	pif_sockaddr(c, &sa, pif, &tgt->oaddr, tgt->oport);
>  
>  	switch (pif) {
>  	case PIF_HOST:
> @@ -224,13 +222,13 @@ int flowside_sock_l4(const struct ctx *c, enum epoll_type type, uint8_t pif,
>  		else if (sa.sa_family == AF_INET6)
>  			ifname = c->ip6.ifname_out;
>  
> -		return sock_l4_sa(c, type, &sa, sl, ifname,
> +		return sock_l4_sa(c, type, &sa, ifname,
>  				  sa.sa_family == AF_INET6, data);
>  
>  	case PIF_SPLICE: {
>  		struct flowside_sock_args args = {
>  			.c = c, .type = type,
> -			.sa = &sa.sa, .sl = sl, .data = data,
> +			.sa = &sa, .data = data,
>  		};
>  		NS_CALL(flowside_sock_splice, &args);
>  		errno = args.err;
> @@ -259,10 +257,9 @@ int flowside_connect(const struct ctx *c, int s,
>  		     uint8_t pif, const struct flowside *tgt)
>  {
>  	union sockaddr_inany sa;
> -	socklen_t sl;
>  
> -	pif_sockaddr(c, &sa, &sl, pif, &tgt->eaddr, tgt->eport);
> -	return connect(s, &sa.sa, sl);
> +	pif_sockaddr(c, &sa, pif, &tgt->eaddr, tgt->eport);
> +	return connect(s, &sa.sa, socklen_inany(&sa));
>  }
>  
>  /** flow_log_ - Log flow-related message
> diff --git a/icmp.c b/icmp.c
> index 6dffafb0..62b3bed8 100644
> --- a/icmp.c
> +++ b/icmp.c
> @@ -301,8 +301,9 @@ int icmp_tap_handler(const struct ctx *c, uint8_t pif, sa_family_t af,
>  	ASSERT(flow_proto[pingf->f.type] == proto);
>  	pingf->ts = now->tv_sec;
>  
> -	pif_sockaddr(c, &sa, &msh.msg_namelen, PIF_HOST, &tgt->eaddr, 0);
> +	pif_sockaddr(c, &sa, PIF_HOST, &tgt->eaddr, 0);
>  	msh.msg_name = &sa;
> +	msh.msg_namelen = socklen_inany(&sa);
>  	msh.msg_iov = iov;
>  	msh.msg_iovlen = cnt;
>  	msh.msg_control = NULL;
> diff --git a/inany.h b/inany.h
> index 7ca5cbd3..e3cae2a8 100644
> --- a/inany.h
> +++ b/inany.h
> @@ -67,6 +67,24 @@ union sockaddr_inany {
>  	struct sockaddr_in6	sa6;
>  };
>  
> +/** socklen_inany() - Return relevant size of an sockaddr_inany

'of a'

...but the fact that it returns that sounds kind of pleonastic. What
about:

/** socklen_inany() - Get relevant address length for sockaddr_inany address

> + * @sa:		sockaddr_iany socket address

sockaddr_inany

> + *
> + * Returns the correct socket address length to pass to bind() or connect() with
> + * @sa, based on whether it is an IPv4 or IPv6 address.

Same here, I guess we obviously want it to be correct, and we have a
somewhat standard syntax for return values in documentation, what about:

 * Return: socket address length for bind() or connect(), from IP family in @sa

?

> + */
> +static inline socklen_t socklen_inany(const union sockaddr_inany *sa)
> +{
> +	switch (sa->sa_family) {
> +	case AF_INET:
> +		return sizeof(sa->sa4);

Wouldn't it be more obvious to return sizeof(struct sockaddr_in), and
sizeof(struct sockaddr_in6) below, instead? I actually had to check that
sa->sa4 matched that (I didn't remember if that was a union).

Not a strong preference from my side, both are obviously correct anyway.

> +	case AF_INET6:
> +		return sizeof(sa->sa6);
> +	default:
> +		ASSERT(0);
> +	}
> +}

-- 
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 [this message]
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
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=20251113073304.56859bae@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).