All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH, mptcp-next 0/9] selftests: mptcp: skip the v6 subtests when CONFIG_MPTCP_IPV6=n
@ 2026-06-11 17:07 Gang Yan
  2026-06-11 17:07 ` [PATCH, mptcp-next 1/9] DO-NOT-MERGE: mptcp: test IPV6=m in docker-virtme Gang Yan
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Gang Yan @ 2026-06-11 17:07 UTC (permalink / raw)
  To: mptcp; +Cc: Gang Yan

From: Gang Yan <yangang@kylinos.cn>

Hi, Matt

This series is for make the selftest useful in the kernel which IPV6 is
compiled as a module.

The MPTCP selftests cover a wide functional surface: connection
establishment, subflow join/remove, ADD_ADDR / RM_ADDR signalling,
path-manager behaviour, nft-based tproxy, transfer of bulk data with
sane throughput and CPU usage, and so on. Together they are the
principal end-to-end suite product-validation teams run to certify
that MPTCP works on a candidate kernel. Kconfig, however, says:

      config MPTCP_IPV6
          depends on IPV6=y

so any distro or product kernel that ships with CONFIG_IPV6=m ends up
with CONFIG_MPTCP_IPV6=n. The corresponding MPTCP over IPv4 path is
built and works correctly; only the v6 subtests are unavailable.

So far, the selftests do not know about this configuration. They
unconditionally configure dead:beef:* endpoints, open AF_INET6
listeners, drive v6 ADD_ADDR / RM_ADDR / subflow commands and load
nft "table inet" chains, and they treat every one of those failures
as a test failure. On a CONFIG_IPV6=m kernel, every subtest
contaminated by a v6 step — including the v4-only ones in
mptcp_join.sh starting with "001 no JOIN" — comes back red. The
v4 functionality cannot be signed off even though it works.

Patch 1 is a DO-NOT-MERGE review aid (it flips the kselftest config
fragment to CONFIG_IPV6=m and adds CONFIG_NF_TABLES_IPV4=y so
docker-virtme can run the scripts in the target environment).
The remaining 8 patches are the real series.

Thanks
Gang

Gang Yan (9):
  DO-NOT-MERGE: mptcp: test IPV6=m in docker-virtme
  selftests: mptcp: mptcp_lib add runtime IPv6 availability detection
    helper
  selftests: mptcp: mptcp_connect.sh degrades to v4-only when MPTCP IPv6
    is missing
  selftests: mptcp: mptcp_connect.sh don't fail because of nft rules in
    IPV6-less kernel
  selftests: mptcp: mptcp_sockopt.sh skips v6 paths when MPTCP IPv6 is
    missing
  selftests: mptcp: simult_flows.sh skips v6 setup when MPTCP IPv6 is
    missing
  selftests: mptcp: mptcp_join.sh: pick v4 bind default when MPTCP IPv6
    is missing
  selftests: mptcp: mptcp_join.sh skips v6 subtests when MPTCP IPv6 is
    missing
  selftests: mptcp: userspace_pm.sh skips v6 paths when MPTCP IPv6 is
    missing

 tools/testing/selftests/net/mptcp/config      |   5 +-
 .../selftests/net/mptcp/mptcp_connect.sh      |  48 +++-
 .../testing/selftests/net/mptcp/mptcp_join.sh | 154 +++++++++---
 .../testing/selftests/net/mptcp/mptcp_lib.sh  |  33 +++
 .../selftests/net/mptcp/mptcp_sockopt.sh      |  81 ++++--
 .../selftests/net/mptcp/simult_flows.sh       |  30 ++-
 .../selftests/net/mptcp/userspace_pm.sh       | 237 ++++++++++--------
 7 files changed, 397 insertions(+), 191 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH, mptcp-next 1/9] DO-NOT-MERGE: mptcp: test IPV6=m in docker-virtme
  2026-06-11 17:07 [PATCH, mptcp-next 0/9] selftests: mptcp: skip the v6 subtests when CONFIG_MPTCP_IPV6=n Gang Yan
@ 2026-06-11 17:07 ` Gang Yan
  2026-06-11 17:07 ` [PATCH, mptcp-next 2/9] selftests: mptcp: mptcp_lib add runtime IPv6 availability detection helper Gang Yan
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Gang Yan @ 2026-06-11 17:07 UTC (permalink / raw)
  To: mptcp; +Cc: Gang Yan

From: Gang Yan <yangang@kylinos.cn>

This is a helper commit for maintainer review of the preceding MPTCP
selftests patches that teach the test scripts to gracefully skip IPv6
subtests when the running kernel has no CONFIG_MPTCP_IPV6.

Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
 tools/testing/selftests/net/mptcp/config | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/net/mptcp/config b/tools/testing/selftests/net/mptcp/config
index 59051ee2a986..616fee329e22 100644
--- a/tools/testing/selftests/net/mptcp/config
+++ b/tools/testing/selftests/net/mptcp/config
@@ -7,11 +7,10 @@ CONFIG_IP_MULTIPLE_TABLES=y
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IPV6=y
+CONFIG_IPV6=m
 CONFIG_IPV6_MULTIPLE_TABLES=y
 CONFIG_KALLSYMS=y
 CONFIG_MPTCP=y
-CONFIG_MPTCP_IPV6=y
 CONFIG_NET_ACT_CSUM=m
 CONFIG_NET_ACT_PEDIT=m
 CONFIG_NET_CLS_ACT=y
@@ -34,3 +33,5 @@ CONFIG_NFT_SOCKET=m
 CONFIG_NFT_TPROXY=m
 CONFIG_SYN_COOKIES=y
 CONFIG_VETH=y
+
+CONFIG_NF_TABLES_IPV4=y
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH, mptcp-next 2/9] selftests: mptcp: mptcp_lib add runtime IPv6 availability detection helper
  2026-06-11 17:07 [PATCH, mptcp-next 0/9] selftests: mptcp: skip the v6 subtests when CONFIG_MPTCP_IPV6=n Gang Yan
  2026-06-11 17:07 ` [PATCH, mptcp-next 1/9] DO-NOT-MERGE: mptcp: test IPV6=m in docker-virtme Gang Yan
@ 2026-06-11 17:07 ` Gang Yan
  2026-06-11 17:07 ` [PATCH, mptcp-next 3/9] selftests: mptcp: mptcp_connect.sh degrades to v4-only when MPTCP IPv6 is missing Gang Yan
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Gang Yan @ 2026-06-11 17:07 UTC (permalink / raw)
  To: mptcp; +Cc: Gang Yan

From: Gang Yan <yangang@kylinos.cn>

This patch introduce a minimal, non-fatal detection helper that subsequent
patches will use to guard the v6 paths:

  - MPTCP_LIB_IPV6_AVAILABLE: cached flag, default 1 (optimistic).
  - mptcp_lib_check_ipv6(): looks for "mptcpv6_init" in /proc/kallsyms.
    That symbol is registered by subsys_initcall() in
    net/mptcp/ctrl.c only when both CONFIG_IPV6=y and
    CONFIG_MPTCP_IPV6=y, so it is a precise runtime proxy. The check
    is non-fatal: it only updates the cached flag and returns 0/1,
    letting callers pick the right degradation (skip a subtest, drop
    to v4-only, etc.) without forcing an exit.
  - mptcp_lib_is_v6_enabled(): cheap accessor wrapping the flag.

No existing caller is changed.

Assisted-by: GLM:5.1 Z.ai
Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
 .../testing/selftests/net/mptcp/mptcp_lib.sh  | 33 +++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_lib.sh b/tools/testing/selftests/net/mptcp/mptcp_lib.sh
index 5ef6033775c8..3bb1c0ac8749 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_lib.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_lib.sh
@@ -32,6 +32,7 @@ MPTCP_LIB_SUBTESTS_LAST_TS_NS=
 MPTCP_LIB_TEST_COUNTER=0
 MPTCP_LIB_TEST_FORMAT="%02u %-50s"
 MPTCP_LIB_IP_MPTCP=0
+MPTCP_LIB_IPV6_AVAILABLE=1
 
 # only if supported (or forced) and not disabled, see no-color.org
 if { [ -t 1 ] || [ "${SELFTESTS_MPTCP_LIB_COLOR_FORCE:-}" = "1" ]; } &&
@@ -178,6 +179,32 @@ mptcp_lib_check_kallsyms() {
 	fi
 }
 
