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 | 257 ++++++++++--------
1 file changed, 151 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..c0d68a1620b0 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,18 @@ 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"
+ else
+ print_test "ADD_ADDR6 id:client dead:beef:2::2 (ns2) => ns1, reuse port"
+ test_skip
+ fi
# ADD_ADDR from the client to server machine using a new port
:>"$server_evts"
@@ -374,13 +384,18 @@ 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"
+ else
+ print_test "ADD_ADDR6 id:server dead:beef:2::1 (ns1) => ns2, reuse port"
+ test_skip
+ fi
# ADD_ADDR from the server to client machine using a new port
:>"$client_evts"
@@ -462,12 +477,17 @@ 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"
+ else
+ print_test "RM_ADDR6 id:client-1 ns2 => ns1"
+ test_skip
+ fi
# Capture events on the network namespace running the client
:>"$client_evts"
@@ -489,12 +509,17 @@ 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"
+ else
+ print_test "RM_ADDR6 id:server-1 ns1 => ns2"
+ test_skip
+ fi
}
verify_subflow_events()
@@ -609,43 +634,48 @@ 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
+ else
+ print_test "subflow v6 client to server"
+ test_skip
+ 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 +754,48 @@ 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
+ else
+ print_test "subflow v6 server to client"
+ test_skip
+ 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 +966,23 @@ test_listener()
print_title "Make connections"
make_connection
-make_connection "v6"
+if mptcp_lib_is_v6_enabled; then
+ make_connection "v6"
+else
+ print_test "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
+else
+ print_test "subflows v4 v6 mix"
+ test_skip
+fi
test_prio
test_listener
--
2.43.0
On 17/06/2026 16:46, Gang Yan wrote: > 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 | 257 ++++++++++-------- That's also a lot, making the code hard to read. Maybe the verify_* functions could do the skip when v6 is required? Cheers, Matt -- Sponsored by the NGI0 Core fund.
© 2016 - 2026 Red Hat, Inc.