From nobody Mon Nov 02 21:42:44 2026 X-Original-To: dev-commits-src-main@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 4jJQD54WDqz6ycBv for ; Mon, 02 Nov 2026 21:42:45 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (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) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 4jJQD432svz527K for ; Mon, 02 Nov 2026 21:42:44 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793655764; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=OU+HXTZFHGdYxPLtOLgh+Ep6lwyk1HAdn+FP0PmMf08=; b=GB2hZc+0obh9VF/xeSH46VfhYYxWJ3yUAPcoMV1RLfuJj1E4pytnfGS+C+N+V8fctGgXr4 e8mkPvnfaipskYm41ZeRUM4N0ZQeg230i5u471TV5DvagPC0s6OOKRHzhG5IHdmWpuB+B1 JXvKNUKoSVzll5u7IB0pTD3DYZIA8Tzx4dqiXAxMYHCcVIkf45jAU088Y6FTkUImvvMDrt CtOvhCRQqulyXZWHY0cYsCiMEDk0JDaSByD3KwWcympUUMmvnJ+yq0vHC7OVfUwrASPPLf yH+rytO8aNs7YX13p5h+U3Vtj4pTshZ26I8kyZgq2xjaibTVtiEfMV3b/a4DIA== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1793655764; b=JPC2vIXLMmLv4qOPn4YZNCNQ+XoIMa7R9jlxc2urz0fkE36xg6KWfMzKYN5nrXuadmBk8K 9qka0Fbvb4iC1laTPj2JebWWBMeHwuWft/C/Q6afrR1CvECO9PQ8qOpxsupL7M8YOyir1F 9tT2+f4hVlHk9Y0/s8VjIN6RMAat06Gy0rf1uZAt0sxMdmghiXe2e2imW7sFQWBsO9OnBk c4cN29y0ewGooWfZXZjDe+GwlI3I25vcASOvqwak31b3kEgVP2B5YLFfroCLHwevSm3bvH UbE0RUtllFN0ImN5Q+tO5yL5dIbF7dBq3AsRiwmyBo1NJMdQdpExa3eOAkD02w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793655764; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=OU+HXTZFHGdYxPLtOLgh+Ep6lwyk1HAdn+FP0PmMf08=; b=DDt030uHCvqlM1b0buwtlwS03uur58BvuBsRDk/eDO56e88gY7/3MKwQMMM1gkQNEKnxXH 4hNwFVosQiJsZW72qmsH+69yzw3rVS45sPyKZT5DPk3m1yA8fp7EO1bL17NIjQmxPzNR+1 nNV0B3TqZCv7lSAXoM0JEPB+zbyWlZ4z34TswpZrkbm/Eli+jpYNGpdE3RjkbEPcYvZaif OsD+cr55s9zBDopiNjFQ8yrgEL6tjl5kfgnndefd9vTJoqkHu9mSpgCV3la/L590XW5TKp 4G1oWV1pevaL2RB2N5vmS4aft45aYP2Xp3P6x4uf4BFflA4SrzxLY8t/GUV+bg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4jJQD42hJNz13Tx for ; Mon, 02 Nov 2026 21:42:44 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 43024 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 02 Nov 2026 21:42:44 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Gleb Smirnoff Subject: git: a08dc822f494 - main - udp6: make udp6_ctlinput() same as IPv4 version List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: Commit messages for the main branch of the src repository List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: glebius X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: a08dc822f4943f2cea509cd0ba1f11a89ec9e82d Auto-Submitted: auto-generated Date: Mon, 02 Nov 2026 21:42:44 +0000 Message-Id: <6ae903d4.43024.550fb9f8@gitrepo.freebsd.org> The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=a08dc822f4943f2cea509cd0ba1f11a89ec9e82d commit a08dc822f4943f2cea509cd0ba1f11a89ec9e82d Author: Gleb Smirnoff AuthorDate: 2026-11-02 21:42:15 +0000 Commit: Gleb Smirnoff CommitDate: 2026-11-02 21:42:15 +0000 udp6: make udp6_ctlinput() same as IPv4 version Processing an incoming ICMPv6 we need to find just the matching inpcb and call udp_notify() on it. The call to in6_pcbnotify() at the first glance seems like a notifying sweep across the entire database, but it is not. It finds just the matching inpcb, but does that in the most inefficient way! The added test case proves that ICMPv6 processing stays the same before and after the change. This weird use of in6_pcbnotify() can be tracked down all the way to the initial KAME code. Reviewed by: tuexen, gallatin Differential Revision: https://reviews.freebsd.org/D60967 --- sys/netinet6/udp6_usrreq.c | 34 +++++++++------- tests/sys/netinet6/Makefile | 1 + tests/sys/netinet6/udp6.c | 97 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 15 deletions(-) diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index 10ba889066ec..5fa574cca753 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -578,23 +578,27 @@ udp6_common_ctlinput(struct ip6ctlparam *ip6cp, struct inpcbinfo *pcbinfo) bzero(&uh, sizeof(uh)); m_copydata(m, off, sizeof(*uhp), &uh); - /* Check to see if its tunneled */ - inp = in6_pcblookup_mbuf(pcbinfo, &ip6->ip6_dst, uh.uh_dport, - &ip6->ip6_src, uh.uh_sport, INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB, - m->m_pkthdr.rcvif, m); + inp = in6_pcblookup(pcbinfo, &ip6->ip6_dst, uh.uh_dport, &ip6->ip6_src, + uh.uh_sport, INPLOOKUP_WLOCKPCB, NULL); if (inp != NULL) { - struct udpcb *up; - udp_tun_icmp_t *func; - - up = intoudpcb(inp); - func = up->u_icmp_func; - INP_RUNLOCK(inp); - if (func != NULL) - func(ip6cp); + INP_WLOCK_ASSERT(inp); + udp_notify(inp, errno); + INP_WUNLOCK(inp); + } else { + inp = in6_pcblookup(pcbinfo, &ip6->ip6_dst, uh.uh_dport, + &ip6->ip6_src, uh.uh_sport, + INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB, NULL); + if (inp != NULL) { + struct udpcb *up; + udp_tun_icmp_t *func; + + up = intoudpcb(inp); + func = up->u_icmp_func; + INP_RUNLOCK(inp); + if (func != NULL) + func(ip6cp); + } } - in6_pcbnotify(pcbinfo, ip6cp->ip6c_finaldst, uh.uh_dport, - ip6cp->ip6c_src, uh.uh_sport, errno, ip6cp->ip6c_cmdarg, - udp_notify); } static void diff --git a/tests/sys/netinet6/Makefile b/tests/sys/netinet6/Makefile index f5a04a299dc6..88db13600f55 100644 --- a/tests/sys/netinet6/Makefile +++ b/tests/sys/netinet6/Makefile @@ -4,6 +4,7 @@ TESTSDIR= ${TESTSBASE}/sys/netinet6 BINDIR= ${TESTSDIR} FILESDIR= ${TESTSDIR} +ATF_TESTS_C= udp6 ATF_TESTS_PYTEST= test_ip6_output.py ATF_TESTS_SH= exthdr \ mld \ diff --git a/tests/sys/netinet6/udp6.c b/tests/sys/netinet6/udp6.c new file mode 100644 index 000000000000..ba4b0503cdb7 --- /dev/null +++ b/tests/sys/netinet6/udp6.c @@ -0,0 +1,97 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2026 Gleb Smirnoff + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include + +static int +connectedsock(void) +{ + struct sockaddr_in6 sa = { + .sin6_family = AF_INET6, + .sin6_len = sizeof(sa), + .sin6_port = htons(1638), + .sin6_addr = IN6ADDR_LOOPBACK_INIT, + }; + int s; + + ATF_REQUIRE((s = socket(AF_INET6, SOCK_DGRAM, 0)) >= 0); + ATF_REQUIRE(connect(s, (struct sockaddr *)&sa, sizeof(sa)) == 0); + return (s); +} + +static void +REQUIRE_SO_ERROR(int s, int expected) +{ + socklen_t len = sizeof(int); + int error; + + ATF_REQUIRE(getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &len) == 0); + ATF_REQUIRE_MSG(error == expected, + "SO_ERROR: got %d (%s), expected %d (%s)", + error, strerror(error), expected, strerror(expected)); +} + +/* + * Two connected sockets to the same remote address and port. Kernel will + * assign different local ports to them. Trigger ICMPv6 Port Unreachable for + * each (kernel generates it). Assert that only one of them is notified. + * XXX: the remote is actually ::1 and the test relies on port being + * unreachable. + */ +ATF_TC_WITHOUT_HEAD(icmp_port_unreach_notify); +ATF_TC_BODY(icmp_port_unreach_notify, tc) +{ + const char buf[] = "probe"; + int s1, s2; + + s1 = connectedsock(); + s2 = connectedsock(); + ATF_REQUIRE(send(s1, buf, sizeof(buf), 0) == sizeof(buf)); + usleep(100000); + REQUIRE_SO_ERROR(s1, ECONNREFUSED); + REQUIRE_SO_ERROR(s2, 0); + ATF_REQUIRE(send(s2, buf, sizeof(buf), 0) == sizeof(buf)); + usleep(100000); + REQUIRE_SO_ERROR(s2, ECONNREFUSED); + REQUIRE_SO_ERROR(s1, 0); + + close(s1); + close(s2); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, icmp_port_unreach_notify); + + return (atf_no_error()); +}