+# Detect whether the MPTCP IPv6 subsystem is available in the running kernel.
+#
+# This is meant to be called once at script init time. It is non-fatal by
+# design: instead of exiting on a missing feature, it just sets the cached
+# MPTCP_LIB_IPV6_AVAILABLE flag and returns 0/1. Callers can then decide
+# whether to skip a single subtest, fall back to a v4-only mode, etc.
+#
+# The check looks for the "mptcpv6_init" symbol in /proc/kallsyms, which is
+# only present when both CONFIG_IPV6=y and CONFIG_MPTCP_IPV6=y. This single
+# symbol gives the most accurate runtime answer.
+mptcp_lib_check_ipv6() {
+	if ! mptcp_lib_has_file "/proc/kallsyms"; then
+		MPTCP_LIB_IPV6_AVAILABLE=0
+		return 1
+	fi
+
+	if ! grep -q " mptcpv6_init$" /proc/kallsyms; then
+		MPTCP_LIB_IPV6_AVAILABLE=0
+		mptcp_lib_pr_skip "MPTCP IPv6 support is not available"
+		return 1
+	fi
+
+	MPTCP_LIB_IPV6_AVAILABLE=1
+	return 0
+}
+
 # Internal: use mptcp_lib_kallsyms_has() instead
 __mptcp_lib_kallsyms_has() {
 	local sym="${1}"
@@ -398,6 +425,12 @@ mptcp_lib_is_v6() {
 	[ -z "${1##*:*}" ]
 }
 
+# Returns 0 (true) if the kernel has MPTCP IPv6 support, 1 (false) otherwise.
+# Cached after the first call to mptcp_lib_check_ipv6().
+mptcp_lib_is_v6_enabled() {
+	[ "${MPTCP_LIB_IPV6_AVAILABLE}" = "1" ]
+}
+
 mptcp_lib_nstat_init() {
 	local ns="${1}"
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH, mptcp-next 3/9] selftests: mptcp: mptcp_connect.sh degrades to v4-only when MPTCP IPv6 is missing
  2026-06-11 17:07 [PATCH, mptcp-next 0/9] selftests: mptcp: skip the v6 subtests when CONFIG_MPTCP_IPV6=n Gang Yan
  2026-06-11 17:07 ` [PATCH, mptcp-next 1/9] DO-NOT-MERGE: mptcp: test IPV6=m in docker-virtme Gang Yan
  2026-06-11 17:07 ` [PATCH, mptcp-next 2/9] selftests: mptcp: mptcp_lib add runtime IPv6 availability detection helper Gang Yan
@ 2026-06-11 17:07 ` Gang Yan
  2026-06-11 17:07 ` [PATCH, mptcp-next 4/9] selftests: mptcp: mptcp_connect.sh don't fail because of nft rules in IPV6-less kernel Gang Yan
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Gang Yan @ 2026-06-11 17:07 UTC (permalink / raw)
  To: mptcp; +Cc: Gang Yan

From: Gang Yan <yangang@kylinos.cn>

Make the IPv6 path optional at runtime:

  - Right after the existing mptcp_lib_check_* calls, query the new
    mptcp_lib_check_ipv6() helper. If the kernel does not support
    MPTCP/IPv6 and the user did not already pass -4 on the command line,
    transparently flip the internal ${ipv6} flag to false and print one
    informational line so the user knows v4-only mode kicked in.
  - Guard every "ip -6 addr add", "ip -6 route add" and the v6
    forwarding sysctl with "if $ipv6; then ... fi".

The -4 command-line option (handled earlier in the same script) keeps
priority: when the user explicitly asks for v4-only mode the new check
is a no-op. In a fully featured kernel ${ipv6} stays true and the
script behaves exactly as before.

Assisted-by: GLM:5.1 Z.ai
Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
 .../selftests/net/mptcp/mptcp_connect.sh      | 42 +++++++++++++------
 1 file changed, 30 insertions(+), 12 deletions(-)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.sh b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
index 7a2a851fa0ad..0e5690d6f68c 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_connect.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
@@ -149,6 +149,14 @@ mptcp_lib_check_mptcp
 mptcp_lib_check_kallsyms
 mptcp_lib_check_tools ip tc
 
+# If MPTCP IPv6 is not available in the running kernel, transparently
+# downgrade to v4-only mode (unless the user already passed -4).
+# This keeps v4 tests running in IPV6=m / MPTCP_IPV6=n kernels.
+if ! mptcp_lib_check_ipv6 && ${ipv6}; then
+	ipv6=false
+	mptcp_lib_pr_info "MPTCP IPv6 not available, running IPv4-only tests"
+fi
+
 sin=$(mktemp)
 sout=$(mktemp)
 cin=$(mktemp)
@@ -169,41 +177,51 @@ ip link add ns2eth3 netns "$ns2" type veth peer name ns3eth2 netns "$ns3"
 ip link add ns3eth4 netns "$ns3" type veth peer name ns4eth3 netns "$ns4"
 
 ip -net "$ns1" addr add 10.0.1.1/24 dev ns1eth2
-ip -net "$ns1" addr add dead:beef:1::1/64 dev ns1eth2 nodad
 
 ip -net "$ns1" link set ns1eth2 up
 ip -net "$ns1" route add default via 10.0.1.2
-ip -net "$ns1" route add default via dead:beef:1::2
 
 ip -net "$ns2" addr add 10.0.1.2/24 dev ns2eth1
-ip -net "$ns2" addr add dead:beef:1::2/64 dev ns2eth1 nodad
 ip -net "$ns2" link set ns2eth1 up
 
 ip -net "$ns2" addr add 10.0.2.1/24 dev ns2eth3
-ip -net "$ns2" addr add dead:beef:2::1/64 dev ns2eth3 nodad
 ip -net "$ns2" link set ns2eth3 up
 ip -net "$ns2" route add default via 10.0.2.2
-ip -net "$ns2" route add default via dead:beef:2::2
 ip netns exec "$ns2" sysctl -q net.ipv4.ip_forward=1
-ip netns exec "$ns2" sysctl -q net.ipv6.conf.all.forwarding=1
 
 ip -net "$ns3" addr add 10.0.2.2/24 dev ns3eth2
-ip -net "$ns3" addr add dead:beef:2::2/64 dev ns3eth2 nodad
 ip -net "$ns3" link set ns3eth2 up
 
 ip -net "$ns3" addr add 10.0.3.2/24 dev ns3eth4
-ip -net "$ns3" addr add dead:beef:3::2/64 dev ns3eth4 nodad
 ip -net "$ns3" link set ns3eth4 up
 ip -net "$ns3" route add default via 10.0.2.1
-ip -net "$ns3" route add default via dead:beef:2::1
 ip netns exec "$ns3" sysctl -q net.ipv4.ip_forward=1
-ip netns exec "$ns3" sysctl -q net.ipv6.conf.all.forwarding=1
 
 ip -net "$ns4" addr add 10.0.3.1/24 dev ns4eth3
-ip -net "$ns4" addr add dead:beef:3::1/64 dev ns4eth3 nodad
 ip -net "$ns4" link set ns4eth3 up
 ip -net "$ns4" route add default via 10.0.3.2
-ip -net "$ns4" route add default via dead:beef:3::2
+
+# IPv6 topology: only configured if MPTCP IPv6 is supported by the
+# running kernel (CONFIG_MPTCP_IPV6=y). On a kernel without it, "ip -6
+# addr add" and the v6 forwarding sysctl would fail and abort the
+# script, taking the v4 tests down with them.
+if $ipv6; then
+	ip -net "$ns1" addr add dead:beef:1::1/64 dev ns1eth2 nodad
+	ip -net "$ns1" route add default via dead:beef:1::2
+
+	ip -net "$ns2" addr add dead:beef:1::2/64 dev ns2eth1 nodad
+	ip -net "$ns2" addr add dead:beef:2::1/64 dev ns2eth3 nodad
+	ip -net "$ns2" route add default via dead:beef:2::2
+	ip netns exec "$ns2" sysctl -q net.ipv6.conf.all.forwarding=1
+
+	ip -net "$ns3" addr add dead:beef:2::2/64 dev ns3eth2 nodad
+	ip -net "$ns3" addr add dead:beef:3::2/64 dev ns3eth4 nodad
+	ip -net "$ns3" route add default via dead:beef:2::1
+	ip netns exec "$ns3" sysctl -q net.ipv6.conf.all.forwarding=1
+
+	ip -net "$ns4" addr add dead:beef:3::1/64 dev ns4eth3 nodad
+	ip -net "$ns4" route add default via dead:beef:3::2
+fi
 
 if $checksum; then
 	for i in "$ns1" "$ns2" "$ns3" "$ns4";do
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH, mptcp-next 4/9] selftests: mptcp: mptcp_connect.sh don't fail because of nft rules in IPV6-less kernel
  2026-06-11 17:07 [PATCH, mptcp-next 0/9] selftests: mptcp: skip the v6 subtests when CONFIG_MPTCP_IPV6=n Gang Yan
                   ` (2 preceding siblings ...)
  2026-06-11 17:07 ` [PATCH, mptcp-next 3/9] selftests: mptcp: mptcp_connect.sh degrades to v4-only when MPTCP IPv6 is missing Gang Yan
@ 2026-06-11 17:07 ` Gang Yan
  2026-06-11 17:07 ` [PATCH, mptcp-next 5/9] selftests: mptcp: mptcp_sockopt.sh skips v6 paths when MPTCP IPv6 is missing Gang Yan
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Gang Yan @ 2026-06-11 17:07 UTC (permalink / raw)
  To: mptcp; +Cc: Gang Yan

From: Gang Yan <yangang@kylinos.cn>

run_test_transparent() loads an nft "table inet mangle" ruleset to
tproxy matching traffic to the listener. "table inet" requires
CONFIG_NF_TABLES_IPV6, which in turn depends on CONFIG_IPV6=y.

In a kernel with full MPTCP IPv6 support, mptcp_lib_is_v6_enabled
returns true and the original CI hard-fail behaviour is preserved
(this is what makes a real "nft is broken on a full kernel" bug
visible to EXPECT_ALL_FEATURES CI). In a CONFIG_IPV6=m kernel the
test is reported as a SKIP and mptcp_connect.sh continues with the
rest of its v4 tests.

Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
 tools/testing/selftests/net/mptcp/mptcp_connect.sh | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.sh b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
