This series brings various small improvements to MPTCP and its selftests:
Patch 1 prints an error if there are duplicated subtests names. It is important to have unique (sub)tests names in TAP, because some CI environments drop (sub)tests with duplicated names.
Patch 2 is a preparation for patches 3 and 4, which check the protocol in tcp_sk() and mptcp_sk() with DEBUG_NET, only in code from net/mptcp/. We recently had the case where an MPTCP socket was wrongly treated as a TCP one, and fuzzers and static checkers never spot the issue. This would prevent such issues in the future.
Patches 5 to 7 are some cleanup for the MPTCP selftests. These patches are not supposed to change the behaviour.
Patch 8 sets the poll timeout in diag selftest to the same value as the one used in the other selftests.
Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- Geliang Tang (4): selftests: mptcp: netlink: drop duplicate var ret selftests: mptcp: simult flows: define missing vars selftests: mptcp: join: change capture/checksum as bool selftests: mptcp: diag: change timeout_poll to 30
Matthieu Baerts (NGI0) (4): selftests: mptcp: lib: catch duplicated subtest entries mptcp: token kunit: set protocol mptcp: check the protocol in tcp_sk() with DEBUG_NET mptcp: check the protocol in mptcp_sk() with DEBUG_NET
net/mptcp/protocol.h | 16 ++++++++++++++++ net/mptcp/token_test.c | 7 ++++++- tools/testing/selftests/net/mptcp/diag.sh | 2 +- tools/testing/selftests/net/mptcp/mptcp_join.sh | 22 +++++++++++----------- tools/testing/selftests/net/mptcp/mptcp_lib.sh | 21 +++++++++++++++++++++ tools/testing/selftests/net/mptcp/pm_netlink.sh | 1 - tools/testing/selftests/net/mptcp/simult_flows.sh | 6 ++++++ 7 files changed, 61 insertions(+), 14 deletions(-) --- base-commit: a818bd12538c1408c7480de31573cdb3c3c0926f change-id: 20240223-upstream-net-next-20240223-misc-improvements-7d64a076bca8
Best regards,
It is important to have a unique (sub)test name in TAP, because some CI environments drop tests with duplicated name.
When adding a new subtest entry, an error message is printed in case of duplicated entries. If there were duplicated entries and if all features were expected to work, the script exits with an error at the end, after having printed all subtests in the TAP format. Thanks to that, the MPTCP CI will catch such issues early.
Reviewed-by: Geliang Tang geliang@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- tools/testing/selftests/net/mptcp/mptcp_lib.sh | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_lib.sh b/tools/testing/selftests/net/mptcp/mptcp_lib.sh index 3a2abae5993e..037cb3e84330 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_lib.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_lib.sh @@ -9,6 +9,7 @@ readonly KSFT_SKIP=4 readonly KSFT_TEST="${MPTCP_LIB_KSFT_TEST:-$(basename "${0}" .sh)}"
MPTCP_LIB_SUBTESTS=() +MPTCP_LIB_SUBTESTS_DUPLICATED=0
# only if supported (or forced) and not disabled, see no-color.org if { [ -t 1 ] || [ "${SELFTESTS_MPTCP_LIB_COLOR_FORCE:-}" = "1" ]; } && @@ -146,12 +147,26 @@ mptcp_lib_kversion_ge() { mptcp_lib_fail_if_expected_feature "kernel version ${1} lower than ${v}" }
+__mptcp_lib_result_check_duplicated() { + local subtest + + for subtest in "${MPTCP_LIB_SUBTESTS[@]}"; do + if [[ "${subtest}" == *" - ${KSFT_TEST}: ${*%% #*}" ]]; then + MPTCP_LIB_SUBTESTS_DUPLICATED=1 + mptcp_lib_print_err "Duplicated entry: ${*}" + break + fi + done +} + __mptcp_lib_result_add() { local result="${1}" shift
local id=$((${#MPTCP_LIB_SUBTESTS[@]} + 1))
+ __mptcp_lib_result_check_duplicated "${*}" + MPTCP_LIB_SUBTESTS+=("${result} ${id} - ${KSFT_TEST}: ${*}") }
@@ -206,6 +221,12 @@ mptcp_lib_result_print_all_tap() { for subtest in "${MPTCP_LIB_SUBTESTS[@]}"; do printf "%s\n" "${subtest}" done + + if [ "${MPTCP_LIB_SUBTESTS_DUPLICATED}" = 1 ] && + mptcp_lib_expect_all_features; then + mptcp_lib_print_err "Duplicated test entries" + exit ${KSFT_FAIL} + fi }
# get the value of keyword $1 in the line marked by keyword $2
As it would be done when initiating an MPTCP sock.
This is not strictly needed for this test, but it will be when a later patch will check if the right protocol is being used when calling mptcp_sk().
Reviewed-by: Mat Martineau martineau@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- net/mptcp/token_test.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/net/mptcp/token_test.c b/net/mptcp/token_test.c index bfff53e668da..4fc39fa2e262 100644 --- a/net/mptcp/token_test.c +++ b/net/mptcp/token_test.c @@ -52,14 +52,19 @@ static struct mptcp_subflow_context *build_ctx(struct kunit *test) static struct mptcp_sock *build_msk(struct kunit *test) { struct mptcp_sock *msk; + struct sock *sk;
msk = kunit_kzalloc(test, sizeof(struct mptcp_sock), GFP_USER); KUNIT_EXPECT_NOT_ERR_OR_NULL(test, msk); refcount_set(&((struct sock *)msk)->sk_refcnt, 1); sock_net_set((struct sock *)msk, &init_net);
+ sk = (struct sock *)msk; + /* be sure the token helpers can dereference sk->sk_prot */ - ((struct sock *)msk)->sk_prot = &tcp_prot; + sk->sk_prot = &tcp_prot; + sk->sk_protocol = IPPROTO_MPTCP; + return msk; }
Fuzzers and static checkers might not detect when tcp_sk() is used with a non tcp_sock structure.
This kind of mistake already happened a few times with MPTCP: when wrongly using TCP-specific helpers with mptcp_sock pointers. On the other hand, there are many 'tcp_xxx()' helpers that are taking a 'struct sock' pointer as arguments, and some of them are only looking at fields from 'struct sock', and nothing from 'struct tcp_sock'. It is then tempting to use them with a 'struct mptcp_sock'.
So a new simple check is done when CONFIG_DEBUG_NET is enabled to tell kernel devs when a non-TCP socket is being used as a TCP one. 'tcp_sk()' macro is then re-defined to add a WARN when an unexpected socket is being used.
Reviewed-by: Mat Martineau martineau@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- net/mptcp/protocol.h | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index f89b197a9f92..026ed360bd72 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -348,6 +348,16 @@ static inline void msk_owned_by_me(const struct mptcp_sock *msk) sock_owned_by_me((const struct sock *)msk); }
+#ifdef CONFIG_DEBUG_NET +/* MPTCP-specific: we might (indirectly) call this helper with the wrong sk */ +#undef tcp_sk +#define tcp_sk(ptr) ({ \ + typeof(ptr) _ptr = (ptr); \ + WARN_ON(_ptr->sk_protocol != IPPROTO_TCP); \ + container_of_const(_ptr, struct tcp_sock, inet_conn.icsk_inet.sk); \ +}) +#endif + #define mptcp_sk(ptr) container_of_const(ptr, struct mptcp_sock, sk.icsk_inet.sk)
/* the msk socket don't use the backlog, also account for the bulk
Fuzzers and static checkers might not detect when mptcp_sk() is used with a non mptcp_sock structure.
This is similar to the parent commit, where it is easy to use mptcp_sk() with a TCP sock, e.g. with a subflow sk.
So a new simple check is done when CONFIG_DEBUG_NET is enabled to tell kernel devs when a non-MPTCP socket is being used as an MPTCP one. 'mptcp_sk()' macro is then defined differently: with an extra WARN to complain when an unexpected socket is being used.
Reviewed-by: Mat Martineau martineau@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- net/mptcp/protocol.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 026ed360bd72..051b100d9403 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -356,9 +356,15 @@ static inline void msk_owned_by_me(const struct mptcp_sock *msk) WARN_ON(_ptr->sk_protocol != IPPROTO_TCP); \ container_of_const(_ptr, struct tcp_sock, inet_conn.icsk_inet.sk); \ }) -#endif +#define mptcp_sk(ptr) ({ \ + typeof(ptr) _ptr = (ptr); \ + WARN_ON(_ptr->sk_protocol != IPPROTO_MPTCP); \ + container_of_const(_ptr, struct mptcp_sock, sk.icsk_inet.sk); \ +})
+#else /* !CONFIG_DEBUG_NET */ #define mptcp_sk(ptr) container_of_const(ptr, struct mptcp_sock, sk.icsk_inet.sk) +#endif
/* the msk socket don't use the backlog, also account for the bulk * free memory
From: Geliang Tang tanggeliang@kylinos.cn
The variable 'ret' are defined twice in pm_netlink.sh. This patch drops this duplicate one that has been defined from the beginning, with commit eedbc685321b ("selftests: add PM netlink functional tests")
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- tools/testing/selftests/net/mptcp/pm_netlink.sh | 1 - 1 file changed, 1 deletion(-)
diff --git a/tools/testing/selftests/net/mptcp/pm_netlink.sh b/tools/testing/selftests/net/mptcp/pm_netlink.sh index 71899a3ffa7a..ebfefae71e13 100755 --- a/tools/testing/selftests/net/mptcp/pm_netlink.sh +++ b/tools/testing/selftests/net/mptcp/pm_netlink.sh @@ -28,7 +28,6 @@ sec=$(date +%s) rndh=$(printf %x $sec)-$(mktemp -u XXXXXX) ns1="ns1-$rndh" err=$(mktemp) -ret=0
cleanup() {
From: Geliang Tang tanggeliang@kylinos.cn
The variables 'large', 'small', 'sout', 'cout', 'capout' and 'size' are used in multiple functions, so they should be clearly defined as global variables at the top of the file.
This patch redefines them at the beginning of simult_flows.sh.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- tools/testing/selftests/net/mptcp/simult_flows.sh | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/tools/testing/selftests/net/mptcp/simult_flows.sh b/tools/testing/selftests/net/mptcp/simult_flows.sh index 8f9ddb3ad4fe..ed0165c15a24 100755 --- a/tools/testing/selftests/net/mptcp/simult_flows.sh +++ b/tools/testing/selftests/net/mptcp/simult_flows.sh @@ -16,6 +16,12 @@ test_cnt=1 ret=0 bail=0 slack=50 +large="" +small="" +sout="" +cout="" +capout="" +size=0
usage() { echo "Usage: $0 [ -b ] [ -c ] [ -d ]"
From: Geliang Tang tanggeliang@kylinos.cn
To maintain consistency with other scripts, this patch changes vars 'capture' and 'checksum' as bool vars in mptcp_join.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- tools/testing/selftests/net/mptcp/mptcp_join.sh | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh index c07386e21e0a..3f198743cb03 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_join.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh @@ -29,11 +29,11 @@ iptables="iptables" ip6tables="ip6tables" timeout_poll=30 timeout_test=$((timeout_poll * 2 + 1)) -capture=0 -checksum=0 +capture=false +checksum=false ip_mptcp=0 check_invert=0 -validate_checksum=0 +validate_checksum=false init=0 evts_ns1="" evts_ns2="" @@ -100,7 +100,7 @@ init_partial() ip netns exec $netns sysctl -q net.mptcp.pm_type=0 2>/dev/null || true ip netns exec $netns sysctl -q net.ipv4.conf.all.rp_filter=0 ip netns exec $netns sysctl -q net.ipv4.conf.default.rp_filter=0 - if [ $checksum -eq 1 ]; then + if $checksum; then ip netns exec $netns sysctl -q net.mptcp.checksum_enabled=1 fi done @@ -380,7 +380,7 @@ reset_with_checksum() ip netns exec $ns1 sysctl -q net.mptcp.checksum_enabled=$ns1_enable ip netns exec $ns2 sysctl -q net.mptcp.checksum_enabled=$ns2_enable
- validate_checksum=1 + validate_checksum=true }
reset_with_allow_join_id0() @@ -413,7 +413,7 @@ reset_with_allow_join_id0() setup_fail_rules() { check_invert=1 - validate_checksum=1 + validate_checksum=true local i="$1" local ip="${2:-4}" local tables @@ -1017,7 +1017,7 @@ do_transfer() :> "$sout" :> "$capout"
- if [ $capture -eq 1 ]; then + if $capture; then local capuser if [ -z $SUDO_USER ] ; then capuser="" @@ -1119,7 +1119,7 @@ do_transfer() wait $spid local rets=$?
- if [ $capture -eq 1 ]; then + if $capture; then sleep 1 kill $cappid fi @@ -1507,7 +1507,7 @@ chk_join_nr() else print_ok fi - if [ $validate_checksum -eq 1 ]; then + if $validate_checksum; then chk_csum_nr $csum_ns1 $csum_ns2 chk_fail_nr $fail_nr $fail_nr chk_rst_nr $rst_nr $rst_nr @@ -3664,10 +3664,10 @@ while getopts "${all_tests_args}cCih" opt; do tests+=("${all_tests[${opt}]}") ;; c) - capture=1 + capture=true ;; C) - checksum=1 + checksum=true ;; i) ip_mptcp=1
From: Geliang Tang tanggeliang@kylinos.cn
Even if it is set to 100ms from the beginning with commit df62f2ec3df6 ("selftests/mptcp: add diag interface tests"), there is no reason not to have it to 30ms like all the other tests. "diag.sh" is not supposed to be slower than the other ones.
To maintain consistency with other scripts, this patch changes it to 30.
Signed-off-by: Geliang Tang tanggeliang@kylinos.cn Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org --- tools/testing/selftests/net/mptcp/diag.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/net/mptcp/diag.sh b/tools/testing/selftests/net/mptcp/diag.sh index 0a58ebb8b04c..8573326d326a 100755 --- a/tools/testing/selftests/net/mptcp/diag.sh +++ b/tools/testing/selftests/net/mptcp/diag.sh @@ -8,7 +8,7 @@ rndh=$(printf %x $sec)-$(mktemp -u XXXXXX) ns="ns1-$rndh" ksft_skip=4 test_cnt=1 -timeout_poll=100 +timeout_poll=30 timeout_test=$((timeout_poll * 2 + 1)) ret=0
Hello:
This series was applied to netdev/net-next.git (main) by Jakub Kicinski kuba@kernel.org:
On Fri, 23 Feb 2024 21:17:52 +0100 you wrote:
This series brings various small improvements to MPTCP and its selftests:
Patch 1 prints an error if there are duplicated subtests names. It is important to have unique (sub)tests names in TAP, because some CI environments drop (sub)tests with duplicated names.
[...]
Here is the summary with links: - [net-next,1/8] selftests: mptcp: lib: catch duplicated subtest entries https://git.kernel.org/netdev/net-next/c/9da74836740d - [net-next,2/8] mptcp: token kunit: set protocol https://git.kernel.org/netdev/net-next/c/28de50eeb734 - [net-next,3/8] mptcp: check the protocol in tcp_sk() with DEBUG_NET https://git.kernel.org/netdev/net-next/c/dcc03f270d1e - [net-next,4/8] mptcp: check the protocol in mptcp_sk() with DEBUG_NET https://git.kernel.org/netdev/net-next/c/14d29ec5302c - [net-next,5/8] selftests: mptcp: netlink: drop duplicate var ret https://git.kernel.org/netdev/net-next/c/488ccbe76cb4 - [net-next,6/8] selftests: mptcp: simult flows: define missing vars https://git.kernel.org/netdev/net-next/c/fccf7c922459 - [net-next,7/8] selftests: mptcp: join: change capture/checksum as bool https://git.kernel.org/netdev/net-next/c/8c6f6b4bb53a - [net-next,8/8] selftests: mptcp: diag: change timeout_poll to 30 https://git.kernel.org/netdev/net-next/c/e8ddc5f255c3
You are awesome, thank you!
linux-kselftest-mirror@lists.linaro.org