:p
atchew
Login
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
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 XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/config +++ b/tools/testing/selftests/net/mptcp/config @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ CONFIG_NFT_SOCKET=m CONFIG_NFT_TPROXY=m CONFIG_SYN_COOKIES=y CONFIG_VETH=y + +CONFIG_NF_TABLES_IPV4=y -- 2.43.0
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 XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_lib.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_lib.sh @@ -XXX,XX +XXX,XX @@ 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" ]; } && @@ -XXX,XX +XXX,XX @@ 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}" @@ -XXX,XX +XXX,XX @@ 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
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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_connect.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_connect.sh @@ -XXX,XX +XXX,XX @@ 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) @@ -XXX,XX +XXX,XX @@ 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
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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_connect.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_connect.sh @@ -XXX,XX +XXX,XX @@ 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
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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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() @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ cleanup() mptcp_lib_check_mptcp mptcp_lib_check_kallsyms mptcp_lib_check_tools ip "${iptables}" "${ip6tables}" +mptcp_lib_check_ipv6 check_mark() { @@ -XXX,XX +XXX,XX @@ 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() @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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
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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/simult_flows.sh +++ b/tools/testing/selftests/net/mptcp/simult_flows.sh @@ -XXX,XX +XXX,XX @@ cleanup() mptcp_lib_check_mptcp mptcp_lib_check_tools ip tc +mptcp_lib_check_ipv6 # "$ns1" ns2 ns3 # ns1eth1 ns2eth1 ns2eth3 ns3eth1 @@ -XXX,XX +XXX,XX @@ 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
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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_join.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh @@ -XXX,XX +XXX,XX @@ 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
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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_join.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh @@ -XXX,XX +XXX,XX @@ 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 } @@ -XXX,XX +XXX,XX @@ 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) @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 \ @@ -XXX,XX +XXX,XX @@ 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 \ @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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)" @@ -XXX,XX +XXX,XX @@ 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)" @@ -XXX,XX +XXX,XX @@ 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
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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/userspace_pm.sh +++ b/tools/testing/selftests/net/mptcp/userspace_pm.sh @@ -XXX,XX +XXX,XX @@ 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} @@ -XXX,XX +XXX,XX @@ 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) @@ -XXX,XX +XXX,XX @@ 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" @@ -XXX,XX +XXX,XX @@ 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" @@ -XXX,XX +XXX,XX @@ 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" @@ -XXX,XX +XXX,XX @@ 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() @@ -XXX,XX +XXX,XX @@ 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\ @@ -XXX,XX +XXX,XX @@ 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\ @@ -XXX,XX +XXX,XX @@ 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
From: Gang Yan <yangang@kylinos.cn> This series is for make the selftest useful in the kernel which IPV6 is compiled as a module. With this series applied, the output with CONFIG_IPV6=m will be like: mptcp_connect.sh: ''' Selftest Test: ./mptcp_connect.sh TAP version 13 1..1 # [SKIP] MPTCP IPv6 support is not available # INFO: MPTCP IPv6 not available, running IPv4-only tests # INFO: set ns3-Ij7oet dev ns3eth2: ethtool -K gro off # INFO: set ns4-MNMck3 dev ns4eth3: ethtool -K tso off gso off # Created /tmp/tmp.MPGwnjy7S8 (size 7478906 B) containing data sent by client # Created /tmp/tmp.xLzF6OOxGG (size 1934300 B) containing data sent by server # 01 New MPTCP socket can be blocked via sysctl [ OK ] ... # 31 ns2 MPTCP -> ns1 (10.0.1.1:10028 ) MPTCP (duration 141ms) [ OK ] # INFO: with MPTFO end # /dev/stdin:2:1-2: Error: Could not process rule: Operation not supported # table inet mangle { # ^^ # /dev/stdin:2:12-17: Error: Could not process rule: No such file or directory # table inet mangle { # ^^^^^^ # /dev/stdin:2:12-17: Error: Could not process rule: No such file or directory # table inet mangle { # ^^^^^^ # /dev/stdin:2:12-17: Error: Could not process rule: No such file or directory # table inet mangle { # ^^^^^^ # [SKIP] tproxy ipv4, could not load nft ruleset # INFO: nft inet table needs CONFIG_IPV6=y # INFO: disconnect # 32 ns1 MPTCP -> ns1 (10.0.1.1:10029 ) MPTCP (duration 276ms) [ OK ] # 33 ns1 MPTCP -> ns1 (10.0.1.1:10030 ) TCP (duration 232ms) [ OK ] # 34 ns1 TCP -> ns1 (10.0.1.1:10031 ) MPTCP (duration 223ms) [ OK ] # Time: 55 seconds ok 1 test: selftest_mptcp_connect ''' mptcp_sockopt.sh: ''' Selftest Test: ./mptcp_sockopt.sh TAP version 13 1..1 # [SKIP] MPTCP IPv6 support is not available # Created /tmp/tmp.xrhCxOCqCb (size 1 KB) containing data sent by client # Created /tmp/tmp.u2QBzkEsfF (size 1 KB) containing data sent by server # 01 Transfer v4 [ OK ] # 02 Mark v4 [ OK ] # 03 Transfer v6 [SKIP] MPTCP IPv6 not available # 04 Mark v6 [SKIP] MPTCP IPv6 not available # 05 SOL_MPTCP sockopt v4 [ OK ] # 06 SOL_MPTCP sockopt v6 [SKIP] MPTCP IPv6 not available # 07 TCP_INQ cmsg/ioctl -t tcp [ OK ] # 08 TCP_INQ cmsg/ioctl -6 -t tcp [SKIP] MPTCP IPv6 not available # 09 TCP_INQ cmsg/ioctl -r tcp [ OK ] # 10 TCP_INQ cmsg/ioctl -6 -r tcp [SKIP] MPTCP IPv6 not available # 11 TCP_INQ cmsg/ioctl -r tcp -t tcp [ OK ] ok 1 test: selftest_mptcp_sockopt # time=17 ''' simult_subflow.sh: ''' Selftest Test: ./simult_flows.sh TAP version 13 1..1 # [SKIP] MPTCP IPv6 support is not available # 01 balanced bwidth 7383 max 7906 [ OK ] # 02 balanced bwidth - reverse direction 7380 max 7906 [ OK ] # 03 balanced bwidth with unbalanced delay 7493 max 7906 [ OK ] # 04 balanced bwidth with unbalanced delay - reverse direction 7442 max 7906 [ OK ] # 05 unbalanced bwidth 11426 max 11921 [ OK ] # 06 unbalanced bwidth - reverse direction 11391 max 11921 [ OK ] # 07 unbalanced bwidth with unbalanced delay 11424 max 11921 [ OK ] # 08 unbalanced bwidth with unbalanced delay - reverse direction 11573 max 11921 [ OK ] # 09 unbalanced bwidth with opposed, unbalanced delay 11584 max 11921 [ OK ] # 10 unbalanced bwidth with opposed, unbalanced delay - reverse direction11559 max 11921 [ OK ] ok 1 test: selftest_simult_flows # time=105 ''' ./mptcp_join.sh: ''' Selftest Test: ./mptcp_join.sh TAP version 13 1..1 # [SKIP] MPTCP IPv6 support is not available # 001 no JOIN # join Rx [ OK ] # join Tx [ OK ] ... # 022 with multiple laminar endpoints # MPTCP IPv6 support is not available [SKIP] ... ''' userspace_pm.sh: ''' Selftest Test: ./userspace_pm.sh TAP version 13 1..1 # [SKIP] MPTCP IPv6 support is not available # INFO: Init # 01 Created network namespaces ns1, ns2 [ OK ] # INFO: Make connections # INFO: Connection info: 10.0.1.2:47434 -> 10.0.1.1:50002 # 03 Established IPv6 MPTCP Connection ns2 => ns1 [SKIP] # INFO: Will be using address IDs 27 (client) and 31 (server) # INFO: Announce tests ... # 32 CREATE_LISTENER 10.0.2.2 (client port) [ OK ] # 33 CLOSE_LISTENER 10.0.2.2 (client port) [ OK ] # INFO: Cleanup # INFO: Done ok 1 test: selftest_userspace_pm # time=23 ''' --- Changelog: v2: - Patch2 uses " mptcpv6_init(\.|$)" to replace " mptcpv6_init$", and trims some code comments and commit message. - Patch5 refactors IPv6 guards in mptcp_sockopt.sh, unifies skip logic, removes redundant wrappers and duplicated title prints, and adds an early v6 check for TCP_INQ tests. - Patch6 removes 2 lines of redundant inline comment. - Patch8 adds 'skip_if' helper, and rewrites all 29 IPv6 subtest guards in mptcp_join.sh to fix TAP log misordering and updates its commit message with accurate test group info. - Patch9 adds missing skip branches for seven IPv6 code paths in userspace_pm.sh to generate proper TAP skip entries. v1: Link: https://patchwork.kernel.org/project/mptcp/cover/cover.1781196828.git.yangang@kylinos.cn/ 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 | 111 ++++++-- .../testing/selftests/net/mptcp/mptcp_lib.sh | 23 ++ .../selftests/net/mptcp/mptcp_sockopt.sh | 94 +++++-- .../selftests/net/mptcp/simult_flows.sh | 28 +- .../selftests/net/mptcp/userspace_pm.sh | 257 ++++++++++-------- 7 files changed, 391 insertions(+), 175 deletions(-) -- 2.43.0
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 XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/config +++ b/tools/testing/selftests/net/mptcp/config @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ CONFIG_NFT_SOCKET=m CONFIG_NFT_TPROXY=m CONFIG_SYN_COOKIES=y CONFIG_VETH=y + +CONFIG_NF_TABLES_IPV4=y -- 2.43.0
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. - 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 | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tools/testing/selftests/net/mptcp/mptcp_lib.sh b/tools/testing/selftests/net/mptcp/mptcp_lib.sh index XXXXXXX..XXXXXXX 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_lib.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_lib.sh @@ -XXX,XX +XXX,XX @@ 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" ]; } && @@ -XXX,XX +XXX,XX @@ mptcp_lib_check_kallsyms() { fi } +# Detect whether the MPTCP IPv6 subsystem is available in the running kernel. +mptcp_lib_check_ipv6() { + if ! mptcp_lib_has_file "/proc/kallsyms"; then + MPTCP_LIB_IPV6_AVAILABLE=0 + return 1 + fi + + if ! grep -qE " 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}" @@ -XXX,XX +XXX,XX @@ mptcp_lib_is_v6() { [ -z "${1##*:*}" ] } +# Returns 0 (true) if the kernel has MPTCP IPv6 support, 1 (false) otherwise. +mptcp_lib_is_v6_enabled() { + [ "${MPTCP_LIB_IPV6_AVAILABLE}" = "1" ] +} + mptcp_lib_nstat_init() { local ns="${1}" -- 2.43.0
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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_connect.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_connect.sh @@ -XXX,XX +XXX,XX @@ 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) @@ -XXX,XX +XXX,XX @@ 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
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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_connect.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_connect.sh @@ -XXX,XX +XXX,XX @@ 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
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 | 94 +++++++++++++++---- 1 file changed, 75 insertions(+), 19 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh index XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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() @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ cleanup() mptcp_lib_check_mptcp mptcp_lib_check_kallsyms mptcp_lib_check_tools ip "${iptables}" "${ip6tables}" +mptcp_lib_check_ipv6 check_mark() { @@ -XXX,XX +XXX,XX @@ do_transfer() ip=ipv4 fi + # Skip v6 subtests when the running kernel has no MPTCP IPv6 support. + # Reuses the same ${ip}/${ip:2} naming as the normal path below so the + # console counter (MPTCP_LIB_TEST_COUNTER, bumped by print_title) and + # the TAP index (bumped by mptcp_lib_result_skip) stay in lock-step. + if [ "${ip}" = "ipv6" ] && ! mptcp_lib_is_v6_enabled; then + print_title "Transfer ${ip:2}" + mptcp_lib_pr_skip "MPTCP IPv6 not available" + mptcp_lib_result_skip "transfer ${ip}" + print_title "Mark ${ip:2}" + mptcp_lib_pr_skip "MPTCP IPv6 not available" + mptcp_lib_result_skip "mark ${ip}" + return 0 + fi + cmsg="TIMESTAMPNS" if mptcp_lib_kallsyms_has "mptcp_ioctl$"; then cmsg+=",TCPINQ" @@ -XXX,XX +XXX,XX @@ do_mptcp_sockopt_tests() mptcp_lib_pr_ok mptcp_lib_result_pass "sockopt v4" - 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 + if ! mptcp_lib_is_v6_enabled; then + mptcp_lib_pr_skip "MPTCP IPv6 not available" + mptcp_lib_result_skip "sockopt v6" + else + ip netns exec "$ns_sbox" ./mptcp_sockopt -6 + lret=$? + + 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() @@ -XXX,XX +XXX,XX @@ run_tests() do_tcpinq_test() { print_title "TCP_INQ cmsg/ioctl $*" + + if [ "${1}" = "-6" ] && ! mptcp_lib_is_v6_enabled; then + mptcp_lib_pr_skip "MPTCP IPv6 not available" + mptcp_lib_result_skip "TCP_INQ: $*" + return 0 + fi + ip netns exec "$ns_sbox" ./mptcp_inq "$@" local lret=$? if [ $lret -ne 0 ];then @@ -XXX,XX +XXX,XX @@ 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 -- 2.43.0
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 | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/simult_flows.sh b/tools/testing/selftests/net/mptcp/simult_flows.sh index XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/simult_flows.sh +++ b/tools/testing/selftests/net/mptcp/simult_flows.sh @@ -XXX,XX +XXX,XX @@ cleanup() mptcp_lib_check_mptcp mptcp_lib_check_tools ip tc +mptcp_lib_check_ipv6 # "$ns1" ns2 ns3 # ns1eth1 ns2eth1 ns2eth3 ns3eth1 @@ -XXX,XX +XXX,XX @@ 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). + 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
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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_join.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh @@ -XXX,XX +XXX,XX @@ 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
From: Gang Yan <yangang@kylinos.cn> mptcp_join.sh configures dedicated dead:beef:*::1/2 IPv6 addresses and IPv6 default routes inside init_partial(). A large number of subtest groups rely on IPv6 or IPv4-mapped IPv6 endpoints: ipv6_tests, v4mapped_tests, mixed_tests, add_addr_timeout_tests, laminar_endp_tests, plus one v4-mapped case in userspace_tests. All these IPv6-related routines fail on kernels built with CONFIG_IPV6=m, which implicitly disables CONFIG_MPTCP_IPV6. This patch adds a helper named 'skip_if' which doesn't call mptcp_lib_fail_if_expected_feature, and can be used for guarding the v6 subtests in userspace_tests. Assisted-by: GLM:5.1 Z.ai Signed-off-by: Gang Yan <yangang@kylinos.cn> --- .../testing/selftests/net/mptcp/mptcp_join.sh | 102 +++++++++++++----- 1 file changed, 78 insertions(+), 24 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh index XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_join.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh @@ -XXX,XX +XXX,XX @@ 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 } @@ -XXX,XX +XXX,XX @@ continue_if() fi } +# $@: condition +# Like continue_if(), but the skip is unconditional: it never calls +# mptcp_lib_fail_if_expected_feature(). +skip_if() +{ + if ! "${@}"; then + print_check "MPTCP IPv6 support is not available" + print_skip + last_test_skipped=1 + return 1 + fi +} + skip_test() { if [ "${#only_tests_ids[@]}" -eq 0 ] && [ "${#only_tests_names[@]}" -eq 0 ]; then @@ -XXX,XX +XXX,XX @@ reset_with_add_addr_timeout() tables="${iptables}" if [ $ip -eq 6 ]; then + if ! mptcp_lib_is_v6_enabled; then + return 0 + fi tables="${ip6tables}" fi @@ -XXX,XX +XXX,XX @@ laminar_endp_tests() # laminar endpoints: these endpoints are used if reset_with_tcp_filter "with multiple laminar endpoints" ns1 10.0.2.2 REJECT && + skip_if mptcp_lib_is_v6_enabled && 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 @@ -XXX,XX +XXX,XX @@ add_addr_timeout_tests() fi # add_addr timeout IPv6 - if reset_with_add_addr_timeout "signal address, ADD_ADDR6 timeout" 6; then + if reset_with_add_addr_timeout "signal address, ADD_ADDR6 timeout" 6 && + skip_if mptcp_lib_is_v6_enabled; 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 @@ -XXX,XX +XXX,XX @@ add_tests() fi # add multiple subflows IPv6 - if reset "add multiple subflows IPv6"; then + if reset "add multiple subflows IPv6" && + skip_if mptcp_lib_is_v6_enabled; then pm_nl_set_limits $ns1 0 2 pm_nl_set_limits $ns2 0 2 addr_nr_ns2=2 speed=slow cestab_ns2=1 \ @@ -XXX,XX +XXX,XX @@ add_tests() fi # add multiple addresses IPv6 - if reset "add multiple addresses IPv6"; then + if reset "add multiple addresses IPv6" && + skip_if mptcp_lib_is_v6_enabled; then pm_nl_set_limits $ns1 0 2 pm_nl_set_limits $ns2 2 2 addr_nr_ns1=2 speed=slow cestab_ns1=1 \ @@ -XXX,XX +XXX,XX @@ add_tests() ipv6_tests() { # subflow IPv6 - if reset "single subflow IPv6"; then + if reset "single subflow IPv6" && + skip_if mptcp_lib_is_v6_enabled; 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 @@ -XXX,XX +XXX,XX @@ ipv6_tests() fi # add_address, unused IPv6 - if reset "unused signal address IPv6"; then + if reset "unused signal address IPv6" && + skip_if mptcp_lib_is_v6_enabled; then pm_nl_add_endpoint $ns1 dead:beef:2::1 flags signal speed=slow \ run_tests $ns1 $ns2 dead:beef:1::1 @@ -XXX,XX +XXX,XX @@ ipv6_tests() fi # signal address IPv6 - if reset "single address IPv6"; then + if reset "single address IPv6" && + skip_if mptcp_lib_is_v6_enabled; 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 @@ -XXX,XX +XXX,XX @@ ipv6_tests() fi # single address IPv6, remove - if reset "remove single address IPv6"; then + if reset "remove single address IPv6" && + skip_if mptcp_lib_is_v6_enabled; 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 @@ -XXX,XX +XXX,XX @@ ipv6_tests() fi # subflow and signal IPv6, remove - if reset "remove subflow and signal IPv6"; then + if reset "remove subflow and signal IPv6" && + skip_if mptcp_lib_is_v6_enabled; 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 @@ -XXX,XX +XXX,XX @@ ipv6_tests() v4mapped_tests() { # subflow IPv4-mapped to IPv4-mapped - if reset "single subflow IPv4-mapped"; then + if reset "single subflow IPv4-mapped" && + skip_if mptcp_lib_is_v6_enabled; 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 @@ -XXX,XX +XXX,XX @@ v4mapped_tests() fi # signal address IPv4-mapped with IPv4-mapped sk - if reset "signal address IPv4-mapped"; then + if reset "signal address IPv4-mapped" && + skip_if mptcp_lib_is_v6_enabled; 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 @@ -XXX,XX +XXX,XX @@ v4mapped_tests() fi # subflow v4-map-v6 - if reset "single subflow v4-map-v6"; then + if reset "single subflow v4-map-v6" && + skip_if mptcp_lib_is_v6_enabled; 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 @@ -XXX,XX +XXX,XX @@ v4mapped_tests() fi # signal address v4-map-v6 - if reset "signal address v4-map-v6"; then + if reset "signal address v4-map-v6" && + skip_if mptcp_lib_is_v6_enabled; 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 @@ -XXX,XX +XXX,XX @@ v4mapped_tests() fi # subflow v6-map-v4 - if reset "single subflow v6-map-v4"; then + if reset "single subflow v6-map-v4" && + skip_if mptcp_lib_is_v6_enabled; 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 @@ -XXX,XX +XXX,XX @@ v4mapped_tests() fi # signal address v6-map-v4 - if reset "signal address v6-map-v4"; then + if reset "signal address v6-map-v4" && + skip_if mptcp_lib_is_v6_enabled; 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 @@ -XXX,XX +XXX,XX @@ v4mapped_tests() fi # no subflow IPv6 to v4 address - if reset "no JOIN with diff families v4-v6"; then + if reset "no JOIN with diff families v4-v6" && + skip_if mptcp_lib_is_v6_enabled; 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 @@ -XXX,XX +XXX,XX @@ 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 reset "no JOIN with diff families v4-v6-2" && + skip_if mptcp_lib_is_v6_enabled; 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 @@ -XXX,XX +XXX,XX @@ 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 reset "no JOIN with diff families v6-v4" && + skip_if mptcp_lib_is_v6_enabled; 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 @@ -XXX,XX +XXX,XX @@ v4mapped_tests() mixed_tests() { if reset "IPv4 sockets do not use IPv6 addresses" && + skip_if mptcp_lib_is_v6_enabled && continue_if mptcp_lib_kversion_ge 6.3; then pm_nl_set_limits $ns1 0 1 pm_nl_set_limits $ns2 1 1 @@ -XXX,XX +XXX,XX @@ mixed_tests() # Need an IPv6 mptcp socket to allow subflows of both families if reset "simult IPv4 and IPv6 subflows" && + skip_if mptcp_lib_is_v6_enabled && continue_if mptcp_lib_kversion_ge 6.3; then pm_nl_set_limits $ns1 0 1 pm_nl_set_limits $ns2 1 1 @@ -XXX,XX +XXX,XX @@ mixed_tests() # cross families subflows will not be created even in fullmesh mode if reset "simult IPv4 and IPv6 subflows, fullmesh 1x1" && + skip_if mptcp_lib_is_v6_enabled && continue_if mptcp_lib_kversion_ge 6.3; then pm_nl_set_limits $ns1 0 4 pm_nl_set_limits $ns2 1 4 @@ -XXX,XX +XXX,XX @@ mixed_tests() # fullmesh still tries to create all the possibly subflows with # matching family if reset "simult IPv4 and IPv6 subflows, fullmesh 2x2" && + skip_if mptcp_lib_is_v6_enabled && continue_if mptcp_lib_kversion_ge 6.3; then pm_nl_set_limits $ns1 0 4 pm_nl_set_limits $ns2 2 4 @@ -XXX,XX +XXX,XX @@ add_addr_ports_tests() # signal address v6 with port if reset "signal address v6 with port" && + skip_if mptcp_lib_is_v6_enabled && 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 @@ -XXX,XX +XXX,XX @@ add_addr_ports_tests() fi # first signal address drops, second one still progresses - if reset "signal addr list progresses after tx drop"; then + if reset "signal addr list progresses after tx drop" && + skip_if mptcp_lib_is_v6_enabled; 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 @@ -XXX,XX +XXX,XX @@ 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 reset "bind main address v6, no join v6" && + skip_if mptcp_lib_is_v6_enabled; 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 @@ -XXX,XX +XXX,XX @@ bind_tests() fi # multiple binds to allow extra subflows to other addresses - if reset "multiple bind to allow joins v6"; then + if reset "multiple bind to allow joins v6" && + skip_if mptcp_lib_is_v6_enabled; then local extra_bind pm_nl_set_limits $ns1 0 2 @@ -XXX,XX +XXX,XX @@ 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 reset "multiple bind to allow joins v6 link-local routing" && + skip_if mptcp_lib_is_v6_enabled; then local extra_bind ns1ll1 ns1ll2 ns1ll1="$(get_ll_addr $ns1 ns1eth1)" @@ -XXX,XX +XXX,XX @@ bind_tests() # multiple binds to allow extra subflows to v6 LL addresses: laminar if reset "multiple bind to allow joins v6 link-local laminar" && + skip_if mptcp_lib_is_v6_enabled && continue_if mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then local extra_bind ns1ll1 ns1ll2 ns2ll2 @@ -XXX,XX +XXX,XX @@ userspace_tests() fi # 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 reset_with_events "userspace pm add & remove address" && + skip_if mptcp_lib_is_v6_enabled && continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then set_userspace_pm $ns1 pm_nl_set_limits $ns2 2 2 @@ -XXX,XX +XXX,XX @@ if [ ${#tests[@]} -eq 0 ]; then tests=("${all_tests_names[@]}") fi +mptcp_lib_check_ipv6 mptcp_lib_subtests_last_ts_reset for subtests in "${tests[@]}"; do "${subtests}" -- 2.43.0
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 XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/userspace_pm.sh +++ b/tools/testing/selftests/net/mptcp/userspace_pm.sh @@ -XXX,XX +XXX,XX @@ 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} @@ -XXX,XX +XXX,XX @@ 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) @@ -XXX,XX +XXX,XX @@ 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" @@ -XXX,XX +XXX,XX @@ 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" @@ -XXX,XX +XXX,XX @@ 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" @@ -XXX,XX +XXX,XX @@ 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() @@ -XXX,XX +XXX,XX @@ 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\ @@ -XXX,XX +XXX,XX @@ 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\ @@ -XXX,XX +XXX,XX @@ 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