index 0e5690d6f68c..9f93924c5d91 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_connect.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
@@ -714,7 +714,11 @@ table inet mangle {
 EOF
 	then
 		mptcp_lib_pr_skip "$msg, could not load nft ruleset"
-		mptcp_lib_fail_if_expected_feature "nft rules"
+		if mptcp_lib_is_v6_enabled; then
+			mptcp_lib_fail_if_expected_feature "nft rules"
+		else
+			mptcp_lib_pr_info "nft inet table needs CONFIG_IPV6=y"
+		fi
 		mptcp_lib_result_skip "${TEST_GROUP}"
 		return
 	fi
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH, mptcp-next 5/9] selftests: mptcp: mptcp_sockopt.sh skips v6 paths when MPTCP IPv6 is missing
  2026-06-11 17:07 [PATCH, mptcp-next 0/9] selftests: mptcp: skip the v6 subtests when CONFIG_MPTCP_IPV6=n Gang Yan
                   ` (3 preceding siblings ...)
  2026-06-11 17:07 ` [PATCH, mptcp-next 4/9] selftests: mptcp: mptcp_connect.sh don't fail because of nft rules in IPV6-less kernel Gang Yan
@ 2026-06-11 17:07 ` Gang Yan
  2026-06-11 17:07 ` [PATCH, mptcp-next 6/9] selftests: mptcp: simult_flows.sh skips v6 setup " Gang Yan
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Gang Yan @ 2026-06-11 17:07 UTC (permalink / raw)
  To: mptcp; +Cc: Gang Yan

From: Gang Yan <yangang@kylinos.cn>

Confine all of ipv6-related commands to mptcp_lib_is_v6_enabled:
  - call mptcp_lib_check_ipv6() once after the existing init-time
    mptcp_lib_check_*() calls to populate the cached flag;
  - guard the ip6tables loop in add_mark_rules() and every v6
    "ip addr add" / mptcp_lib_pm_nl_add_endpoint() in init();
  - in do_mptcp_sockopt_tests(), do_tcpinq_tests() and the top-level
    run_tests dispatcher, emit a SKIP TAP line for each v6 subtest
    instead of running it.

v4 transfers, v4 mark checks and the AF_INET sockopt / TCP_INQ tests
are untouched. In a full-featured kernel the new guards always take
their v6 branch and the test set runs as before.

Assisted-by: GLM:5.1 Z.ai
Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
 .../selftests/net/mptcp/mptcp_sockopt.sh      | 81 ++++++++++++++-----
 1 file changed, 61 insertions(+), 20 deletions(-)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
index e850a87429b6..63f1ec4604ce 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
@@ -50,7 +50,7 @@ add_mark_rules()
 	local m=$2
 
 	local t
-	for t in ${iptables} ${ip6tables}; do
+	for t in ${iptables}; do
 		# just to debug: check we have multiple subflows connection requests
 		ip netns exec $ns $t -A OUTPUT -p tcp --syn -m mark --mark $m -j ACCEPT
 
@@ -60,6 +60,21 @@ add_mark_rules()
 		ip netns exec $ns $t -A OUTPUT -p tcp -m mark --mark $m -j ACCEPT
 		ip netns exec $ns $t -A OUTPUT -p tcp -m mark --mark 0 -j DROP
 	done
+	# ip6tables rules require MPTCP IPv6 support in the kernel, otherwise
+	# ip6tables will reject them (or, in some environments, the binary itself
+	# may behave oddly without IPv6 available).
+	if mptcp_lib_is_v6_enabled; then
+		for t in ${ip6tables}; do
+			# just to debug: check we have multiple subflows connection requests
+			ip netns exec $ns $t -A OUTPUT -p tcp --syn -m mark --mark $m -j ACCEPT
+
+			# RST packets might be handled by a internal dummy socket
+			ip netns exec $ns $t -A OUTPUT -p tcp --tcp-flags RST RST -m mark --mark 0 -j ACCEPT
+
+			ip netns exec $ns $t -A OUTPUT -p tcp -m mark --mark $m -j ACCEPT
+			ip netns exec $ns $t -A OUTPUT -p tcp -m mark --mark 0 -j DROP
+		done
+	fi
 }
 
 init()
@@ -70,21 +85,29 @@ init()
 	for i in $(seq 1 4); do
 		ip link add ns1eth$i netns "$ns1" type veth peer name ns2eth$i netns "$ns2"
 		ip -net "$ns1" addr add 10.0.$i.1/24 dev ns1eth$i
-		ip -net "$ns1" addr add dead:beef:$i::1/64 dev ns1eth$i nodad
+		if mptcp_lib_is_v6_enabled; then
+			ip -net "$ns1" addr add dead:beef:$i::1/64 dev ns1eth$i nodad
+		fi
 		ip -net "$ns1" link set ns1eth$i up
 
 		ip -net "$ns2" addr add 10.0.$i.2/24 dev ns2eth$i
-		ip -net "$ns2" addr add dead:beef:$i::2/64 dev ns2eth$i nodad
+		if mptcp_lib_is_v6_enabled; then
+			ip -net "$ns2" addr add dead:beef:$i::2/64 dev ns2eth$i nodad
+		fi
 		ip -net "$ns2" link set ns2eth$i up
 
 		# let $ns2 reach any $ns1 address from any interface
 		ip -net "$ns2" route add default via 10.0.$i.1 dev ns2eth$i metric 10$i
 
 		mptcp_lib_pm_nl_add_endpoint "${ns1}" "10.0.${i}.1" flags signal
-		mptcp_lib_pm_nl_add_endpoint "${ns1}" "dead:beef:${i}::1" flags signal
+		if mptcp_lib_is_v6_enabled; then
+			mptcp_lib_pm_nl_add_endpoint "${ns1}" "dead:beef:${i}::1" flags signal
+		fi
 
 		mptcp_lib_pm_nl_add_endpoint "${ns2}" "10.0.${i}.2" flags signal
-		mptcp_lib_pm_nl_add_endpoint "${ns2}" "dead:beef:${i}::2" flags signal
+		if mptcp_lib_is_v6_enabled; then
+			mptcp_lib_pm_nl_add_endpoint "${ns2}" "dead:beef:${i}::2" flags signal
+		fi
 	done
 
 	mptcp_lib_pm_nl_set_limits "${ns1}" 8 8
@@ -106,6 +129,7 @@ cleanup()
 mptcp_lib_check_mptcp
 mptcp_lib_check_kallsyms
 mptcp_lib_check_tools ip "${iptables}" "${ip6tables}"
+mptcp_lib_check_ipv6
 
 check_mark()
 {
@@ -274,18 +298,24 @@ do_mptcp_sockopt_tests()
 	mptcp_lib_pr_ok
 	mptcp_lib_result_pass "sockopt v4"
 
-	ip netns exec "$ns_sbox" ./mptcp_sockopt -6
-	lret=$?
+	if ! mptcp_lib_is_v6_enabled; then
+		print_title "SOL_MPTCP sockopt v6"
+		mptcp_lib_pr_skip "MPTCP IPv6 not available"
+		mptcp_lib_result_skip "sockopt v6"
+	else
+		ip netns exec "$ns_sbox" ./mptcp_sockopt -6
+		lret=$?
 
-	print_title "SOL_MPTCP sockopt v6"
-	if [ $lret -ne 0 ]; then
-		mptcp_lib_pr_fail
-		mptcp_lib_result_fail "sockopt v6"
-		ret=$lret
-		return
+		print_title "SOL_MPTCP sockopt v6"
+		if [ $lret -ne 0 ]; then
+			mptcp_lib_pr_fail
+			mptcp_lib_result_fail "sockopt v6"
+			ret=$lret
+			return
+		fi
+		mptcp_lib_pr_ok
+		mptcp_lib_result_pass "sockopt v6"
 	fi
-	mptcp_lib_pr_ok
-	mptcp_lib_result_pass "sockopt v6"
 }
 
 run_tests()
@@ -339,10 +369,16 @@ do_tcpinq_tests()
 		if [ $lret -ne 0 ] ; then
 			return $lret
 		fi
-		do_tcpinq_test -6 $args
-		lret=$?
-		if [ $lret -ne 0 ] ; then
-			return $lret
+		if mptcp_lib_is_v6_enabled; then
+			do_tcpinq_test -6 $args
+			lret=$?
+			if [ $lret -ne 0 ] ; then
+				return $lret
+			fi
+		else
+			print_title "TCP_INQ cmsg/ioctl -6 $args"
+			mptcp_lib_pr_skip "MPTCP IPv6 not available"
+			mptcp_lib_result_skip "TCP_INQ: -6 $args"
 		fi
 	done
 
@@ -362,7 +398,12 @@ make_file "$sin" "server" 1
 mptcp_lib_subtests_last_ts_reset
 
 run_tests $ns1 $ns2 10.0.1.1
-run_tests $ns1 $ns2 dead:beef:1::1
+if mptcp_lib_is_v6_enabled; then
+	run_tests $ns1 $ns2 dead:beef:1::1
+else
+	mptcp_lib_result_skip "transfer ipv6"
+	mptcp_lib_result_skip "mark ipv6"
+fi
 
 do_mptcp_sockopt_tests
 do_tcpinq_tests
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH, mptcp-next 6/9] selftests: mptcp: simult_flows.sh skips v6 setup when MPTCP IPv6 is missing
  2026-06-11 17:07 [PATCH, mptcp-next 0/9] selftests: mptcp: skip the v6 subtests when CONFIG_MPTCP_IPV6=n Gang Yan
                   ` (4 preceding siblings ...)
  2026-06-11 17:07 ` [PATCH, mptcp-next 5/9] selftests: mptcp: mptcp_sockopt.sh skips v6 paths when MPTCP IPv6 is missing Gang Yan
@ 2026-06-11 17:07 ` Gang Yan
  2026-06-11 17:07 ` [PATCH, mptcp-next 7/9] selftests: mptcp: mptcp_join.sh: pick v4 bind default " Gang Yan
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Gang Yan @ 2026-06-11 17:07 UTC (permalink / raw)
  To: mptcp; +Cc: Gang Yan

From: Gang Yan <yangang@kylinos.cn>

