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
next prev parent 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).