[PATCH MPTCH-next] selftests: add test for userspace PM address ID overflow
luoqing <[email protected]> Tue, 4 Aug 2026 10:23:50 +0800
| Newsgroups | dev.linux.lists.mptcp |
|---|---|
| Message-ID | <[email protected]> |
From: Qing Luo <[email protected]> Add a test that verifies the userspace PM correctly returns an error when all address IDs (1-255) are exhausted, instead of overflowing. The test first announces 255 unique addresses (IDs 1-255) to fill the ID bitmap. It then attempts to create a subflow (CSF) without specifying a local ID, which triggers auto-allocation via mptcp_userspace_pm_get_local_id(). With all IDs in use, the allocation should fail with -ENOSPC. Also modify pm_nl_ctl to make the 'lid' parameter optional for the CSF command. When omitted, the kernel auto-allocates a local ID. MPTCP_PM_MAX_ADDR_ID has been 255 since the userspace PM was introduced, so no version-dependent limit adjustment is needed (unlike pm_netlink.sh). Assisted-by: LLM # code Signed-off-by: Qing Luo <[email protected]> --- tools/testing/selftests/net/mptcp/pm_nl_ctl.c | 8 +-- .../selftests/net/mptcp/userspace_pm.sh | 63 +++++++++++++++++++ 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c index 78180da1efcc..a9dd650805a9 100644 --- a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c +++ b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c @@ -32,7 +32,7 @@ static void syntax(char *argv[]) fprintf(stderr, "\tadd [flags signal|subflow|backup|fullmesh] [id <nr>] [dev <name>] <ip>\n"); fprintf(stderr, "\tann <local-ip> id <local-id> token <token> [port <local-port>] [dev <name>]\n"); fprintf(stderr, "\trem id <local-id> token <token>\n"); - fprintf(stderr, "\tcsf lip <local-ip> lid <local-id> rip <remote-ip> rport <remote-port> token <token>\n"); + fprintf(stderr, "\tcsf lip <local-ip> [lid <local-id>] rip <remote-ip> rport <remote-port> token <token>\n"); fprintf(stderr, "\tdsf lip <local-ip> lport <local-port> rip <remote-ip> rport <remote-port> token <token>\n"); fprintf(stderr, "\tdel <id> [<ip>]\n"); fprintf(stderr, "\tget <id>\n"); @@ -481,7 +481,7 @@ int csf(int fd, int pm_family, int argc, char *argv[]) off = init_genl_req(data, pm_family, MPTCP_PM_CMD_SUBFLOW_CREATE, MPTCP_PM_VER); - if (argc < 12) + if (argc < 10) syntax(argv); /* Params recorded in this order: @@ -557,9 +557,9 @@ int csf(int fd, int pm_family, int argc, char *argv[]) off += NLMSG_ALIGN(rta->rta_len); } - if (arg == 0) { + if (arg == 0 && params[1]) { /* id */ - id = atoi(params[arg + 1]); + id = atoi(params[1]); rta = (void *)(data + off); rta->rta_type = MPTCP_PM_ADDR_ATTR_ID; rta->rta_len = RTA_LENGTH(1); diff --git a/tools/testing/selftests/net/mptcp/userspace_pm.sh b/tools/testing/selftests/net/mptcp/userspace_pm.sh index 30a809752d1b..45b040a8c0e5 100755 --- a/tools/testing/selftests/net/mptcp/userspace_pm.sh +++ b/tools/testing/selftests/net/mptcp/userspace_pm.sh @@ -847,6 +847,68 @@ test_subflows_v4_v6_mix() sleep 0.5 } +test_addr_id_overflow() +{ + print_title "Address ID overflow tests" + + local i announced=0 + + :>"$server_evts" + + # Clear leftover addresses from previous tests + for i in $(seq 0 255); do + ip netns exec "$ns2" ./pm_nl_ctl rem token "$client4_token" id "$i" > /dev/null 2>&1 + done + + # Announce 255 addresses (IDs 1-255) to exhaust all available IDs + for i in $(seq 1 255); do + if ip netns exec "$ns2" ./pm_nl_ctl ann 10.0.3."${i}" token "$client4_token" id \ + "$i" dev ns2eth1 > /dev/null 2>&1; then + announced=$((announced + 1)) + fi + done + + print_test "ADD_ADDR with all IDs 1-255 exhausted" + sleep 1 + if [ -s "$server_evts" ]; then + test_pass + else + test_fail "No events generated" + return + fi + + # Start listener to ensure subflow creation doesn't fail on connectivity + ip netns exec "$ns1" ./pm_nl_ctl listen 10.0.1.1 "$app4_port" >/dev/null 2>&1 & + local listener_pid=$! + sleep 0.5 + + # Try to create a subflow without specifying a local ID. + # With all IDs exhausted, this should fail with -ENOSPC. + print_test "CSF without local ID after all IDs exhausted - expect failure" + local out + if out=$(ip netns exec "$ns2" ./pm_nl_ctl csf lip 10.0.1.2 \ + rip 10.0.1.1 rport "$app4_port" token "$client4_token" 2>&1); then + test_fail "Expected failure but CSF succeeded" + else + # pm_nl_ctl prints the kernel error as "netlink error -28 (No space + # left on device)" for -ENOSPC. Match either form. + if echo "$out" | grep -qE "netlink error -?28|No space left on device"; then + test_pass + else + test_fail "CSF failed, but not with the expected ENOSPC: ${out}" + fi + fi + + # Delete the listener from the server ns, if one was created + mptcp_lib_kill_wait $listener_pid + + # Cleanup: remove all announced addresses + for i in $(seq 1 255); do + ip netns exec "$ns2" ./pm_nl_ctl rem token "$client4_token" id "$i" > /dev/null 2>&1 + done + sleep 1 +} + test_prio() { print_title "Prio tests" @@ -940,6 +1002,7 @@ test_subflows test_subflows_v4_v6_mix test_prio test_listener +test_addr_id_overflow mptcp_lib_result_print_all_tap exit ${ret} -- 2.25.1