On a CONFIG_IPV6=m kernel (which forces
CONFIG_MPTCP_IPV6=n) every v6 setup step errors out, setup() exits
non-zero and all subtests report spurious failures.

Call mptcp_lib_check_ipv6() at script init, then collect the entire
v6 setup into a single "if mptcp_lib_is_v6_enabled; then ... fi"
block at the end of setup(). v4 topology and run_test invocations
are untouched; in a full-featured kernel the block is always taken
and the script runs as before.

Assisted-by: GLM:5.1 Z.ai
Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
 .../selftests/net/mptcp/simult_flows.sh       | 30 ++++++++++++-------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/tools/testing/selftests/net/mptcp/simult_flows.sh b/tools/testing/selftests/net/mptcp/simult_flows.sh
index 3ea3d1efe32e..7f9c6a343aaa 100755
--- a/tools/testing/selftests/net/mptcp/simult_flows.sh
+++ b/tools/testing/selftests/net/mptcp/simult_flows.sh
@@ -48,6 +48,7 @@ cleanup()
 
 mptcp_lib_check_mptcp
 mptcp_lib_check_tools ip tc
+mptcp_lib_check_ipv6
 
 #  "$ns1"              ns2                    ns3
 #     ns1eth1    ns2eth1   ns2eth3      ns3eth1
@@ -81,39 +82,48 @@ setup()
 	ip link add ns2eth3 netns "$ns2" type veth peer name ns3eth1 netns "$ns3"
 
 	ip -net "$ns1" addr add 10.0.1.1/24 dev ns1eth1
-	ip -net "$ns1" addr add dead:beef:1::1/64 dev ns1eth1 nodad
 	ip -net "$ns1" link set ns1eth1 up mtu 1500 gso_max_segs 0
 	ip -net "$ns1" route add default via 10.0.1.2
-	ip -net "$ns1" route add default via dead:beef:1::2
 
 	ip -net "$ns1" addr add 10.0.2.1/24 dev ns1eth2
-	ip -net "$ns1" addr add dead:beef:2::1/64 dev ns1eth2 nodad
 	ip -net "$ns1" link set ns1eth2 up mtu 1500 gso_max_segs 0
 	ip -net "$ns1" route add default via 10.0.2.2 metric 101
-	ip -net "$ns1" route add default via dead:beef:2::2 metric 101
 
 	mptcp_lib_pm_nl_set_limits "${ns1}" 1 1
 	mptcp_lib_pm_nl_add_endpoint "${ns1}" 10.0.2.1 dev ns1eth2 flags subflow
 
 	ip -net "$ns2" addr add 10.0.1.2/24 dev ns2eth1
-	ip -net "$ns2" addr add dead:beef:1::2/64 dev ns2eth1 nodad
 	ip -net "$ns2" link set ns2eth1 up mtu 1500 gso_max_segs 0
 
 	ip -net "$ns2" addr add 10.0.2.2/24 dev ns2eth2
-	ip -net "$ns2" addr add dead:beef:2::2/64 dev ns2eth2 nodad
 	ip -net "$ns2" link set ns2eth2 up mtu 1500 gso_max_segs 0
 
 	ip -net "$ns2" addr add 10.0.3.2/24 dev ns2eth3
-	ip -net "$ns2" addr add dead:beef:3::2/64 dev ns2eth3 nodad
 	ip -net "$ns2" link set ns2eth3 up mtu 1500 gso_max_segs 0
 	ip netns exec "$ns2" sysctl -q net.ipv4.ip_forward=1
-	ip netns exec "$ns2" sysctl -q net.ipv6.conf.all.forwarding=1
 
 	ip -net "$ns3" addr add 10.0.3.3/24 dev ns3eth1
-	ip -net "$ns3" addr add dead:beef:3::3/64 dev ns3eth1 nodad
 	ip -net "$ns3" link set ns3eth1 up mtu 1500 gso_max_segs 0
 	ip -net "$ns3" route add default via 10.0.3.2
-	ip -net "$ns3" route add default via dead:beef:3::2
+
+	# IPv6 topology: only configured if MPTCP IPv6 is supported by the
+	# running kernel (CONFIG_MPTCP_IPV6=y). On a kernel without it,
+	# "ip -6 addr add", "ip -6 route add" and the v6 forwarding sysctl
+	# would fail and abort setup(), taking the v4 tests down with them.
+	if mptcp_lib_is_v6_enabled; then
+		ip -net "$ns1" addr add dead:beef:1::1/64 dev ns1eth1 nodad
+		ip -net "$ns1" route add default via dead:beef:1::2
+		ip -net "$ns1" addr add dead:beef:2::1/64 dev ns1eth2 nodad
+		ip -net "$ns1" route add default via dead:beef:2::2 metric 101
+
+		ip -net "$ns2" addr add dead:beef:1::2/64 dev ns2eth1 nodad
+		ip -net "$ns2" addr add dead:beef:2::2/64 dev ns2eth2 nodad
+		ip -net "$ns2" addr add dead:beef:3::2/64 dev ns2eth3 nodad
+		ip netns exec "$ns2" sysctl -q net.ipv6.conf.all.forwarding=1
+
+		ip -net "$ns3" addr add dead:beef:3::3/64 dev ns3eth1 nodad
+		ip -net "$ns3" route add default via dead:beef:3::2
+	fi
 
 	mptcp_lib_pm_nl_set_limits "${ns3}" 1 1
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH, mptcp-next 7/9] selftests: mptcp: mptcp_join.sh: pick v4 bind default when MPTCP IPv6 is missing
  2026-06-11 17:07 [PATCH, mptcp-next 0/9] selftests: mptcp: skip the v6 subtests when CONFIG_MPTCP_IPV6=n Gang Yan
                   ` (5 preceding siblings ...)
  2026-06-11 17:07 ` [PATCH, mptcp-next 6/9] selftests: mptcp: simult_flows.sh skips v6 setup " Gang Yan
@ 2026-06-11 17:07 ` Gang Yan
  2026-06-11 17:07 ` [PATCH, mptcp-next 8/9] selftests: mptcp: mptcp_join.sh skips v6 subtests " Gang Yan
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Gang Yan @ 2026-06-11 17:07 UTC (permalink / raw)
  To: mptcp; +Cc: Gang Yan

From: Gang Yan <yangang@kylinos.cn>

do_transfer() defaults bind_addr to "::", and mptcp_connect.c
auto-selects the protocol family from the bind string (a ':' forces
AF_INET6). On a kernel without CONFIG_MPTCP_IPV6 the listener becomes
socket(AF_INET6, SOCK_STREAM, IPPROTO_MPTCP), which the kernel rejects
with -EAFNOSUPPORT and every subtest that does not override bind_addr
reports "client exit code 2, server 1" — starting with "001 no JOIN" —
even though nothing v6-specific is being tested.

Pick the default from the mptcp_lib_is_v6_enabled flag when v6 is
available, "0.0.0.0" otherwise. Callers that explicitly set bind_addr
are unaffected.

Assisted-by: GLM:5.1 Z.ai
Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
 tools/testing/selftests/net/mptcp/mptcp_join.sh | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
index 550a6b6117a9..26fb5e433384 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -1004,7 +1004,14 @@ do_transfer()
 	local FAILING_LINKS=${FAILING_LINKS:-""}
 	local fastclose=${fastclose:-""}
 	local speed=${speed:-"fast"}
-	local bind_addr=${bind_addr:-"::"}
+	local bind_addr=${bind_addr:-}
+	if [ -z "${bind_addr}" ]; then
+		if mptcp_lib_is_v6_enabled; then
+			bind_addr="::"
+		else
+			bind_addr="0.0.0.0"
+		fi
+	fi
 	local listener_in="${sin}"
 	local connector_in="${cin}"
 	port=$(get_port)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH, mptcp-next 8/9] selftests: mptcp: mptcp_join.sh skips v6 subtests when MPTCP IPv6 is missing
  2026-06-11 17:07 [PATCH, mptcp-next 0/9] selftests: mptcp: skip the v6 subtests when CONFIG_MPTCP_IPV6=n Gang Yan
                   ` (6 preceding siblings ...)
  2026-06-11 17:07 ` [PATCH, mptcp-next 7/9] selftests: mptcp: mptcp_join.sh: pick v4 bind default " Gang Yan
