From nobody Mon Aug 3 14:01:39 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hDJJ600BMz6nRgb; Mon, 03 Aug 2026 14:01:42 +0000 (UTC) (envelope-from markj@freebsd.org) Received: from smtp.freebsd.org (smtp.freebsd.org [96.47.72.83]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "smtp.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hDJJ56VScz3pJd; Mon, 03 Aug 2026 14:01:41 +0000 (UTC) (envelope-from markj@freebsd.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785765701; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=xHyw1CARp7jm4TloewuVS9CLAB+H8vDNE/rni/3YKVU=; b=wkGbbtxZyCZYsALoPdgteNIiNsGN1+R/k3W6oZdERl1V8wh911L/AbW8cBDoZ82fxxJJ4D NBHAcFEX5yWPuiv2zUdGlVLTefjLS1lohG1SiCUf6yytcqHtVyqqMPcz8QFSuhJ5FRMXRw sgE2GDKIdwz1HYykiTM+KfwYKTxhrChLNTovDknWsJwK84UNgNNga1o9jsQdKbrGuH6msg abzhl2RGfB1rAAFt3gLwUWLoVPOzgFkM0Are+k9Av2y2IsNobSSxkbRQK4t52M5h2NIAkp cg9BwJgBCXgtfHzHxMdPXywDuVYVIQMQVDVzkgeDAqz6QyobNB6Wp+ggy/OhEQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1785765701; a=rsa-sha256; cv=none; b=ogMqE+MLUZoPem/VzNKmP5n/XBGFBte1ItIjCXmixXbnUS1hEZ2GrRz6uRbBWGq2dvR1p9 6HhqUtAVqHoOX7PtsT57SDhW85xoY2tcmzfvjhKXh4gMmLld0Zi5lzs3pAbc1izGWMkDXJ 5tUoxWUFPdPBSMep65Tcx1KPWV6AqTrTtjs0cp0GqEztxNWhdS3hMU9S76y5k6sHySQ2np AQG+pN2DTuzZiPjDLzaR2/biyeYhdufvTZ9Xhkb1EW7xAHEf4JsWlenthAAeCc5+dD1izs 0N1KSkXK3pbsA4/57zyoBg/Ev5Q+dTpcmCO74finfGRAGZCM2zZGnqSHcxfNEw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785765701; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=xHyw1CARp7jm4TloewuVS9CLAB+H8vDNE/rni/3YKVU=; b=EwMSz4bs6ZHAY4Azl/A0tGkhc8atmCocDGI9CdSqQng6HK2jbBWUNT0ymrcwdTCy+LlmiQ 9kE+IfuXNnHLxl6gCeBU6sxcUlrn1preeg0pmaFf7VN96XyWxP5XURZZwC8ya28j94k3an PqfVlsVWboNdQjvY2o5dKhalh+6n426SxKSNnlOSqpqYd7jb+MfQfK7yvg0hiM/w3Q8gT8 +sjJcEgneNlXEquycHESazcXay9wFZtg7NM2D+rW48FVkDpG6Jz+HtuzbEw7/lCopsiABq Zk/yHWpGWJFCm9+Z5JwhIw3B6OGsw7QjMmt1BjP4jUKjQF9/ZzHYpNWesG8hFw== Received: from nuc (192-0-220-237.cpe.teksavvy.com [192.0.220.237]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: markj) by smtp.freebsd.org (Postfix) with ESMTPSA id 4hDJJ53pyFz9KR; Mon, 03 Aug 2026 14:01:41 +0000 (UTC) (envelope-from markj@freebsd.org) Date: Mon, 3 Aug 2026 10:01:39 -0400 From: Mark Johnston To: Bruce M Simpson Cc: src-committers@freebsd.org, dev-commits-src-all@freebsd.org, dev-commits-src-main@freebsd.org Subject: Re: git: f9cdaeeeb9ad - main - netinet6: Pass IPv4-mapped ASM multicast joins/leaves to netinet. Message-ID: References: <6a707b66.1864b.48d16eee@gitrepo.freebsd.org> List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: On Mon, Aug 03, 2026 at 10:00:18AM -0400, Mark Johnston wrote: > On Mon, Aug 03, 2026 at 11:28:38AM +0000, Bruce M Simpson wrote: > > The branch main has been updated by bms: > > > > URL: https://cgit.FreeBSD.org/src/commit/?id=f9cdaeeeb9ad45a5e8c0cd32ff9443d245b64185 > > > > commit f9cdaeeeb9ad45a5e8c0cd32ff9443d245b64185 > > Author: Bruce M Simpson > > AuthorDate: 2026-08-01 10:14:57 +0000 > > Commit: Bruce M Simpson > > CommitDate: 2026-08-03 11:27:45 +0000 > > > > netinet6: Pass IPv4-mapped ASM multicast joins/leaves to netinet. > > > > Add support for allowing IPv4 multicast groups to be joined on IPv6 sockets, > > as a number of applications began to rely on this over the years, despite it > > only ever having been a convenience which appeared in Solaris & Linux over > > the course of the 00s decade. It is limited to any-source joins (ASM). > > > > To avoid further quibbling over the meaning of the term "undocumented" as it > > applies to this change, I have chosen to use the wording "non-IETF-ratified > > extension" in comments, with reference to the updated ip6(4) man page. > > > > PR: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=193246 > > --- > > sys/netinet/in_mcast.c | 6 +-- > > sys/netinet/in_var.h | 5 +++ > > sys/netinet6/in6_mcast.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++- > > 3 files changed, 118 insertions(+), 5 deletions(-) > > > > diff --git a/sys/netinet/in_mcast.c b/sys/netinet/in_mcast.c > > index 934cc71e745b..ad908b72c340 100644 > > --- a/sys/netinet/in_mcast.c > > +++ b/sys/netinet/in_mcast.c > > @@ -158,8 +158,6 @@ static void inm_release(struct in_multi *); > > static struct ip_moptions * > > inp_findmoptions(struct inpcb *); > > static int inp_get_source_filters(struct inpcb *, struct sockopt *); > > -static int inp_join_group(struct inpcb *, struct sockopt *); > > -static int inp_leave_group(struct inpcb *, struct sockopt *); > > static int inp_block_unblock_source(struct inpcb *, struct sockopt *); > > static int inp_set_multicast_if(struct inpcb *, struct sockopt *); > > static int inp_set_source_filters(struct inpcb *, struct sockopt *); > > @@ -1884,7 +1882,7 @@ const struct in_addr *ina, const u_int index) > > /* > > * Join an IPv4 multicast group, possibly with a source. > > */ > > -static int > > +int > > inp_join_group(struct inpcb *inp, struct sockopt *sopt) > > { > > struct group_source_req gsr; > > @@ -2208,7 +2206,7 @@ out_inp_unlocked: > > /* > > * Leave an IPv4 multicast group on an inpcb, possibly with a source. > > */ > > -static int > > +int > > inp_leave_group(struct inpcb *inp, struct sockopt *sopt) > > { > > struct epoch_tracker et; > > diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h > > index 99a628477155..e9db1efd9fe9 100644 > > --- a/sys/netinet/in_var.h > > +++ b/sys/netinet/in_var.h > > @@ -459,6 +459,11 @@ void in_ifattach(void *, struct ifnet *); > > void in_detachhead(struct rib_head *rh); > > #endif > > > > +struct sockopt; > > + > > +int inp_join_group(struct inpcb *, struct sockopt *); > > +int inp_leave_group(struct inpcb *, struct sockopt *); > > + > > #endif /* _KERNEL */ > > > > /* INET6 stuff */ > > diff --git a/sys/netinet6/in6_mcast.c b/sys/netinet6/in6_mcast.c > > index fad47cb0e69b..a204ad88a9a5 100644 > > --- a/sys/netinet6/in6_mcast.c > > +++ b/sys/netinet6/in6_mcast.c > > @@ -1,7 +1,7 @@ > > /*- > > * SPDX-License-Identifier: BSD-3-Clause > > * > > - * Copyright (c) 2009 Bruce Simpson. > > + * Copyright (c) 2009-2026 Bruce Simpson. > > * All rights reserved. > > * > > * Redistribution and use in source and binary forms, with or without > > @@ -34,6 +34,7 @@ > > * Normative references: RFC 2292, RFC 3492, RFC 3542, RFC 3678, RFC 3810. > > */ > > > > +#include "opt_inet.h" > > #include "opt_inet6.h" > > > > #include > > @@ -162,6 +163,9 @@ static struct ifnet * > > static int in6p_block_unblock_source(struct inpcb *, struct sockopt *); > > static int in6p_set_multicast_if(struct inpcb *, struct sockopt *); > > static int in6p_set_source_filters(struct inpcb *, struct sockopt *); > > +#ifdef INET > > +static int in6_v6_mreq_to_v4(struct ipv6_mreq *, struct ip_mreq *); > > +#endif > > static int sysctl_ip6_mcast_filters(SYSCTL_HANDLER_ARGS); > > > > SYSCTL_DECL(_net_inet6_ip6); /* XXX Not in any common header. */ > > @@ -1881,6 +1885,54 @@ in6p_lookup_mcast_ifp(const struct inpcb *inp, const struct sockaddr_in6 *gsin6) > > return (nh ? nh->nh_ifp : NULL); > > } > > > > +#ifdef INET > > +/* > > + * Perform sockopt mreq argument conversion for IPv4-mapped groups. > > + * > > + * This function is required to support an extension to the behaviour > > + * in RFC 3493 Sec 3.7, which was never formally proposed by any > > + * contemporary IPv6 normative reference, but which is now required > > + * by much application software using IPv6 sockets as a convenience. > > + * Refer to manual page ip6(4) for further information. > > + * > > + * FUTURE: Use IPv4 source-address selection. > > + */ > > +static int > > +in6_v6_mreq_to_v4(struct ipv6_mreq *mreq, struct ip_mreq *mreq_v4) > > +{ > > + int error; > > + struct epoch_tracker et; > > + struct ifnet *ifp; > > + struct in_ifaddr *ia; > > + > > + NET_EPOCH_ENTER(et); > > + > > + ifp = ifnet_byindex(mreq->ipv6mr_interface); > > + if (ifp == NULL) { > > + error = EADDRNOTAVAIL; > > + goto out; > > + } > > + > > + /* > > + * Here, we do not compare the ifnet's primary IPv4 address with > > + * INADDR_ANY, to permit its use during system initialization. > > + * If this is not required, an appropriate check to screen it out > > + * should be added, e.g. in_nullhost(ia->ia_addr.sin_addr.s_addr). > > + */ > > + ia = in_ifprimaryaddr(ifp); > > + if (ia == NULL) { > > + error = EADDRNOTAVAIL; > > + goto out; > > + } > > + mreq_v4->imr_interface.s_addr = IA_SIN(ia)->sin_addr.s_addr; > > + error = 0; > > + > > +out: > > + NET_EPOCH_EXIT(et); > > + return (error); > > +} > > +#endif /* INET */ > > + > > /* > > * Join an IPv6 multicast group, possibly with a source. > > * > > @@ -1929,6 +1981,35 @@ in6p_join_group(struct inpcb *inp, struct sockopt *sopt) > > sizeof(struct ipv6_mreq)); > > if (error) > > return (error); > > +#ifdef INET > > + /* > > + * Support for the non-IETF-ratified extension to RFC 3493 to > > + * join IPv4 groups as IPv4 mapped addresses on IPv6 sockets. > > + */ > > + if (IN6_IS_ADDR_V4MAPPED(&mreq.ipv6mr_multiaddr)) { > > + struct ip_mreq mreq_v4; > > + struct sockopt sopt_v4 = { > > + .sopt_dir = SOPT_SET, > > + .sopt_level = sopt->sopt_level, > > + .sopt_name = IP_ADD_MEMBERSHIP, > > + .sopt_val = &mreq_v4, > > + .sopt_valsize = sizeof(mreq_v4), > > + .sopt_rights = sopt->sopt_rights, > > + .sopt_td = sopt->sopt_td > > + }; > > + > > + mreq_v4.imr_multiaddr.s_addr = > > + mreq.ipv6mr_multiaddr.s6_addr32[3]; > > + if (mreq.ipv6mr_interface == 0) > > + mreq_v4.imr_interface.s_addr = INADDR_ANY; > > + else > > + error = in6_v6_mreq_to_v4(&mreq, &mreq_v4); > > + if (error) > > + return error; > > + > > + return (inp_join_group(inp, &sopt_v4)); > > I'm not sure how this can work: inp_join_group() will invoke > sooptcopyin() with sopt_val pointing to kernel memory and sopt_td > non-NULL, so sooptcopyin() will try to copy in from a kernel address and > inevitably return EFAULT. I missed your follow up message, sorry for the noise.