From nobody Sat Sep 26 12:30:56 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3F77A495038 for ; Fri, 11 Sep 2026 15:42:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789141334; cv=none; b=QT+qa9k1Vr1WhXXeRmr1Y05eh+CxXV4G6c5YTYIDmesa/Qc9JVD4mjdVU8P9KcC0JTEejaDeYkuiLyMz8l/m5B/i+xo8hY0WdmvGuo5vKwtmi5m0+rAuuAwDGljI6vFQbVnTPzFf6mK88UmvqEgB51SY41qvPT6SrTiZvcamZ2w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789141334; c=relaxed/simple; bh=fh9NokvorsBhx6QCgeFU/GgkO1N4tGQ4pTKXIttbTOU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qu8Ut7xo7n8iw3tWh964lrRn70wYWqbYUwoHIwcjwkgnEmnUxG8LZmc7lOpA46LCoBFiQm3/OZUjWVa2eZaI5SJerYGOvNEPNFvphPI8XMx3kV9bS/ERElfDjC7m9DpBb8dKw21WLqDoX1cqz+C7A5RwveEeV/1teVuBCZgf+Qk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tQUc0VKQ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="tQUc0VKQ" Received: by smtp.kernel.org (Postfix) with ESMTPS id DB46FC2BCF5 for ; Fri, 11 Sep 2026 15:42:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789141333; bh=fh9NokvorsBhx6QCgeFU/GgkO1N4tGQ4pTKXIttbTOU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=tQUc0VKQxU+zxaQCX3kGDvz/w7sBjfda0lSh4Q0ZBgIO2X2anfavNZ8Fa8zJfrhT+ GzShG0feoWI/jw2in22lxspKlDWQNY9nXfvHt6WgSQSoCBy7ReVEefiLS4ZYn7amZP rtK31Jf/VyuxGQo8napDPp/k4HdUZ63XwF0ptUgqfhY2/HwNNUHaYlyh4unJUZJunK tfYGAQHr+XHhD/yzq7ASuaZH6R9w37qWN+hCECsn8geV0jwnENsaYYkYkcnBuy+FcF jqrIpPF8NYWJDylGrp5y82TkK5aYJHCcDbnVLjG52+Q+w5lJhfawsx8QfSKJvPV09X JQ63Dd2bmmhoA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id B9089C88E45 for ; Fri, 11 Sep 2026 15:42:13 +0000 (UTC) From: Quanye Yang via B4 Relay Date: Fri, 11 Sep 2026 23:42:07 +0800 Subject: [PATCH mptcp-net v2 1/2] mptcp: reset msk state on early connect failure Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260911-mptcp-connect-undo-net-v2-1-54224cea2238@proton.me> References: <20260911-mptcp-connect-undo-net-v2-0-54224cea2238@proton.me> In-Reply-To: <20260911-mptcp-connect-undo-net-v2-0-54224cea2238@proton.me> To: mptcp@lists.linux.dev Cc: X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1789141332; l=1608; i=quanyeyang@proton.me; s=20260801; h=from:subject:message-id; bh=Gb88AGXvEtF1PuBgJ2BG7vao+UDAMuDxJ22yWrqoiy4=; b=zeaCexkhDYeOzuZvUNipNnmSRiTtnq2sR3HltMgMaq1XoBpP/uDkO22WPbVHJ9NTktUtm6+03 69BzlIMHj9ZDmFdgYRLX5ZP/Uw+YLIgfE2Nu66FKcD1lpwkTdQYNoRY X-Developer-Key: i=quanyeyang@proton.me; a=ed25519; pk=9L9FrcvzMgxPaBRU6XV0EnqTgjDqVO596rQKSZ9qZoY= X-Endpoint-Received: by B4 Relay for quanyeyang@proton.me/20260801 with auth_id=963 X-Original-From: Quanye Yang Reply-To: quanyeyang@proton.me From: Quanye Yang mptcp_connect() can fall back before the subflow SYN is sent, for example when the netns is in an MPTCP blackhole, token allocation fails, or MD5SIG is in use. If the subsequent subflow connect() fails immediately (EAFNOSUPPORT, ENETUNREACH, ...), __inet_stream_connect() returns while the socket is still SS_UNCONNECTED and never calls ->disconnect(). The error path only dropped the token and moved the msk back to TCP_CLOSE. MPTCP_FALLBACK_DONE, allow_subflows and request_mptcp were left as after early fallback, so a later connect() on the same fd stayed TCP-only. Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/633 Fixes: 0235d075a592 ("mptcp: mark as fallback even early ones") Signed-off-by: Quanye Yang --- net/mptcp/protocol.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index e1f08f71cdb1..10817ab03cbb 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -4197,9 +4197,16 @@ static int mptcp_connect(struct sock *sk, struct soc= kaddr_unsized *uaddr, * subflow_finish_connect() */ if (unlikely(err)) { - /* avoid leaving a dangling token in an unconnected socket */ mptcp_token_destroy(msk); mptcp_set_state(sk, TCP_CLOSE); + + spin_lock_bh(&msk->fallback_lock); + msk->allow_subflows =3D true; + msk->allow_infinite_fallback =3D true; + clear_bit(MPTCP_FALLBACK_DONE, &msk->flags); + spin_unlock_bh(&msk->fallback_lock); + + mptcp_subflow_ctx_reset(mptcp_subflow_ctx(ssk)); return err; } =20 --=20 2.55.0 From nobody Sat Sep 26 12:30:56 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3E6AE49159C for ; Fri, 11 Sep 2026 15:42:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789141334; cv=none; b=pNrNNAmySO38vdTr35C8r5hZg2hdJkclVsJWlktrXV42t43WBVIbQ4S4Kwj0WImJyUE+XFY2Ad58hrCvVcZbSREDUFiWcJcoR1u5uXatKDBApvN1ZlPRPtgaQO7YiNYEqhXno8uG69GErl8zRgDkqfvGOuTe3JrOV5wFTih+tkM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789141334; c=relaxed/simple; bh=b+vzH7qg4sRXiA9sZuV4XghH+6ldfHQuvfkjHwYICZ8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DgmYbkLSn/VxNZ4YP2BuCsb3UTcdknphoMngbzJLtxYtdT3WoAy6kTq1ohGYGD2HVYTaWl4YLFW5ws1eGxLQGgFVYBso0NBr8b4fDtad+2gdM8H4344ql4pILK+Wsi86A4LUizNyDy4Tnaj75Big7vuVAltwd8ONWcz1Eu3Y584= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rWbyYcCm; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rWbyYcCm" Received: by smtp.kernel.org (Postfix) with ESMTPS id E3851C2BCFA for ; Fri, 11 Sep 2026 15:42:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789141333; bh=b+vzH7qg4sRXiA9sZuV4XghH+6ldfHQuvfkjHwYICZ8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=rWbyYcCmPf2cnAybCdJZP2yVafnk6bbEkxUhM6ds2R1vhbXG/Aj6bHyPTelwugYtw oNgTSYGYSUOGubUTYBoKQSSS3Uh3G2HnpXIxldWm9i4uaII7IiIWIsStXhL6V55Zew WpMmtOchPR38cgQt2V2lQcFWmI1V0tsZslA08uiAid/ukSCxDn4ErlRubVXBC9FogM haOtp36Hn1J9MqQ1XyFVH2cMKtAb1+t02WFXgRzmxup9bsfFxujJw8IYR8NdbhY8JB WbANUiBouTZW1uRmGzWHVMiI5d9dK7VCtJHKfLGmxLCuQwIYBvuBSHvUh3Bdg9roW8 oKUQGXqXFibFA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id CCB1FC88E58 for ; Fri, 11 Sep 2026 15:42:13 +0000 (UTC) From: Quanye Yang via B4 Relay Date: Fri, 11 Sep 2026 23:42:08 +0800 Subject: [PATCH mptcp-net v2 2/2] selftests: mptcp: join: retry connect after early fallback Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260911-mptcp-connect-undo-net-v2-2-54224cea2238@proton.me> References: <20260911-mptcp-connect-undo-net-v2-0-54224cea2238@proton.me> In-Reply-To: <20260911-mptcp-connect-undo-net-v2-0-54224cea2238@proton.me> To: mptcp@lists.linux.dev Cc: X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1789141332; l=10390; i=quanyeyang@proton.me; s=20260801; h=from:subject:message-id; bh=TgcJx9K1BwzBI2BnFgkB7YkEtClbAU1cR8sXW8Q7B9k=; b=DUKG9g/M65dnDJ+K3T/XhgyezIaDRmgptVQqprMYMgpxrtinhEhPje5JTNiRUMxAXGRGAMcpF Hm2/zr2MjHEAOxTWI2ON/9jPLRfWQE1kMtccpPyeYWIQ/ruyzGNubGH X-Developer-Key: i=quanyeyang@proton.me; a=ed25519; pk=9L9FrcvzMgxPaBRU6XV0EnqTgjDqVO596rQKSZ9qZoY= X-Endpoint-Received: by B4 Relay for quanyeyang@proton.me/20260801 with auth_id=963 X-Original-From: Quanye Yang Reply-To: quanyeyang@proton.me From: Quanye Yang Cover leftover msk state when connect() fails before SS_CONNECTING. Existing mptcp_connect tests always use a fresh socket, so they cannot see a sticky fallback on the same fd. Add a small helper that optionally issues a wrong-family connect() on an MPTCP socket, then connects to a real IPv4 destination and checks MPTCP_INFO. A new mptcp_join.sh group (-n) runs two cases: - a failed connect without early fallback must not poison the retry - after a blackhole-driven early fallback plus a failed connect, clearing blackhole_timeout, the same fd must complete MP_CAPABLE again Signed-off-by: Quanye Yang --- tools/testing/selftests/net/mptcp/.gitignore | 1 + tools/testing/selftests/net/mptcp/Makefile | 1 + .../selftests/net/mptcp/mptcp_connect_retry.c | 216 +++++++++++++++++= ++++ tools/testing/selftests/net/mptcp/mptcp_join.sh | 108 +++++++++++ 4 files changed, 326 insertions(+) diff --git a/tools/testing/selftests/net/mptcp/.gitignore b/tools/testing/s= elftests/net/mptcp/.gitignore index 833279fb34e2..5ea8f3e4985f 100644 --- a/tools/testing/selftests/net/mptcp/.gitignore +++ b/tools/testing/selftests/net/mptcp/.gitignore @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only mptcp_connect +mptcp_connect_retry mptcp_diag mptcp_inq mptcp_sockopt diff --git a/tools/testing/selftests/net/mptcp/Makefile b/tools/testing/sel= ftests/net/mptcp/Makefile index 22ba0da2adb8..e2325d49228f 100644 --- a/tools/testing/selftests/net/mptcp/Makefile +++ b/tools/testing/selftests/net/mptcp/Makefile @@ -21,6 +21,7 @@ TEST_PROGS :=3D \ =20 TEST_GEN_FILES :=3D \ mptcp_connect \ + mptcp_connect_retry \ mptcp_diag \ mptcp_inq \ mptcp_sockopt \ diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect_retry.c b/tool= s/testing/selftests/net/mptcp/mptcp_connect_retry.c new file mode 100644 index 000000000000..a034d2ad73f7 --- /dev/null +++ b/tools/testing/selftests/net/mptcp/mptcp_connect_retry.c @@ -0,0 +1,216 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Same-fd MPTCP connect() retry helper. + * + * Optionally fails an initial connect() with the wrong address family, th= en + * connects to the given IPv4 destination and checks MPTCP_INFO flags. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifndef IPPROTO_MPTCP +#define IPPROTO_MPTCP 262 +#endif +#ifndef SOL_MPTCP +#define SOL_MPTCP 284 +#endif + +static void die_perror(const char *msg) +{ + perror(msg); + exit(1); +} + +static void usage(const char *argv0) +{ + fprintf(stderr, + "Usage: %s [-e] [-c] \n" + " -e first connect() with a wrong sin_family (EAFNOSUPPORT)\n" + " -c clear net.mptcp.blackhole_timeout after the failed connect\n", + argv0); + exit(1); +} + +static int getsockopt_mptcp_info(int fd, struct mptcp_info *info) +{ + socklen_t olen =3D sizeof(*info); + + memset(info, 0, sizeof(*info)); + return getsockopt(fd, SOL_MPTCP, MPTCP_INFO, info, &olen); +} + +static int get_mptcp_info(int fd, struct mptcp_info *info) +{ + if (!getsockopt_mptcp_info(fd, info)) + return 0; + + /* Fallback sockets forward SOL_MPTCP to TCP. */ + if (errno =3D=3D EOPNOTSUPP) { + info->mptcpi_flags =3D MPTCP_INFO_FLAG_FALLBACK; + return 0; + } + return -1; +} + +static int clear_blackhole_timeout(void) +{ + ssize_t n; + int fd; + + fd =3D open("/proc/sys/net/mptcp/blackhole_timeout", O_WRONLY); + if (fd < 0) + return -1; + + n =3D write(fd, "0\n", 2); + close(fd); + return n =3D=3D 2 ? 0 : -1; +} + +static int connect_wrong_family(int fd) +{ + struct sockaddr_in addr =3D { + .sin_family =3D AF_INET6, + }; + + if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) =3D=3D 0) { + fprintf(stderr, "wrong-family connect() unexpectedly succeeded\n"); + return -1; + } + if (errno !=3D EAFNOSUPPORT) { + fprintf(stderr, "wrong-family connect(): unexpected errno %d (%s)\n", + errno, strerror(errno)); + return -1; + } + return 0; +} + +static int connect_ipv4(int fd, const char *ip, unsigned short port) +{ + struct sockaddr_in addr =3D { + .sin_family =3D AF_INET, + .sin_port =3D htons(port), + }; + + if (inet_pton(AF_INET, ip, &addr.sin_addr) !=3D 1) { + fprintf(stderr, "invalid IPv4 address %s\n", ip); + return -1; + } + if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + fprintf(stderr, "connect(%s:%u): %s\n", ip, port, strerror(errno)); + return -1; + } + return 0; +} + +int main(int argc, char **argv) +{ + bool fail_first =3D false, clear_bh =3D false; + struct mptcp_info after_fail =3D { 0 }, after_ok, probe; + bool fail_fb =3D false, ok_fb, ok_key; + const char *ip; + unsigned short port; + int fd, opt, err =3D 0; + char buf[128]; + ssize_t n; + + while ((opt =3D getopt(argc, argv, "ec")) !=3D -1) { + switch (opt) { + case 'e': + fail_first =3D true; + break; + case 'c': + clear_bh =3D true; + break; + default: + usage(argv[0]); + } + } + + if (optind + 2 !=3D argc) + usage(argv[0]); + + ip =3D argv[optind]; + port =3D atoi(argv[optind + 1]); + if (!port) + usage(argv[0]); + + fd =3D socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP); + if (fd < 0) + die_perror("socket(IPPROTO_MPTCP)"); + + if (getsockopt_mptcp_info(fd, &probe)) { + fprintf(stderr, "getsockopt(MPTCP_INFO): %s\n", strerror(errno)); + close(fd); + return 2; + } + + if (fail_first && connect_wrong_family(fd)) { + close(fd); + return 1; + } + + if (fail_first) { + if (get_mptcp_info(fd, &after_fail)) { + fprintf(stderr, "getsockopt(MPTCP_INFO) after fail: %s\n", + strerror(errno)); + close(fd); + return 2; + } + fail_fb =3D after_fail.mptcpi_flags & MPTCP_INFO_FLAG_FALLBACK; + } + + if (clear_bh && clear_blackhole_timeout()) { + fprintf(stderr, "unable to clear blackhole_timeout: %s\n", + strerror(errno)); + close(fd); + return 1; + } + + if (connect_ipv4(fd, ip, port)) { + close(fd); + return 1; + } + + if (get_mptcp_info(fd, &after_ok)) { + fprintf(stderr, "getsockopt(MPTCP_INFO) after connect: %s\n", + strerror(errno)); + close(fd); + return 2; + } + + if (write(fd, "retry\n", 6) < 0) + perror("write"); + shutdown(fd, SHUT_WR); + do { + n =3D read(fd, buf, sizeof(buf)); + } while (n > 0); + close(fd); + + ok_fb =3D after_ok.mptcpi_flags & MPTCP_INFO_FLAG_FALLBACK; + ok_key =3D after_ok.mptcpi_flags & MPTCP_INFO_FLAG_REMOTE_KEY_RECEIVED; + + if (fail_fb) { + fprintf(stderr, "fallback still set after failed connect()\n"); + err =3D 1; + } + if (ok_fb || !ok_key) { + fprintf(stderr, "second connect() did not complete MPTCP handshake\n"); + err =3D 1; + } + + return err; +} diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testin= g/selftests/net/mptcp/mptcp_join.sh index 18ce7136a2b0..dd7984414747 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_join.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh @@ -3876,6 +3876,113 @@ fail_tests() fi } =20 +# $1: ns ; $2: addr ; $3: port +start_mptcp_listener() +{ + local ns=3D"${1}" + local addr=3D"${2}" + local port=3D"${3}" + local pid + + ip netns exec "${ns}" ./mptcp_connect -t ${timeout_poll} -l -p "${port}" \ + -s MPTCP "${addr}" < "${sin}" > "${sout}" & + pid=3D$! + mptcp_lib_wait_local_port_listen "${ns}" "${port}" + echo "${pid}" +} + +# Drop MP_CAPABLE SYNs until the client netns records a blackhole. +trigger_mptcp_blackhole() +{ + local port spid rc=3D0 + local count + + print_check "trigger blackhole" + + ip netns exec $ns2 sysctl -q net.mptcp.syn_retrans_before_tcp_fallback=3D0 + + if ! ip netns exec $ns2 ${iptables} -A OUTPUT -p tcp \ + -m tcp --tcp-option 30 -j DROP; then + mark_as_skipped "unable to drop MP_CAPABLE SYNs" + return 1 + fi + + port=3D$(get_port) + spid=3D$(start_mptcp_listener "$ns1" 10.0.1.1 "${port}") + + timeout ${timeout_test} ip netns exec $ns2 ./mptcp_connect \ + -t ${timeout_poll} -p "${port}" -s MPTCP 10.0.1.1 \ + < "$cin" > "$cout" || rc=3D$? + wait "${spid}" 2>/dev/null || true + + ip netns exec $ns2 ${iptables} -D OUTPUT -p tcp \ + -m tcp --tcp-option 30 -j DROP 2>/dev/null || true + + if [ ${rc} -ne 0 ]; then + fail_test "blackhole helper connect failed (rc=3D${rc})" + return 1 + fi + + count=3D$(mptcp_lib_get_counter $ns2 "MPTcpExtBlackhole") + if [ "${count:-0}" -lt 1 ]; then + fail_test "got ${count:-0} Blackhole event(s) expected >=3D 1" + return 1 + fi + + print_ok + return 0 +} + +connect_retry_tests() +{ + # failed connect without fallback, then retry + if reset "retry connect after failed connect"; then + local port spid rc + + port=3D$(get_port) + spid=3D$(start_mptcp_listener "$ns1" 10.0.1.1 "${port}") + + print_check "MPTCP after failed connect" + ip netns exec $ns2 ./mptcp_connect_retry -e 10.0.1.1 "${port}" + rc=3D$? + wait "${spid}" 2>/dev/null || true + + if [ ${rc} -eq 2 ]; then + mark_as_skipped "MPTCP_INFO not available" + elif [ ${rc} -ne 0 ]; then + fail_test "retry connect without fallback failed (rc=3D${rc})" + else + print_ok + fi + fi + + # early fallback + failed connect, then retry with blackhole disabled + if reset_check_counter "retry connect after early fallback fail" \ + "MPTcpExtBlackhole"; then + local port spid rc + + if ! trigger_mptcp_blackhole; then + return + fi + + port=3D$(get_port) + spid=3D$(start_mptcp_listener "$ns1" 10.0.1.1 "${port}") + + print_check "MPTCP after sticky fallback fail" + ip netns exec $ns2 ./mptcp_connect_retry -e -c 10.0.1.1 "${port}" + rc=3D$? + wait "${spid}" 2>/dev/null || true + + if [ ${rc} -eq 2 ]; then + mark_as_skipped "MPTCP_INFO not available" + elif [ ${rc} -ne 0 ]; then + fail_test "sticky fallback survived failed connect() (rc=3D${rc})" + else + print_ok + fi + fi +} + # $1: ns ; $2: addr ; $3: id userspace_pm_add_addr() { @@ -4617,6 +4724,7 @@ all_tests_sorted=3D( m@fullmesh_tests z@fastclose_tests F@fail_tests + n@connect_retry_tests u@userspace_tests I@endpoint_tests ) --=20 2.55.0