@ 2026-06-11 17:07 ` Gang Yan
  2026-06-11 17:07 ` [PATCH, mptcp-next 9/9] selftests: mptcp: userspace_pm.sh skips v6 paths " Gang Yan
  2026-06-11 18:07 ` [PATCH, mptcp-next 0/9] selftests: mptcp: skip the v6 subtests when CONFIG_MPTCP_IPV6=n MPTCP CI
  9 siblings, 0 replies; 11+ messages in thread
From: Gang Yan @ 2026-06-11 17:07 UTC (permalink / raw)
  To: mptcp; +Cc: Gang Yan

From: Gang Yan <yangang@kylinos.cn>

mptcp_join.sh pre-stages dead:beef:*::1/2 and v6 default routes in
init_partial(), and dozens of v6 subtests under ipv6_tests,
v4mapped_tests, mixed_tests, add_addr_timeout_tests,
signal_address_tests, link_failure_tests, laminar_endp_tests and
one userspace_tests case drive dead:beef:* or ::ffff:* endpoints. On
a CONFIG_IPV6=m kernel (which forces CONFIG_MPTCP_IPV6=n) all of
this fails.

The fix is mechanical: call mptcp_lib_check_ipv6() from init(),
guard the v6 bits in init_partial(), and prepend the standard
"if ! mptcp_lib_is_v6_enabled; then mptcp_lib_result_skip ...; elif
reset ...; then ...; fi" guard to every v6 subtest. v4 subtests and
the pass/fail behaviour on a full-featured kernel are unchanged.

Assisted-by: GLM:5.1 Z.ai
Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
 .../testing/selftests/net/mptcp/mptcp_join.sh | 145 +++++++++++++-----
 1 file changed, 106 insertions(+), 39 deletions(-)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
index 26fb5e433384..d3adef18b3c7 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -154,16 +154,22 @@ init_partial()
 	for i in $(seq 1 "${ifaces_nr:-4}"); do
 		ip link add ns1eth$i netns "$ns1" type veth peer name ns2eth$i netns "$ns2"
 		ip -net "$ns1" addr add 10.0.$i.1/24 dev ns1eth$i
-		ip -net "$ns1" addr add dead:beef:$i::1/64 dev ns1eth$i nodad
+		if mptcp_lib_is_v6_enabled; then
+			ip -net "$ns1" addr add dead:beef:$i::1/64 dev ns1eth$i nodad
+		fi
 		ip -net "$ns1" link set ns1eth$i up
 
 		ip -net "$ns2" addr add 10.0.$i.2/24 dev ns2eth$i
-		ip -net "$ns2" addr add dead:beef:$i::2/64 dev ns2eth$i nodad
+		if mptcp_lib_is_v6_enabled; then
+			ip -net "$ns2" addr add dead:beef:$i::2/64 dev ns2eth$i nodad
+		fi
 		ip -net "$ns2" link set ns2eth$i up
 
 		# let $ns2 reach any $ns1 address from any interface
 		ip -net "$ns2" route add default via 10.0.$i.1 dev ns2eth$i metric 10$i
-		ip -net "$ns2" route add default via dead:beef:$i::1 dev ns2eth$i metric 10$i
+		if mptcp_lib_is_v6_enabled; then
+			ip -net "$ns2" route add default via dead:beef:$i::1 dev ns2eth$i metric 10$i
+		fi
 	done
 }
 
@@ -189,6 +195,7 @@ init() {
 	mptcp_lib_check_mptcp
 	mptcp_lib_check_kallsyms
 	mptcp_lib_check_tools ip tc ss "${iptables}" "${ip6tables}"
+	mptcp_lib_check_ipv6
 
 	sin=$(mktemp)
 	sout=$(mktemp)
@@ -2395,8 +2402,10 @@ laminar_endp_tests()
 	fi
 
 	# laminar endpoints: these endpoints are used
-	if reset_with_tcp_filter "with multiple laminar endpoints" ns1 10.0.2.2 REJECT &&
-	   continue_if mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "with multiple laminar endpoints"
+	elif reset_with_tcp_filter "with multiple laminar endpoints" ns1 10.0.2.2 REJECT &&
+	     continue_if mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then
 		pm_nl_set_limits $ns1 0 2
 		pm_nl_set_limits $ns2 2 2
 		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
@@ -2538,7 +2547,9 @@ add_addr_timeout_tests()
 	fi
 
 	# add_addr timeout IPv6
-	if reset_with_add_addr_timeout "signal address, ADD_ADDR6 timeout" 6; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "signal address, ADD_ADDR6 timeout"
+	elif reset_with_add_addr_timeout "signal address, ADD_ADDR6 timeout" 6; then
 		pm_nl_set_limits $ns1 0 1
 		pm_nl_set_limits $ns2 1 1
 		pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
@@ -2818,7 +2829,9 @@ add_tests()
 	fi
 
 	# add multiple subflows IPv6
-	if reset "add multiple subflows IPv6"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "add multiple subflows IPv6"
+	elif reset "add multiple subflows IPv6"; then
 		pm_nl_set_limits $ns1 0 2
 		pm_nl_set_limits $ns2 0 2
 		addr_nr_ns2=2 speed=slow cestab_ns2=1 \
@@ -2828,7 +2841,9 @@ add_tests()
 	fi
 
 	# add multiple addresses IPv6
-	if reset "add multiple addresses IPv6"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "add multiple addresses IPv6"
+	elif reset "add multiple addresses IPv6"; then
 		pm_nl_set_limits $ns1 0 2
 		pm_nl_set_limits $ns2 2 2
 		addr_nr_ns1=2 speed=slow cestab_ns1=1 \
@@ -2842,7 +2857,9 @@ add_tests()
 ipv6_tests()
 {
 	# subflow IPv6
-	if reset "single subflow IPv6"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "single subflow IPv6"
+	elif reset "single subflow IPv6"; then
 		pm_nl_set_limits $ns1 0 1
 		pm_nl_set_limits $ns2 0 1
 		pm_nl_add_endpoint $ns2 dead:beef:3::2 dev ns2eth3 flags subflow
@@ -2852,7 +2869,9 @@ ipv6_tests()
 	fi
 
 	# add_address, unused IPv6
-	if reset "unused signal address IPv6"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "unused signal address IPv6"
+	elif reset "unused signal address IPv6"; then
 		pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
 		speed=slow \
 			run_tests $ns1 $ns2 dead:beef:1::1
@@ -2861,7 +2880,9 @@ ipv6_tests()
 	fi
 
 	# signal address IPv6
-	if reset "single address IPv6"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "single address IPv6"
+	elif reset "single address IPv6"; then
 		pm_nl_set_limits $ns1 0 1
 		pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
 		pm_nl_set_limits $ns2 1 1
@@ -2872,7 +2893,9 @@ ipv6_tests()
 	fi
 
 	# single address IPv6, remove
-	if reset "remove single address IPv6"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "remove single address IPv6"
+	elif reset "remove single address IPv6"; then
 		pm_nl_set_limits $ns1 0 1
 		pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
 		pm_nl_set_limits $ns2 1 1
@@ -2884,7 +2907,9 @@ ipv6_tests()
 	fi
 
 	# subflow and signal IPv6, remove
-	if reset "remove subflow and signal IPv6"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "remove subflow and signal IPv6"
+	elif reset "remove subflow and signal IPv6"; then
 		pm_nl_set_limits $ns1 0 2
 		pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
 		pm_nl_set_limits $ns2 1 2
@@ -2900,7 +2925,9 @@ ipv6_tests()
 v4mapped_tests()
 {
 	# subflow IPv4-mapped to IPv4-mapped
-	if reset "single subflow IPv4-mapped"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "single subflow IPv4-mapped"
+	elif reset "single subflow IPv4-mapped"; then
 		pm_nl_set_limits $ns1 0 1
 		pm_nl_set_limits $ns2 0 1
 		pm_nl_add_endpoint $ns2 "::ffff:10.0.3.2" flags subflow
@@ -2909,7 +2936,9 @@ v4mapped_tests()
 	fi
 
 	# signal address IPv4-mapped with IPv4-mapped sk
-	if reset "signal address IPv4-mapped"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "signal address IPv4-mapped"
+	elif reset "signal address IPv4-mapped"; then
 		pm_nl_set_limits $ns1 0 1
 		pm_nl_set_limits $ns2 1 1
 		pm_nl_add_endpoint $ns1 "::ffff:10.0.2.1" flags signal
@@ -2919,7 +2948,9 @@ v4mapped_tests()
 	fi
 
 	# subflow v4-map-v6
-	if reset "single subflow v4-map-v6"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "single subflow v4-map-v6"
+	elif reset "single subflow v4-map-v6"; then
 		pm_nl_set_limits $ns1 0 1
 		pm_nl_set_limits $ns2 0 1
 		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
@@ -2928,7 +2959,9 @@ v4mapped_tests()
 	fi
 
 	# signal address v4-map-v6
-	if reset "signal address v4-map-v6"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "signal address v4-map-v6"
+	elif reset "signal address v4-map-v6"; then
 		pm_nl_set_limits $ns1 0 1
 		pm_nl_set_limits $ns2 1 1
 		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
@@ -2938,7 +2971,9 @@ v4mapped_tests()
 	fi
 
 	# subflow v6-map-v4
-	if reset "single subflow v6-map-v4"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "single subflow v6-map-v4"
+	elif reset "single subflow v6-map-v4"; then
 		pm_nl_set_limits $ns1 0 1
 		pm_nl_set_limits $ns2 0 1
 		pm_nl_add_endpoint $ns2 "::ffff:10.0.3.2" flags subflow
@@ -2947,7 +2982,9 @@ v4mapped_tests()
 	fi
 
 	# signal address v6-map-v4
-	if reset "signal address v6-map-v4"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "signal address v6-map-v4"
+	elif reset "signal address v6-map-v4"; then
 		pm_nl_set_limits $ns1 0 1
 		pm_nl_set_limits $ns2 1 1
 		pm_nl_add_endpoint $ns1 "::ffff:10.0.2.1" flags signal
@@ -2957,7 +2994,9 @@ v4mapped_tests()
 	fi
 
 	# no subflow IPv6 to v4 address
-	if reset "no JOIN with diff families v4-v6"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "no JOIN with diff families v4-v6"
+	elif reset "no JOIN with diff families v4-v6"; then
 		pm_nl_set_limits $ns1 0 1
 		pm_nl_set_limits $ns2 0 1
 		pm_nl_add_endpoint $ns2 dead:beef:2::2 flags subflow
@@ -2966,7 +3005,9 @@ v4mapped_tests()
 	fi
 
 	# no subflow IPv6 to v4 address even if v6 has a valid v4 at the end
-	if reset "no JOIN with diff families v4-v6-2"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "no JOIN with diff families v4-v6-2"
+	elif reset "no JOIN with diff families v4-v6-2"; then
 		pm_nl_set_limits $ns1 0 1
 		pm_nl_set_limits $ns2 0 1
 		pm_nl_add_endpoint $ns2 dead:beef:2::10.0.3.2 flags subflow
@@ -2975,7 +3016,9 @@ v4mapped_tests()
 	fi
 
 	# no subflow IPv4 to v6 address, no need to slow down too then
-	if reset "no JOIN with diff families v6-v4"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "no JOIN with diff families v6-v4"
+	elif reset "no JOIN with diff families v6-v4"; then
 		pm_nl_set_limits $ns1 0 1
 		pm_nl_set_limits $ns2 0 1
 		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
@@ -2986,8 +3029,10 @@ v4mapped_tests()
 
 mixed_tests()
 {
-	if reset "IPv4 sockets do not use IPv6 addresses" &&
-	   continue_if mptcp_lib_kversion_ge 6.3; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "IPv4 sockets do not use IPv6 addresses"
+	elif reset "IPv4 sockets do not use IPv6 addresses" &&
+	     continue_if mptcp_lib_kversion_ge 6.3; then
 		pm_nl_set_limits $ns1 0 1
 		pm_nl_set_limits $ns2 1 1
 		pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
@@ -2997,8 +3042,10 @@ mixed_tests()
 	fi
 
 	# Need an IPv6 mptcp socket to allow subflows of both families
-	if reset "simult IPv4 and IPv6 subflows" &&
-	   continue_if mptcp_lib_kversion_ge 6.3; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "simult IPv4 and IPv6 subflows"
+	elif reset "simult IPv4 and IPv6 subflows" &&
+	     continue_if mptcp_lib_kversion_ge 6.3; then
 		pm_nl_set_limits $ns1 0 1
 		pm_nl_set_limits $ns2 1 1
 		pm_nl_add_endpoint $ns1 10.0.1.1 flags signal
@@ -3008,8 +3055,10 @@ mixed_tests()
 	fi
 
 	# cross families subflows will not be created even in fullmesh mode
-	if reset "simult IPv4 and IPv6 subflows, fullmesh 1x1" &&
-	   continue_if mptcp_lib_kversion_ge 6.3; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "simult IPv4 and IPv6 subflows, fullmesh 1x1"
+	elif reset "simult IPv4 and IPv6 subflows, fullmesh 1x1" &&
+	     continue_if mptcp_lib_kversion_ge 6.3; then
 		pm_nl_set_limits $ns1 0 4
 		pm_nl_set_limits $ns2 1 4
 		pm_nl_add_endpoint $ns2 dead:beef:2::2 flags subflow,fullmesh
@@ -3025,8 +3074,10 @@ mixed_tests()
 
 	# fullmesh still tries to create all the possibly subflows with
 	# matching family
-	if reset "simult IPv4 and IPv6 subflows, fullmesh 2x2" &&
-	   continue_if mptcp_lib_kversion_ge 6.3; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "simult IPv4 and IPv6 subflows, fullmesh 2x2"
+	elif reset "simult IPv4 and IPv6 subflows, fullmesh 2x2" &&
+	     continue_if mptcp_lib_kversion_ge 6.3; then
 		pm_nl_set_limits $ns1 0 4
 		pm_nl_set_limits $ns2 2 4
 		pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
@@ -3206,8 +3257,10 @@ add_addr_ports_tests()
 	fi
 
 	# signal address v6 with port
-	if reset "signal address v6 with port" &&
-	   continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/add_addr_v6_port_drop_ts'; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "signal address v6 with port"
+	elif reset "signal address v6 with port" &&
+	     continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/add_addr_v6_port_drop_ts'; then
 		pm_nl_set_limits $ns1 0 1
 		pm_nl_set_limits $ns2 1 1
 		pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal port 10100
@@ -3312,7 +3365,9 @@ add_addr_ports_tests()
 	fi
 
 	# first signal address drops, second one still progresses
-	if reset "signal addr list progresses after tx drop"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "signal addr list progresses after tx drop"
+	elif reset "signal addr list progresses after tx drop"; then
 		pm_nl_set_limits $ns1 0 2
 		pm_nl_set_limits $ns2 1 0
 		ip netns exec $ns1 sysctl -q net.mptcp.add_addr_v6_port_drop_ts=0 2>/dev/null || true
@@ -3342,7 +3397,9 @@ bind_tests()
 	fi
 
 	# bind to one address should not allow extra subflows to other addresses
-	if reset "bind main address v6, no join v6"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "bind main address v6, no join v6"
+	elif reset "bind main address v6, no join v6"; then
 		pm_nl_set_limits $ns1 0 2
 		pm_nl_set_limits $ns2 2 2
 		pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal
@@ -3376,7 +3433,9 @@ bind_tests()
 	fi
 
 	# multiple binds to allow extra subflows to other addresses
-	if reset "multiple bind to allow joins v6"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "multiple bind to allow joins v6"
+	elif reset "multiple bind to allow joins v6"; then
 		local extra_bind
 
 		pm_nl_set_limits $ns1 0 2
@@ -3398,7 +3457,9 @@ bind_tests()
 	fi
 
 	# multiple binds to allow extra subflows to other addresses: v6 LL case
-	if reset "multiple bind to allow joins v6 link-local routing"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "multiple bind to allow joins v6 link-local routing"
+	elif reset "multiple bind to allow joins v6 link-local routing"; then
 		local extra_bind ns1ll1 ns1ll2
 
 		ns1ll1="$(get_ll_addr $ns1 ns1eth1)"
@@ -3426,8 +3487,10 @@ bind_tests()
 	fi
 
 	# multiple binds to allow extra subflows to v6 LL addresses: laminar
-	if reset "multiple bind to allow joins v6 link-local laminar" &&
-	   continue_if mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "multiple bind to allow joins v6 link-local laminar"
+	elif reset "multiple bind to allow joins v6 link-local laminar" &&
+	     continue_if mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then
 		local extra_bind ns1ll1 ns1ll2 ns2ll2
 
 		ns1ll1="$(get_ll_addr $ns1 ns1eth1)"
@@ -4072,7 +4135,11 @@ userspace_tests()
 	fi
 
 	# userspace pm add & remove address
-	if reset_with_events "userspace pm add & remove address" &&
+	# The test uses the v4-mapped address "::ffff:10.0.2.1" in
+	# userspace_pm_rm_sf, which requires CONFIG_MPTCP_IPV6=y in the kernel.
+	if ! mptcp_lib_is_v6_enabled; then
+		mptcp_lib_result_skip "userspace pm add & remove address"
+	elif reset_with_events "userspace pm add & remove address" &&
 	   continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
 		set_userspace_pm $ns1
 		pm_nl_set_limits $ns2 2 2
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH, mptcp-next 9/9] selftests: mptcp: userspace_pm.sh skips v6 paths when MPTCP IPv6 is missing
  2026-06-11 17:07 [PATCH, mptcp-next 0/9] selftests: mptcp: skip the v6 subtests when CONFIG_MPTCP_IPV6=n Gang Yan
                   ` (7 preceding siblings ...)
  2026-06-11 17:07 ` [PATCH, mptcp-next 8/9] selftests: mptcp: mptcp_join.sh skips v6 subtests " Gang Yan
@ 2026-06-11 17:07 ` Gang Yan
  2026-06-11 18:07 ` [PATCH, mptcp-next 0/9] selftests: mptcp: skip the v6 subtests when CONFIG_MPTCP_IPV6=n MPTCP CI
  9 siblings, 0 replies; 11+ messages in thread
From: Gang Yan @ 2026-06-11 17:07 UTC (permalink / raw)
  To: mptcp; +Cc: Gang Yan

From: Gang Yan <yangang@kylinos.cn>

Call mptcp_lib_check_ipv6() at script init, then guard every v6
step — the init-time dead:beef:* assignments, the v6 PM sequences
inside test_announce()/test_remove()/test_subflows(), and the
top-level make_connection "v6" / test_subflows_v4_v6_mix() calls —
with mptcp_lib_is_v6_enabled. Each v6-only subtest emits a SKIP TAP
line under its existing name when v6 is unavailable. v4 paths and
the pass/fail behaviour on a full-featured kernel are unchanged.

Assisted-by: GLM:5.1 Z.ai
Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
 .../selftests/net/mptcp/userspace_pm.sh       | 237 ++++++++++--------
 1 file changed, 131 insertions(+), 106 deletions(-)

diff --git a/tools/testing/selftests/net/mptcp/userspace_pm.sh b/tools/testing/selftests/net/mptcp/userspace_pm.sh
index e9ae1806ab07..8a20d33b1f03 100755
--- a/tools/testing/selftests/net/mptcp/userspace_pm.sh
+++ b/tools/testing/selftests/net/mptcp/userspace_pm.sh
@@ -18,6 +18,7 @@ if ! mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
 	exit ${KSFT_SKIP}
 fi
 mptcp_lib_check_tools ip
+mptcp_lib_check_ipv6
 
 ANNOUNCED=${MPTCP_LIB_EVENT_ANNOUNCED}
 REMOVED=${MPTCP_LIB_EVENT_REMOVED}
@@ -159,14 +160,18 @@ ip link add ns1eth2 netns "$ns1" type veth peer name ns2eth1 netns "$ns2"
 # Add IPv4/v6 addresses to the namespaces
 ip -net "$ns1" addr add 10.0.1.1/24 dev ns1eth2
 ip -net "$ns1" addr add 10.0.2.1/24 dev ns1eth2
-ip -net "$ns1" addr add dead:beef:1::1/64 dev ns1eth2 nodad
-ip -net "$ns1" addr add dead:beef:2::1/64 dev ns1eth2 nodad
+if mptcp_lib_is_v6_enabled; then
+	ip -net "$ns1" addr add dead:beef:1::1/64 dev ns1eth2 nodad
+	ip -net "$ns1" addr add dead:beef:2::1/64 dev ns1eth2 nodad
+fi
 ip -net "$ns1" link set ns1eth2 up
 
 ip -net "$ns2" addr add 10.0.1.2/24 dev ns2eth1
 ip -net "$ns2" addr add 10.0.2.2/24 dev ns2eth1
-ip -net "$ns2" addr add dead:beef:1::2/64 dev ns2eth1 nodad
-ip -net "$ns2" addr add dead:beef:2::2/64 dev ns2eth1 nodad
+if mptcp_lib_is_v6_enabled; then
+	ip -net "$ns2" addr add dead:beef:1::2/64 dev ns2eth1 nodad
+	ip -net "$ns2" addr add dead:beef:2::2/64 dev ns2eth1 nodad
+fi
 ip -net "$ns2" link set ns2eth1 up
 
 file=$(mktemp)
@@ -344,13 +349,15 @@ test_announce()
 			      "$client4_port"
 
 	# ADD_ADDR6 from the client to server machine reusing the subflow port
-	:>"$server_evts"
-	ip netns exec "$ns2" ./pm_nl_ctl ann\
-	   dead:beef:2::2 token "$client6_token" id $client_addr_id dev ns2eth1
-	print_test "ADD_ADDR6 id:client dead:beef:2::2 (ns2) => ns1, reuse port"
-	sleep 0.5
-	verify_announce_event "$server_evts" "$ANNOUNCED" "$server6_token" "dead:beef:2::2"\
-			      "$client_addr_id" "$client6_port" "v6"
+	if mptcp_lib_is_v6_enabled; then
+		:>"$server_evts"
+		ip netns exec "$ns2" ./pm_nl_ctl ann\
+		   dead:beef:2::2 token "$client6_token" id $client_addr_id dev ns2eth1
+		print_test "ADD_ADDR6 id:client dead:beef:2::2 (ns2) => ns1, reuse port"
+		sleep 0.5
+		verify_announce_event "$server_evts" "$ANNOUNCED" "$server6_token" "dead:beef:2::2"\
+				      "$client_addr_id" "$client6_port" "v6"
+	fi
 
 	# ADD_ADDR from the client to server machine using a new port
 	:>"$server_evts"
@@ -374,13 +381,15 @@ test_announce()
 			      "$server_addr_id" "$app4_port"
 
 	# ADD_ADDR6 from the server to client machine reusing the subflow port
-	:>"$client_evts"
-	ip netns exec "$ns1" ./pm_nl_ctl ann dead:beef:2::1 token "$server6_token" id\
-	   $server_addr_id dev ns1eth2
-	print_test "ADD_ADDR6 id:server dead:beef:2::1 (ns1) => ns2, reuse port"
-	sleep 0.5
-	verify_announce_event "$client_evts" "$ANNOUNCED" "$client6_token" "dead:beef:2::1"\
-			      "$server_addr_id" "$app6_port" "v6"
+	if mptcp_lib_is_v6_enabled; then
+		:>"$client_evts"
+		ip netns exec "$ns1" ./pm_nl_ctl ann dead:beef:2::1 token "$server6_token" id\
+		   $server_addr_id dev ns1eth2
+		print_test "ADD_ADDR6 id:server dead:beef:2::1 (ns1) => ns2, reuse port"
+		sleep 0.5
+		verify_announce_event "$client_evts" "$ANNOUNCED" "$client6_token" "dead:beef:2::1"\
+				      "$server_addr_id" "$app6_port" "v6"
+	fi
 
 	# ADD_ADDR from the server to client machine using a new port
 	:>"$client_evts"
@@ -462,12 +471,14 @@ test_remove()
 	verify_remove_event "$server_evts" "$REMOVED" "$server4_token" "$client_addr_id"
 
 	# RM_ADDR6 from the client to server machine
-	:>"$server_evts"
-	ip netns exec "$ns2" ./pm_nl_ctl rem token "$client6_token" id\
-	   $client_addr_id
-	print_test "RM_ADDR6 id:client-1 ns2 => ns1"
-	sleep 0.5
-	verify_remove_event "$server_evts" "$REMOVED" "$server6_token" "$client_addr_id"
+	if mptcp_lib_is_v6_enabled; then
+		:>"$server_evts"
+		ip netns exec "$ns2" ./pm_nl_ctl rem token "$client6_token" id\
+		   $client_addr_id
+		print_test "RM_ADDR6 id:client-1 ns2 => ns1"
+		sleep 0.5
+		verify_remove_event "$server_evts" "$REMOVED" "$server6_token" "$client_addr_id"
+	fi
 
 	# Capture events on the network namespace running the client
 	:>"$client_evts"
@@ -489,12 +500,14 @@ test_remove()
 	verify_remove_event "$client_evts" "$REMOVED" "$client4_token" "$server_addr_id"
 
 	# RM_ADDR6 from the server to client machine
-	:>"$client_evts"
-	ip netns exec "$ns1" ./pm_nl_ctl rem token "$server6_token" id\
-	   $server_addr_id
-	print_test "RM_ADDR6 id:server-1 ns1 => ns2"
-	sleep 0.5
-	verify_remove_event "$client_evts" "$REMOVED" "$client6_token" "$server_addr_id"
+	if mptcp_lib_is_v6_enabled; then
+		:>"$client_evts"
+		ip netns exec "$ns1" ./pm_nl_ctl rem token "$server6_token" id\
+		   $server_addr_id
+		print_test "RM_ADDR6 id:server-1 ns1 => ns2"
+		sleep 0.5
+		verify_remove_event "$client_evts" "$REMOVED" "$client6_token" "$server_addr_id"
+	fi
 }
 
 verify_subflow_events()
@@ -609,43 +622,45 @@ test_subflows()
 	sleep 0.5
 
 	# Attempt to add a listener at dead:beef:2::2:<subflow-port>
-	ip netns exec "$ns2" ./pm_nl_ctl listen dead:beef:2::2\
-	   "$client6_port" &
-	listener_pid=$!
-
-	# ADD_ADDR6 from client to server machine reusing the subflow port
-	:>"$server_evts"
-	ip netns exec "$ns2" ./pm_nl_ctl ann dead:beef:2::2 token "$client6_token" id\
-	   $client_addr_id
-	sleep 0.5
-
-	# CREATE_SUBFLOW6 from server to client machine
-	:>"$server_evts"
-	ip netns exec "$ns1" ./pm_nl_ctl csf lip dead:beef:2::1 lid 23 rip\
-	   dead:beef:2::2 rport "$client6_port" token "$server6_token"
-	sleep 0.5
-	verify_subflow_events "$server_evts" "$SUB_ESTABLISHED" "$server6_token" "$AF_INET6"\
-			      "dead:beef:2::1" "dead:beef:2::2" "$client6_port" "23"\
-			      "$client_addr_id" "ns1" "ns2"
-
-	# Delete the listener from the client ns, if one was created
-	mptcp_lib_kill_wait $listener_pid
-
-	sport=$(mptcp_lib_evts_get_info sport "$server_evts" $SUB_ESTABLISHED)
-
-	# DESTROY_SUBFLOW6 from server to client machine
-	:>"$server_evts"
-	ip netns exec "$ns1" ./pm_nl_ctl dsf lip dead:beef:2::1 lport "$sport" rip\
-	   dead:beef:2::2 rport "$client6_port" token "$server6_token"
-	sleep 0.5
-	verify_subflow_events "$server_evts" "$SUB_CLOSED" "$server6_token" "$AF_INET6"\
-			      "dead:beef:2::1" "dead:beef:2::2" "$client6_port" "23"\
-			      "$client_addr_id" "ns1" "ns2"
-
-	# RM_ADDR from client to server machine
-	ip netns exec "$ns2" ./pm_nl_ctl rem id $client_addr_id token\
-	   "$client6_token"
-	sleep 0.5
+	if mptcp_lib_is_v6_enabled; then
+		ip netns exec "$ns2" ./pm_nl_ctl listen dead:beef:2::2\
+		   "$client6_port" &
+		listener_pid=$!
+
+		# ADD_ADDR6 from client to server machine reusing the subflow port
+		:>"$server_evts"
+		ip netns exec "$ns2" ./pm_nl_ctl ann dead:beef:2::2 token "$client6_token" id\
+		   $client_addr_id
+		sleep 0.5
+
+		# CREATE_SUBFLOW6 from server to client machine
+		:>"$server_evts"
+		ip netns exec "$ns1" ./pm_nl_ctl csf lip dead:beef:2::1 lid 23 rip\
+		   dead:beef:2::2 rport "$client6_port" token "$server6_token"
+		sleep 0.5
+		verify_subflow_events "$server_evts" "$SUB_ESTABLISHED" "$server6_token" "$AF_INET6"\
+				      "dead:beef:2::1" "dead:beef:2::2" "$client6_port" "23"\
+				      "$client_addr_id" "ns1" "ns2"
+
+		# Delete the listener from the client ns, if one was created
+		mptcp_lib_kill_wait $listener_pid
+
+		sport=$(mptcp_lib_evts_get_info sport "$server_evts" $SUB_ESTABLISHED)
+
+		# DESTROY_SUBFLOW6 from server to client machine
+		:>"$server_evts"
+		ip netns exec "$ns1" ./pm_nl_ctl dsf lip dead:beef:2::1 lport "$sport" rip\
+		   dead:beef:2::2 rport "$client6_port" token "$server6_token"
+		sleep 0.5
+		verify_subflow_events "$server_evts" "$SUB_CLOSED" "$server6_token" "$AF_INET6"\
+				      "dead:beef:2::1" "dead:beef:2::2" "$client6_port" "23"\
+				      "$client_addr_id" "ns1" "ns2"
+
+		# RM_ADDR from client to server machine
+		ip netns exec "$ns2" ./pm_nl_ctl rem id $client_addr_id token\
+		   "$client6_token"
+		sleep 0.5
+	fi
 
 	# Attempt to add a listener at 10.0.2.2:<new-port>
 	ip netns exec "$ns2" ./pm_nl_ctl listen 10.0.2.2\
@@ -724,43 +739,45 @@ test_subflows()
 	sleep 0.5
 
 	# Attempt to add a listener at dead:beef:2::1:<subflow-port>
-	ip netns exec "$ns1" ./pm_nl_ctl listen dead:beef:2::1\
-	   $app6_port &
-	listener_pid=$!
-
-	# ADD_ADDR6 from server to client machine reusing the subflow port
-	:>"$client_evts"
-	ip netns exec "$ns1" ./pm_nl_ctl ann dead:beef:2::1 token "$server6_token" id\
-	   $server_addr_id
-	sleep 0.5
-
-	# CREATE_SUBFLOW6 from client to server machine
-	:>"$client_evts"
-	ip netns exec "$ns2" ./pm_nl_ctl csf lip dead:beef:2::2 lid 23 rip\
-	   dead:beef:2::1 rport $app6_port token "$client6_token"
-	sleep 0.5
-	verify_subflow_events "$client_evts" "$SUB_ESTABLISHED" "$client6_token"\
-			      "$AF_INET6" "dead:beef:2::2"\
-			      "dead:beef:2::1" "$app6_port" "23"\
-			      "$server_addr_id" "ns2" "ns1"
-
-	# Delete the listener from the server ns, if one was created
-	mptcp_lib_kill_wait $listener_pid
-
-	sport=$(mptcp_lib_evts_get_info sport "$client_evts" $SUB_ESTABLISHED)
-
-	# DESTROY_SUBFLOW6 from client to server machine
-	:>"$client_evts"
-	ip netns exec "$ns2" ./pm_nl_ctl dsf lip dead:beef:2::2 lport "$sport" rip\
-	   dead:beef:2::1 rport $app6_port token "$client6_token"
-	sleep 0.5
-	verify_subflow_events $client_evts $SUB_CLOSED $client6_token $AF_INET6 "dead:beef:2::2"\
-			      "dead:beef:2::1" "$app6_port" "23" "$server_addr_id" "ns2" "ns1"
-
-	# RM_ADDR6 from server to client machine
-	ip netns exec "$ns1" ./pm_nl_ctl rem id $server_addr_id token\
-	   "$server6_token"
-	sleep 0.5
+	if mptcp_lib_is_v6_enabled; then
+		ip netns exec "$ns1" ./pm_nl_ctl listen dead:beef:2::1\
+		   $app6_port &
+		listener_pid=$!
+
+		# ADD_ADDR6 from server to client machine reusing the subflow port
+		:>"$client_evts"
+		ip netns exec "$ns1" ./pm_nl_ctl ann dead:beef:2::1 token "$server6_token" id\
+		   $server_addr_id
+		sleep 0.5
+
+		# CREATE_SUBFLOW6 from client to server machine
+		:>"$client_evts"
+		ip netns exec "$ns2" ./pm_nl_ctl csf lip dead:beef:2::2 lid 23 rip\
+		   dead:beef:2::1 rport $app6_port token "$client6_token"
+		sleep 0.5
+		verify_subflow_events "$client_evts" "$SUB_ESTABLISHED" "$client6_token"\
+				      "$AF_INET6" "dead:beef:2::2"\
+				      "dead:beef:2::1" "$app6_port" "23"\
+				      "$server_addr_id" "ns2" "ns1"
+
+		# Delete the listener from the server ns, if one was created
+		mptcp_lib_kill_wait $listener_pid
+
+		sport=$(mptcp_lib_evts_get_info sport "$client_evts" $SUB_ESTABLISHED)
+
+		# DESTROY_SUBFLOW6 from client to server machine
+		:>"$client_evts"
+		ip netns exec "$ns2" ./pm_nl_ctl dsf lip dead:beef:2::2 lport "$sport" rip\
+		   dead:beef:2::1 rport $app6_port token "$client6_token"
+		sleep 0.5
+		verify_subflow_events $client_evts $SUB_CLOSED $client6_token $AF_INET6 "dead:beef:2::2"\
+				      "dead:beef:2::1" "$app6_port" "23" "$server_addr_id" "ns2" "ns1"
+
+		# RM_ADDR6 from server to client machine
+		ip netns exec "$ns1" ./pm_nl_ctl rem id $server_addr_id token\
+		   "$server6_token"
+		sleep 0.5
+	fi
 
 	# Attempt to add a listener at 10.0.2.1:<new-port>
 	ip netns exec "$ns1" ./pm_nl_ctl listen 10.0.2.1\
@@ -931,13 +948,21 @@ test_listener()
 
 print_title "Make connections"
 make_connection
-make_connection "v6"
+if mptcp_lib_is_v6_enabled; then
+	make_connection "v6"
+else
+	# Track this as a skipped test for TAP output
+	test_name="Established IPv6 MPTCP Connection ns2 => ns1"
+	test_skip
+fi
 print_title "Will be using address IDs ${client_addr_id} (client) and ${server_addr_id} (server)"
 
 test_announce
 test_remove
 test_subflows
-test_subflows_v4_v6_mix
+if mptcp_lib_is_v6_enabled; then
+	test_subflows_v4_v6_mix
+fi
 test_prio
 test_listener
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH, mptcp-next 0/9] selftests: mptcp: skip the v6 subtests when CONFIG_MPTCP_IPV6=n
  2026-06-11 17:07 [PATCH, mptcp-next 0/9] selftests: mptcp: skip the v6 subtests when CONFIG_MPTCP_IPV6=n Gang Yan
                   ` (8 preceding siblings ...)
  2026-06-11 17:07 ` [PATCH, mptcp-next 9/9] selftests: mptcp: userspace_pm.sh skips v6 paths " Gang Yan
@ 2026-06-11 18:07 ` MPTCP CI
  9 siblings, 0 replies; 11+ messages in thread
