From nobody Tue Oct 13 23:34:20 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 4j49f42fG1z6w4JQ for ; Tue, 13 Oct 2026 23:34:20 +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 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4j49f41nYFz4mKn for ; Tue, 13 Oct 2026 23:34:20 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791934460; 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=/tqenLtH42107xtGgEOLnLgTfupINUBG0UToYFX2XgQ=; b=sQpCNaYZ+YDeVJ4Oj+7tX8+Wj+PzIGc0bzaQajkk3r9riBJFkSkRGJUmLMyfBjG98xkNps q6xGZLwju/OlmUUAXg5JokeWn/Fztol2eau/OkTp4J4YDwcbV1TK2gEZ1WpaXAvS87bI7D unsbjhAk191Ya6z8KP0SyniMDobwHD4OGqawBfRWY/AhMISzvBWvUW2wZowuoADXwg4sWX WmFBettMSQPkp9mBCW2i2BwdBCwxmW6vCpZmqIJrBw5m9J5G3ZFaHmg7xzFDNEOhwtTRkw Fq1t/iZJL3SGjv3Wp+qn3Ax+Fg0EPQvEpcr7+mj0ntWr4Po5wYxnAtTqxjql2w== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1791934460; b=N7ipbNKhn6gE1Su8JuxaGeMClV8TfQT5VJG7MEWOJZ8pKgTN+mFJ4+1taxL9MDW2CF2A+W fUxeAerMozs62HUU5E9UUXW7DCY72oHLkg1QSZX9P5vxCiuZWwoo783UmxqQC4SXiYP96H /aINYMUXggzfeugZLQiqKVdqBcoutDYV1NPFcfj+cPKftMTt24ZslAlVMMhp5SE9dn/sGZ cPSTWBZsaSaJo+3olt//4FyYRqF8yaPPyQWvowc3pxNSHo/uzuleeC8fyTwwBmn5RmYjtb 156KbHqF3L1jfqOqGMtxMLiG4gHJzG8IQT0dlrYgkOg55cTtqYQCN4BKECdYhA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791934460; 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=/tqenLtH42107xtGgEOLnLgTfupINUBG0UToYFX2XgQ=; b=LbKpC6taUJs4xUuH8SFp2mJ/i2d4rVUovjZhwmTU8BSedguu39xdBp/dvGmU6H2pEGNYmP BCYuhVUQGEy2Fe252OcklwPycctdXcjv6sdANrxNrHzhEFIIp30u02Sm+va+felT6sHaf7 YKjVb15qA5MCz8npCFhtwWSIuwCN4mEc/kd0wpNnA2ixgM6mfVxabGFnAaDro46XeY73UL Do+0oGtQl/MTmeg72DQ22op/CrFvPLLqPkAVytq3hX9wR54H53mpvylrRYtHSBEOGe7CtW NHP+y5CPU7+Xm/odCOdGEWCq41jsYZCe5aAS0qiGTL5grV7hLjGcrhqLcavFKQ== 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 4j49f40Xv1zdQG for ; Tue, 13 Oct 2026 23:34:20 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 36801 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Tue, 13 Oct 2026 23:34:20 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: R. Christian McDonald Subject: git: 9fd9039c888d - main - tests: Add SLAAC interface identifier cases to ndp.sh 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: rcm X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 9fd9039c888d2d3d6cec47a3383c6825b903fcba Auto-Submitted: auto-generated Date: Tue, 13 Oct 2026 23:34:20 +0000 Message-Id: <6acebffc.36801.db54092@gitrepo.freebsd.org> The branch main has been updated by rcm: URL: https://cgit.FreeBSD.org/src/commit/?id=9fd9039c888d2d3d6cec47a3383c6825b903fcba commit 9fd9039c888d2d3d6cec47a3383c6825b903fcba Author: R. Christian McDonald AuthorDate: 2026-10-13 19:33:37 +0000 Commit: R. Christian McDonald CommitDate: 2026-10-13 23:31:53 +0000 tests: Add SLAAC interface identifier cases to ndp.sh Cover the interface identifier selection in in6_ifadd(): a /64 link-local address provides the identifier, while a /128 link-local address or no link-local address at all yields the EUI-64 identifier derived from the MAC address. Each case asserts the exact autoconfigured address. ndp_prefix_len_mismatch reaches the same fallback with a /127 link-local address, but only checks that some address was configured. Stable addresses (RFC 7217) are the default and bypass both paths, so the host disables them. The advertisement goes to all nodes, and an interface only joins that group with its first address, so the case without a link-local address gives the host a static address from another prefix. ra.py now takes the Ethernet source address from --sendif rather than from a route lookup; for ff02::1 that lookup fails in scapy 2.7.0. Reviewed by: pouria MFC after: 2 weeks Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D60520 --- tests/sys/netinet6/ndp.sh | 159 ++++++++++++++++++++++++++++++++++++++++++++++ tests/sys/netinet6/ra.py | 2 +- 2 files changed, 160 insertions(+), 1 deletion(-) diff --git a/tests/sys/netinet6/ndp.sh b/tests/sys/netinet6/ndp.sh index d70258bb3925..74c35a0b554e 100755 --- a/tests/sys/netinet6/ndp.sh +++ b/tests/sys/netinet6/ndp.sh @@ -862,6 +862,162 @@ ndp_routeinfo_option_cleanup() { } +# SLAAC interface identifier selection in in6_ifadd(): a link-local +# address with the advertised prefix length lends its identifier to the +# autoconfigured address, otherwise the identifier is derived from the MAC +# address, which covers PPP links with a /128 link-local address as well as +# interfaces without a link-local address. The MAC address below gives the +# EUI-64 based identifier 11:22ff:fe33:4455. Stable addresses (RFC 7217) +# are switched off on the host, they bypass both paths. +ndp_slaac_prefix="2001:db8:ffff:2000" +ndp_slaac_mac="02:11:22:33:44:55" +ndp_slaac_mac_ifid="11:22ff:fe33:4455" +ndp_slaac_ll_ifid="dead:beef:1:2" + +# Prepare ${ifname} in jail ${jname} as a SLAAC host with the test MAC +# address and without an automatic link-local address. DAD is off, so +# that addresses are final once configured. The caller adds the addresses +# its case needs and brings the interface up. +ndp_slaac_host() +{ + local ifname=$1 jname=$2 + + atf_check ifconfig -j ${jname} ${ifname} ether ${ndp_slaac_mac} + atf_check ifconfig -j ${jname} ${ifname} inet6 -auto_linklocal \ + -ifdisabled accept_rtadv -stableaddr no_dad +} + +# Advertise ${ndp_slaac_prefix}::/64 to all nodes from ${sendif} and wait +# for jail ${jname} to autoconfigure an address from it on ${ifname}. Any +# further arguments are passed to ra.py. +ndp_slaac_advertise() +{ + local sendif=$1 jname=$2 ifname=$3 i + + shift 3 + atf_check -e ignore python3 $(atf_get_srcdir)/ra.py \ + --sendif ${sendif} \ + --dst ff02::1 \ + --src $(ndp_if_lladdr ${sendif}) \ + --prefix "${ndp_slaac_prefix}::" --prefixlen 64 "$@" + for i in $(jot 20); do + if ifconfig -j ${jname} ${ifname} inet6 | \ + grep -q "inet6 ${ndp_slaac_prefix}:.*autoconf"; then + return + fi + sleep 0.1 + done + atf_fail "No address from ${ndp_slaac_prefix}::/64 was autoconfigured on ${ifname}" +} + +atf_test_case "ndp_slaac_ifid_lladdr" "cleanup" +ndp_slaac_ifid_lladdr_head() { + atf_set descr 'SLAAC takes the interface ID from a /64 link-local address' + atf_set require.user root + atf_set require.progs python3 scapy +} + +ndp_slaac_ifid_lladdr_body() { + local epair jname + + vnet_init + + jname="v6t-ndp_slaac_ifid_lladdr" + + epair=$(vnet_mkepair) + + vnet_mkjail ${jname} ${epair}a + + ndp_slaac_host ${epair}a ${jname} + atf_check ifconfig -j ${jname} ${epair}a inet6 \ + fe80::${ndp_slaac_ll_ifid}/64 + atf_check ifconfig -j ${jname} ${epair}a up + ndp_if_up ${epair}b + ndp_slaac_advertise ${epair}b ${jname} ${epair}a + + atf_check \ + -o match:"inet6 ${ndp_slaac_prefix}:${ndp_slaac_ll_ifid} prefixlen 64.*autoconf" \ + -o not-match:"inet6 ${ndp_slaac_prefix}:${ndp_slaac_mac_ifid} " \ + ifconfig -j ${jname} ${epair}a inet6 +} + +ndp_slaac_ifid_lladdr_cleanup() { + vnet_cleanup +} + +atf_test_case "ndp_slaac_ifid_no_lladdr" "cleanup" +ndp_slaac_ifid_no_lladdr_head() { + atf_set descr 'SLAAC derives the interface ID from the MAC address without a link-local address' + atf_set require.user root + atf_set require.progs python3 scapy +} + +ndp_slaac_ifid_no_lladdr_body() { + local epair jname + + vnet_init + + jname="v6t-ndp_slaac_ifid_no_lladdr" + + epair=$(vnet_mkepair) + + vnet_mkjail ${jname} ${epair}a + + # An interface joins the all-nodes group, and so receives + # advertisements, only once it has an IPv6 address: give it a + # static one from another prefix in place of the link-local one. + ndp_slaac_host ${epair}a ${jname} + atf_check ifconfig -j ${jname} ${epair}a inet6 \ + 2001:db8:ffff:1::2/64 + atf_check ifconfig -j ${jname} ${epair}a up + ndp_if_up ${epair}b + ndp_slaac_advertise ${epair}b ${jname} ${epair}a + + atf_check \ + -o match:"inet6 ${ndp_slaac_prefix}:${ndp_slaac_mac_ifid} prefixlen 64.*autoconf" \ + -o not-match:"inet6 fe80:" \ + ifconfig -j ${jname} ${epair}a inet6 +} + +ndp_slaac_ifid_no_lladdr_cleanup() { + vnet_cleanup +} + +atf_test_case "ndp_slaac_ifid_lladdr_plen128" "cleanup" +ndp_slaac_ifid_lladdr_plen128_head() { + atf_set descr 'SLAAC derives the interface ID from the MAC address when the link-local address is a /128' + atf_set require.user root + atf_set require.progs python3 scapy +} + +ndp_slaac_ifid_lladdr_plen128_body() { + local epair jname + + vnet_init + + jname="v6t-ndp_slaac_ifid_lladdr_plen128" + + epair=$(vnet_mkepair) + + vnet_mkjail ${jname} ${epair}a + + ndp_slaac_host ${epair}a ${jname} + atf_check ifconfig -j ${jname} ${epair}a inet6 \ + fe80::${ndp_slaac_ll_ifid}/128 + atf_check ifconfig -j ${jname} ${epair}a up + ndp_if_up ${epair}b + ndp_slaac_advertise ${epair}b ${jname} ${epair}a + + atf_check \ + -o match:"inet6 ${ndp_slaac_prefix}:${ndp_slaac_mac_ifid} prefixlen 64.*autoconf" \ + -o not-match:"inet6 ${ndp_slaac_prefix}:${ndp_slaac_ll_ifid} " \ + ifconfig -j ${jname} ${epair}a inet6 +} + +ndp_slaac_ifid_lladdr_plen128_cleanup() { + vnet_cleanup +} + atf_init_test_cases() { atf_add_test_case "ndp_add_gu_success" @@ -877,4 +1033,7 @@ atf_init_test_cases() atf_add_test_case "ndp_input_validation_src_linklocal" atf_add_test_case "ndp_multirouter_pref" atf_add_test_case "ndp_routeinfo_option" + atf_add_test_case "ndp_slaac_ifid_lladdr" + atf_add_test_case "ndp_slaac_ifid_no_lladdr" + atf_add_test_case "ndp_slaac_ifid_lladdr_plen128" } diff --git a/tests/sys/netinet6/ra.py b/tests/sys/netinet6/ra.py index e732e952be71..72680c1db4d5 100644 --- a/tests/sys/netinet6/ra.py +++ b/tests/sys/netinet6/ra.py @@ -56,7 +56,7 @@ def main(): help='The route info preference advertised') args = parser.parse_args() - pkt = sp.Ether() / \ + pkt = sp.Ether(src=sp.get_if_hwaddr(args.sendif[0])) / \ sp.IPv6(src=args.src, dst=args.dst, hlim=args.hoplimit) / \ sp.ICMPv6ND_RA(chlim=64, prf=args.rtrpref,