From: MPTCP CI @ 2026-06-11 18:07 UTC (permalink / raw)
  To: Gang Yan; +Cc: mptcp

Hi Gang,

Thank you for your modifications, that's great!

Our CI did some validations and here is its report:

- KVM Validation: normal (except selftest_mptcp_join): Unstable: 11 failed test(s): packetdrill_add_addr packetdrill_dss packetdrill_fastclose packetdrill_fastopen packetdrill_mp_capable packetdrill_mp_join packetdrill_mp_prio packetdrill_mp_reset packetdrill_regressions packetdrill_sockopts packetdrill_syscalls ⚠️ 
- KVM Validation: normal (only selftest_mptcp_join): Success! ✅
- KVM Validation: debug (except selftest_mptcp_join): Success! ✅
- KVM Validation: debug (only selftest_mptcp_join): Success! ✅
- KVM Validation: btf-normal (only bpftest_all): Success! ✅
- KVM Validation: btf-debug (only bpftest_all): Success! ✅
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/27364818369

Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/127e9ba80ff5
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1110208


If there are some issues, you can reproduce them using the same environment as
the one used by the CI thanks to a docker image, e.g.:

    $ cd [kernel source code]
    $ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \
        --pull always mptcp/mptcp-upstream-virtme-docker:latest \
        auto-normal

For more details:

    https://github.com/multipath-tcp/mptcp-upstream-virtme-docker


Please note that despite all the efforts that have been already done to have a
stable tests suite when executed on a public CI like here, it is possible some
reported issues are not due to your modifications. Still, do not hesitate to
help us improve that ;-)

Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (NGI0 Core)

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2026-06-11 18:07 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-11 17:07 [PATCH, mptcp-next 0/9] selftests: mptcp: skip the v6 subtests when CONFIG_MPTCP_IPV6=n Gang Yan
2026-06-11 17:07 ` [PATCH, mptcp-next 1/9] DO-NOT-MERGE: mptcp: test IPV6=m in docker-virtme Gang Yan
2026-06-11 17:07 ` [PATCH, mptcp-next 2/9] selftests: mptcp: mptcp_lib add runtime IPv6 availability detection helper Gang Yan
2026-06-11 17:07 ` [PATCH, mptcp-next 3/9] selftests: mptcp: mptcp_connect.sh degrades to v4-only when MPTCP IPv6 is missing Gang Yan
2026-06-11 17:07 ` [PATCH, mptcp-next 4/9] selftests: mptcp: mptcp_connect.sh don't fail because of nft rules in IPV6-less kernel Gang Yan
2026-06-11 17:07 ` [PATCH, mptcp-next 5/9] selftests: mptcp: mptcp_sockopt.sh skips v6 paths when MPTCP IPv6 is missing Gang Yan
2026-06-11 17:07 ` [PATCH, mptcp-next 6/9] selftests: mptcp: simult_flows.sh skips v6 setup " Gang Yan
2026-06-11 17:07 ` [PATCH, mptcp-next 7/9] selftests: mptcp: mptcp_join.sh: pick v4 bind default " Gang Yan
2026-06-11 17:07 ` [PATCH, mptcp-next 8/9] selftests: mptcp: mptcp_join.sh skips v6 subtests " Gang Yan
2026-06-11 17:07 ` [PATCH, mptcp-next 9/9] selftests: mptcp: userspace_pm.sh skips v6 paths " Gang Yan
2026-06-11 18:07 ` [PATCH, mptcp-next 0/9] selftests: mptcp: skip the v6 subtests when CONFIG_MPTCP_IPV6=n MPTCP CI

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.