Skip to contentSkip to conversation

mptcp: fix recent failed backports (20260211)

PATCH Applied Matthieu Baerts (NGI0) 2 participants 13 messages Feb 11 – Feb 17

Subsystems (4)
lore
Share & tools
lore

Matthieu Baerts (NGI0)

author maintainer
#0 lore raw

cover mptcp: fix recent failed backports (20260211)

The following patches could not be applied without conflicts in this tree:

- 29f4801e9c8d ("selftests: mptcp: pm: ensure unknown flags are ignored")
- 2ea6190f42d0 ("mptcp: schedule rtx timer only after pushing data")
- 86730ac255b0 ("mptcp: ensure context reset on disconnect()")
- 8467458dfa61 ("selftests: mptcp: check no dup close events after error")
- 2ef9e3a3845d ("selftests: mptcp: check subflow errors in close events")
- c5d5ecf21fdd ("selftests: mptcp: join: fix local endp not being tracked")

Conflicts have been resolved, and documented in each patch.

(Note: sorry for the delay, but I was unavailable for a few weeks.)

Matthieu Baerts (NGI0) (4):
selftests: mptcp: pm: ensure unknown flags are ignored
selftests: mptcp: check no dup close events after error
selftests: mptcp: check subflow errors in close events
selftests: mptcp: join: fix local endp not being tracked

Paolo Abeni (2):
mptcp: schedule rtx timer only after pushing data
mptcp: ensure context reset on disconnect()

 net/mptcp/protocol.c                          |  24 ++--
 net/mptcp/protocol.h                          |   3 +-
 .../testing/selftests/net/mptcp/mptcp_join.sh | 111 ++++++++++++++++--
 .../testing/selftests/net/mptcp/pm_netlink.sh |   4 +
 tools/testing/selftests/net/mptcp/pm_nl_ctl.c |  11 ++
 5 files changed, 136 insertions(+), 17 deletions(-)
Signature · 1 line
2.51.0
author maintainer
#1 lore raw

PATCH 1/6 selftests: mptcp: pm: ensure unknown flags are ignored

commit 29f4801e9c8dfd12bdcb33b61a6ac479c7162bd7 upstream.

This validates the previous commit: the userspace can set unknown flags -- the 7th bit is currently unused -- without errors, but only the supported ones are printed in the endpoints dumps.

The 'Fixes' tag here below is the same as the one from the previous
commit: this patch here is not fixing anything wrong in the selftests, but it validates the previous fix for an issue introduced by this commit ID.

[ Conflicts in pm_netlink.sh, because some refactoring have been done
later on: commit 0d16ed0c2e74 ("selftests: mptcp: add {get,format}_endpoint(s) helpers") and commit c99d57d0007a ("selftests: mptcp: use pm_nl endpoint ops") are not in this version. The same operation can still be done at the same place, without using the new helpers.
Also, commit 1dc88d241f92 ("selftests: mptcp: pm_nl_ctl: always look for errors") is not in this version, and create a conflict in the context which is not related to the modification here. ]

---
 tools/testing/selftests/net/mptcp/pm_netlink.sh |  4 ++++
 tools/testing/selftests/net/mptcp/pm_nl_ctl.c   | 11 +++++++++++
 2 files changed, 15 insertions(+)
tools/testing/selftests/net/mptcp/pm_netlink.sh +4 -0
index 1b0ed849c617..4dfb6b93d9cb 100755
@@ -124,6 +124,10 @@ id 8 flags signal 10.0.1.8" "id limit"
 ip netns exec $ns1 ./pm_nl_ctl flush
 check "ip netns exec $ns1 ./pm_nl_ctl dump" "" "flush addrs"
 
+ip netns exec $ns1 ./pm_nl_ctl add 10.0.1.1 flags unknown
+check "ip netns exec $ns1 ./pm_nl_ctl dump" "id 1 flags  10.0.1.1" "ignore unknown flags"
+ip netns exec $ns1 ./pm_nl_ctl flush
+
 ip netns exec $ns1 ./pm_nl_ctl limits 9 1
 check "ip netns exec $ns1 ./pm_nl_ctl limits" "$default_limits" "rcv addrs above hard limit"
 
tools/testing/selftests/net/mptcp/pm_nl_ctl.c +11 -0
index 17e5b7ec53b6..5feecb3463a1 100644
@@ -29,6 +29,8 @@
 #define IPPROTO_MPTCP 262
 #endif
 
+#define MPTCP_PM_ADDR_FLAG_UNKNOWN _BITUL(7)
+
 static void syntax(char *argv[])
 {
 	fprintf(stderr, "%s add|ann|rem|csf|dsf|get|set|del|flush|dump|events|listen|accept [<args>]\n", argv[0]);
@@ -814,6 +816,8 @@ int add_addr(int fd, int pm_family, int argc, char *argv[])
 					flags |= MPTCP_PM_ADDR_FLAG_BACKUP;
 				else if (!strcmp(tok, "fullmesh"))
 					flags |= MPTCP_PM_ADDR_FLAG_FULLMESH;
+				else if (!strcmp(tok, "unknown"))
+					flags |= MPTCP_PM_ADDR_FLAG_UNKNOWN;
 				else
 					error(1, errno,
 					      "unknown flag %s", argv[arg]);
@@ -1019,6 +1023,13 @@ static void print_addr(struct rtattr *attrs, int len)
 					printf(",");
 			}
 
+			if (flags & MPTCP_PM_ADDR_FLAG_UNKNOWN) {
+				printf("unknown");
+				flags &= ~MPTCP_PM_ADDR_FLAG_UNKNOWN;
+				if (flags)
+					printf(",");
+			}
+
 			/* bump unknown flags, if any */
 			if (flags)
 				printf("0x%x", flags);
Signature · 1 line
2.51.0
maintainer Applied
#2 lore raw

Patch "selftests: mptcp: pm: ensure unknown flags are ignored" has been added to the 6.1-stable tree

This is a note to let you know that I've just added the patch titled

selftests: mptcp: pm: ensure unknown flags are ignored

to the 6.1-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
selftests-mptcp-pm-ensure-unknown-flags-are-ignored.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

From [email protected] Wed Feb 11 20:06:54 2026
From: "Matthieu Baerts (NGI0)" <[email protected]>
Date: Wed, 11 Feb 2026 20:06:19 +0100
Subject: selftests: mptcp: pm: ensure unknown flags are ignored
To: [email protected], [email protected], [email protected]
Cc: "Matthieu Baerts (NGI0)" <[email protected]>, [email protected], Mat Martineau <[email protected]>, Jakub Kicinski <[email protected]>
Message-ID: <[email protected]>

From: "Matthieu Baerts (NGI0)" <[email protected]>

commit 29f4801e9c8dfd12bdcb33b61a6ac479c7162bd7 upstream.

This validates the previous commit: the userspace can set unknown flags -- the 7th bit is currently unused -- without errors, but only the supported ones are printed in the endpoints dumps.

The 'Fixes' tag here below is the same as the one from the previous
commit: this patch here is not fixing anything wrong in the selftests, but it validates the previous fix for an issue introduced by this commit ID.

[ Conflicts in pm_netlink.sh, because some refactoring have been done
later on: commit 0d16ed0c2e74 ("selftests: mptcp: add {get,format}_endpoint(s) helpers") and commit c99d57d0007a ("selftests: mptcp: use pm_nl endpoint ops") are not in this version. The same operation can still be done at the same place, without using the new helpers.
Also, commit 1dc88d241f92 ("selftests: mptcp: pm_nl_ctl: always look for errors") is not in this version, and create a conflict in the context which is not related to the modification here. ]

---
 tools/testing/selftests/net/mptcp/pm_netlink.sh |    4 ++++
 tools/testing/selftests/net/mptcp/pm_nl_ctl.c   |   11 +++++++++++
 2 files changed, 15 insertions(+)
tools/testing/selftests/net/mptcp/pm_netlink.sh +4 -0
@@ -124,6 +124,10 @@ id 8 flags signal 10.0.1.8" "id limit"
 ip netns exec $ns1 ./pm_nl_ctl flush
 check "ip netns exec $ns1 ./pm_nl_ctl dump" "" "flush addrs"
 
+ip netns exec $ns1 ./pm_nl_ctl add 10.0.1.1 flags unknown
+check "ip netns exec $ns1 ./pm_nl_ctl dump" "id 1 flags  10.0.1.1" "ignore unknown flags"
+ip netns exec $ns1 ./pm_nl_ctl flush
+
 ip netns exec $ns1 ./pm_nl_ctl limits 9 1
 check "ip netns exec $ns1 ./pm_nl_ctl limits" "$default_limits" "rcv addrs above hard limit"
 
tools/testing/selftests/net/mptcp/pm_nl_ctl.c +11 -0
@@ -29,6 +29,8 @@
 #define IPPROTO_MPTCP 262
 #endif
 
+#define MPTCP_PM_ADDR_FLAG_UNKNOWN _BITUL(7)
+
 static void syntax(char *argv[])
 {
 	fprintf(stderr, "%s add|ann|rem|csf|dsf|get|set|del|flush|dump|events|listen|accept [<args>]\n", argv[0]);
@@ -814,6 +816,8 @@ int add_addr(int fd, int pm_family, int
 					flags |= MPTCP_PM_ADDR_FLAG_BACKUP;
 				else if (!strcmp(tok, "fullmesh"))
 					flags |= MPTCP_PM_ADDR_FLAG_FULLMESH;
+				else if (!strcmp(tok, "unknown"))
+					flags |= MPTCP_PM_ADDR_FLAG_UNKNOWN;
 				else
 					error(1, errno,
 					      "unknown flag %s", argv[arg]);
@@ -1018,6 +1022,13 @@ static void print_addr(struct rtattr *at
 				if (flags)
 					printf(",");
 			}
+
+			if (flags & MPTCP_PM_ADDR_FLAG_UNKNOWN) {
+				printf("unknown");
+				flags &= ~MPTCP_PM_ADDR_FLAG_UNKNOWN;
+				if (flags)
+					printf(",");
+			}
 
 			/* bump unknown flags, if any */
 			if (flags)

Patches currently in stable-queue which might be from [email protected] are

queue-6.1/selftests-mptcp-join-fix-local-endp-not-being-tracked.patch queue-6.1/mptcp-schedule-rtx-timer-only-after-pushing-data.patch queue-6.1/mptcp-ensure-context-reset-on-disconnect.patch queue-6.1/selftests-mptcp-pm-ensure-unknown-flags-are-ignored.patch queue-6.1/selftests-mptcp-check-no-dup-close-events-after-error.patch queue-6.1/selftests-mptcp-check-subflow-errors-in-close-events.patch

author maintainer
#3 lore raw

PATCH 2/6 mptcp: schedule rtx timer only after pushing data

In reply to Matthieu Baerts (NGI0)

From: Paolo Abeni <[email protected]>

commit 2ea6190f42d0416a4310e60a7fcb0b49fcbbd4fb upstream.

The MPTCP protocol usually schedule the retransmission timer only when there is some chances for such retransmissions to happen.

With a notable exception: __mptcp_push_pending() currently schedule such timer unconditionally, potentially leading to unnecessary rtx timer expiration.

The issue is present since the blamed commit below but become easily reproducible after commit 27b0e701d387 ("mptcp: drop bogus optimization in __mptcp_check_push()")

[ Conflicts in protocol.c, because commit 0fa1b3783a17 ("mptcp: use
get_send wrapper") is not in this version, and is changing the context. The same modification can still be applied. ]

---
 net/mptcp/protocol.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)
net/mptcp/protocol.c +9 -6
index 2d107a1f2ef9..ad0bfdd308be 100644
@@ -1666,7 +1666,7 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags)
 	struct mptcp_sendmsg_info info = {
 				.flags = flags,
 	};
-	bool do_check_data_fin = false;
+	bool copied = false;
 	struct mptcp_data_frag *dfrag;
 	int len;
 
@@ -1703,7 +1703,7 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags)
 				goto out;
 			}
 
-			do_check_data_fin = true;
+			copied = true;
 			info.sent += ret;
 			len -= ret;
 
@@ -1717,11 +1717,14 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags)
 		mptcp_push_release(ssk, &info);
 
 out:
-	/* ensure the rtx timer is running */
-	if (!mptcp_rtx_timer_pending(sk))
-		mptcp_reset_rtx_timer(sk);
-	if (do_check_data_fin)
+	/* Avoid scheduling the rtx timer if no data has been pushed; the timer
+	 * will be updated on positive acks by __mptcp_cleanup_una().
+	 */
+	if (copied) {
+		if (!mptcp_rtx_timer_pending(sk))
+			mptcp_reset_rtx_timer(sk);
 		mptcp_check_send_data_fin(sk);
+	}
 }
 
 static void __mptcp_subflow_push_pending(struct sock *sk, struct sock *ssk, bool first)
Signature · 1 line
2.51.0
maintainer Applied
#4 lore raw

Patch "mptcp: schedule rtx timer only after pushing data" has been added to the 6.1-stable tree

This is a note to let you know that I've just added the patch titled

mptcp: schedule rtx timer only after pushing data

to the 6.1-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
mptcp-schedule-rtx-timer-only-after-pushing-data.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

From [email protected] Wed Feb 11 20:06:58 2026
From: "Matthieu Baerts (NGI0)" <[email protected]>
Date: Wed, 11 Feb 2026 20:06:20 +0100
Subject: mptcp: schedule rtx timer only after pushing data
To: [email protected], [email protected], [email protected]
Cc: Paolo Abeni <[email protected]>, [email protected], "Matthieu Baerts (NGI0)" <[email protected]>, Jakub Kicinski <[email protected]>
Message-ID: <[email protected]>

From: Paolo Abeni <[email protected]>

commit 2ea6190f42d0416a4310e60a7fcb0b49fcbbd4fb upstream.

The MPTCP protocol usually schedule the retransmission timer only when there is some chances for such retransmissions to happen.

With a notable exception: __mptcp_push_pending() currently schedule such timer unconditionally, potentially leading to unnecessary rtx timer expiration.

The issue is present since the blamed commit below but become easily reproducible after commit 27b0e701d387 ("mptcp: drop bogus optimization in __mptcp_check_push()")

[ Conflicts in protocol.c, because commit 0fa1b3783a17 ("mptcp: use
get_send wrapper") is not in this version, and is changing the context. The same modification can still be applied. ]

---
 net/mptcp/protocol.c |   15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)
net/mptcp/protocol.c +9 -6
@@ -1666,7 +1666,7 @@ void __mptcp_push_pending(struct sock *s
 	struct mptcp_sendmsg_info info = {
 				.flags = flags,
 	};
-	bool do_check_data_fin = false;
+	bool copied = false;
 	struct mptcp_data_frag *dfrag;
 	int len;
 
@@ -1703,7 +1703,7 @@ void __mptcp_push_pending(struct sock *s
 				goto out;
 			}
 
-			do_check_data_fin = true;
+			copied = true;
 			info.sent += ret;
 			len -= ret;
 
@@ -1717,11 +1717,14 @@ void __mptcp_push_pending(struct sock *s
 		mptcp_push_release(ssk, &info);
 
 out:
-	/* ensure the rtx timer is running */
-	if (!mptcp_rtx_timer_pending(sk))
-		mptcp_reset_rtx_timer(sk);
-	if (do_check_data_fin)
+	/* Avoid scheduling the rtx timer if no data has been pushed; the timer
+	 * will be updated on positive acks by __mptcp_cleanup_una().
+	 */
+	if (copied) {
+		if (!mptcp_rtx_timer_pending(sk))
+			mptcp_reset_rtx_timer(sk);
 		mptcp_check_send_data_fin(sk);
+	}
 }
 
 static void __mptcp_subflow_push_pending(struct sock *sk, struct sock *ssk, bool first)

Patches currently in stable-queue which might be from [email protected] are

queue-6.1/selftests-mptcp-join-fix-local-endp-not-being-tracked.patch queue-6.1/mptcp-schedule-rtx-timer-only-after-pushing-data.patch queue-6.1/mptcp-ensure-context-reset-on-disconnect.patch queue-6.1/selftests-mptcp-pm-ensure-unknown-flags-are-ignored.patch queue-6.1/selftests-mptcp-check-no-dup-close-events-after-error.patch queue-6.1/selftests-mptcp-check-subflow-errors-in-close-events.patch

author maintainer
#5 lore raw

PATCH 3/6 mptcp: ensure context reset on disconnect()

In reply to Matthieu Baerts (NGI0)

From: Paolo Abeni <[email protected]>

commit 86730ac255b0497a272704de9a1df559f5d6602e upstream.

After the blamed commit below, if the MPC subflow is already in TCP_CLOSE status or has fallback to TCP at mptcp_disconnect() time, mptcp_do_fastclose() skips setting the send_fastclose flag and the later __mptcp_close_ssk() does not reset anymore the related subflow context.

Any later connection will be created with both the request_mptcp flag and the msk-level fallback status off (it is unconditionally cleared at MPTCP disconnect time), leading to a warning in subflow_data_ready():

  WARNING: CPU: 26 PID: 8996 at net/mptcp/subflow.c:1519 subflow_data_ready (net/mptcp/subflow.c:1519 (discriminator 13))
  Modules linked in:
  CPU: 26 UID: 0 PID: 8996 Comm: syz.22.39 Not tainted 6.18.0-rc7-05427-g11fc074f6c36 #1 PREEMPT(voluntary)
  Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
  RIP: 0010:subflow_data_ready (net/mptcp/subflow.c:1519 (discriminator 13))
  Code: 90 0f 0b 90 90 e9 04 fe ff ff e8 b7 1e f5 fe 89 ee bf 07 00 00 00 e8 db 19 f5 fe 83 fd 07 0f 84 35 ff ff ff e8 9d 1e f5 fe 90 <0f> 0b 90 e9 27 ff ff ff e8 8f 1e f5 fe 4c 89 e7 48 89 de e8 14 09
  RSP: 0018:ffffc9002646fb30 EFLAGS: 00010293
  RAX: 0000000000000000 RBX: ffff88813b218000 RCX: ffffffff825c8435
  RDX: ffff8881300b3580 RSI: ffffffff825c8443 RDI: 0000000000000005
  RBP: 000000000000000b R08: ffffffff825c8435 R09: 000000000000000b
  R10: 0000000000000005 R11: 0000000000000007 R12: ffff888131ac0000
  R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
  FS:  00007f88330af6c0(0000) GS:ffff888a93dd2000(0000) knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  CR2: 00007f88330aefe8 CR3: 000000010ff59000 CR4: 0000000000350ef0
  Call Trace:
   <TASK>
   tcp_data_ready (net/ipv4/tcp_input.c:5356)
   tcp_data_queue (net/ipv4/tcp_input.c:5445)
   tcp_rcv_state_process (net/ipv4/tcp_input.c:7165)
   tcp_v4_do_rcv (net/ipv4/tcp_ipv4.c:1955)
   __release_sock (include/net/sock.h:1158 (discriminator 6) net/core/sock.c:3180 (discriminator 6))
   release_sock (net/core/sock.c:3737)
   mptcp_sendmsg (net/mptcp/protocol.c:1763 net/mptcp/protocol.c:1857)
   inet_sendmsg (net/ipv4/af_inet.c:853 (discriminator 7))
   __sys_sendto (net/socket.c:727 (discriminator 15) net/socket.c:742 (discriminator 15) net/socket.c:2244 (discriminator 15))
   __x64_sys_sendto (net/socket.c:2247)
   do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1))
   entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
  RIP: 0033:0x7f883326702d

Address the issue setting an explicit fastclosing flag at fastclose time, and checking such flag after mptcp_do_fastclose().

---
 net/mptcp/protocol.c | 9 ++++++---
 net/mptcp/protocol.h | 3 ++-
 2 files changed, 8 insertions(+), 4 deletions(-)
net/mptcp/protocol.c +6 -3
index ad0bfdd308be..5274b19a5dbd 100644
@@ -2456,10 +2456,10 @@ bool __mptcp_retransmit_pending_data(struct sock *sk)
  */
 static void __mptcp_subflow_disconnect(struct sock *ssk,
 				       struct mptcp_subflow_context *subflow,
-				       unsigned int flags)
+				       bool fastclosing)
 {
 	if (((1 << ssk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) ||
-	    subflow->send_fastclose) {
+	    fastclosing) {
 		/* The MPTCP code never wait on the subflow sockets, TCP-level
 		 * disconnect should never fail
 		 */
@@ -2511,7 +2511,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
 
 	need_push = (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(sk);
 	if (!dispose_it) {
-		__mptcp_subflow_disconnect(ssk, subflow, flags);
+		__mptcp_subflow_disconnect(ssk, subflow, msk->fastclosing);
 		if (msk->subflow && ssk == msk->subflow->sk)
 			msk->subflow->state = SS_UNCONNECTED;
 		release_sock(ssk);
@@ -2802,6 +2802,8 @@ static void mptcp_do_fastclose(struct sock *sk)
 	struct mptcp_subflow_context *subflow, *tmp;
 	struct mptcp_sock *msk = mptcp_sk(sk);
 
+	msk->fastclosing = 1;
+
 	/* Explicitly send the fastclose reset as need */
 	if (__mptcp_check_fallback(msk))
 		return;
@@ -3290,6 +3292,7 @@ static int mptcp_disconnect(struct sock *sk, int flags)
 	WRITE_ONCE(msk->csum_enabled, mptcp_is_checksum_enabled(sock_net(sk)));
 	mptcp_pm_data_reset(msk);
 	mptcp_ca_reset(sk);
+	msk->fastclosing = 0;
 
 	WRITE_ONCE(sk->sk_shutdown, 0);
 	sk_error_report(sk);
net/mptcp/protocol.h +2 -1
index 6575712c789e..dd5070d57d74 100644
@@ -289,7 +289,8 @@ struct mptcp_sock {
 			nodelay:1,
 			fastopening:1,
 			in_accept_queue:1,
-			free_first:1;
+			free_first:1,
+			fastclosing:1;
 	int		keepalive_cnt;
 	int		keepalive_idle;
 	int		keepalive_intvl;
Signature · 1 line
2.51.0
maintainer Applied
#6 lore raw

Patch "mptcp: ensure context reset on disconnect()" has been added to the 6.1-stable tree

This is a note to let you know that I've just added the patch titled

mptcp: ensure context reset on disconnect()

to the 6.1-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
mptcp-ensure-context-reset-on-disconnect.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

From [email protected] Wed Feb 11 20:07:03 2026
From: "Matthieu Baerts (NGI0)" <[email protected]>
Date: Wed, 11 Feb 2026 20:06:21 +0100
Subject: mptcp: ensure context reset on disconnect()
To: [email protected], [email protected], [email protected]
Cc: Paolo Abeni <[email protected]>, [email protected], "Matthieu Baerts (NGI0)" <[email protected]>
Message-ID: <[email protected]>

From: Paolo Abeni <[email protected]>

commit 86730ac255b0497a272704de9a1df559f5d6602e upstream.

After the blamed commit below, if the MPC subflow is already in TCP_CLOSE status or has fallback to TCP at mptcp_disconnect() time, mptcp_do_fastclose() skips setting the send_fastclose flag and the later __mptcp_close_ssk() does not reset anymore the related subflow context.

Any later connection will be created with both the request_mptcp flag and the msk-level fallback status off (it is unconditionally cleared at MPTCP disconnect time), leading to a warning in subflow_data_ready():

  WARNING: CPU: 26 PID: 8996 at net/mptcp/subflow.c:1519 subflow_data_ready (net/mptcp/subflow.c:1519 (discriminator 13))
  Modules linked in:
  CPU: 26 UID: 0 PID: 8996 Comm: syz.22.39 Not tainted 6.18.0-rc7-05427-g11fc074f6c36 #1 PREEMPT(voluntary)
  Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
  RIP: 0010:subflow_data_ready (net/mptcp/subflow.c:1519 (discriminator 13))
  Code: 90 0f 0b 90 90 e9 04 fe ff ff e8 b7 1e f5 fe 89 ee bf 07 00 00 00 e8 db 19 f5 fe 83 fd 07 0f 84 35 ff ff ff e8 9d 1e f5 fe 90 <0f> 0b 90 e9 27 ff ff ff e8 8f 1e f5 fe 4c 89 e7 48 89 de e8 14 09
  RSP: 0018:ffffc9002646fb30 EFLAGS: 00010293
  RAX: 0000000000000000 RBX: ffff88813b218000 RCX: ffffffff825c8435
  RDX: ffff8881300b3580 RSI: ffffffff825c8443 RDI: 0000000000000005
  RBP: 000000000000000b R08: ffffffff825c8435 R09: 000000000000000b
  R10: 0000000000000005 R11: 0000000000000007 R12: ffff888131ac0000
  R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
  FS:  00007f88330af6c0(0000) GS:ffff888a93dd2000(0000) knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  CR2: 00007f88330aefe8 CR3: 000000010ff59000 CR4: 0000000000350ef0
  Call Trace:
   <TASK>
   tcp_data_ready (net/ipv4/tcp_input.c:5356)
   tcp_data_queue (net/ipv4/tcp_input.c:5445)
   tcp_rcv_state_process (net/ipv4/tcp_input.c:7165)
   tcp_v4_do_rcv (net/ipv4/tcp_ipv4.c:1955)
   __release_sock (include/net/sock.h:1158 (discriminator 6) net/core/sock.c:3180 (discriminator 6))
   release_sock (net/core/sock.c:3737)
   mptcp_sendmsg (net/mptcp/protocol.c:1763 net/mptcp/protocol.c:1857)
   inet_sendmsg (net/ipv4/af_inet.c:853 (discriminator 7))
   __sys_sendto (net/socket.c:727 (discriminator 15) net/socket.c:742 (discriminator 15) net/socket.c:2244 (discriminator 15))
   __x64_sys_sendto (net/socket.c:2247)
   do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1))
   entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
  RIP: 0033:0x7f883326702d

Address the issue setting an explicit fastclosing flag at fastclose time, and checking such flag after mptcp_do_fastclose().

---
 net/mptcp/protocol.c |    9 ++++++---
 net/mptcp/protocol.h |    3 ++-
 2 files changed, 8 insertions(+), 4 deletions(-)
net/mptcp/protocol.c +6 -3
@@ -2456,10 +2456,10 @@ bool __mptcp_retransmit_pending_data(str
  */
 static void __mptcp_subflow_disconnect(struct sock *ssk,
 				       struct mptcp_subflow_context *subflow,
-				       unsigned int flags)
+				       bool fastclosing)
 {
 	if (((1 << ssk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) ||
-	    subflow->send_fastclose) {
+	    fastclosing) {
 		/* The MPTCP code never wait on the subflow sockets, TCP-level
 		 * disconnect should never fail
 		 */
@@ -2511,7 +2511,7 @@ static void __mptcp_close_ssk(struct soc
 
 	need_push = (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(sk);
 	if (!dispose_it) {
-		__mptcp_subflow_disconnect(ssk, subflow, flags);
+		__mptcp_subflow_disconnect(ssk, subflow, msk->fastclosing);
 		if (msk->subflow && ssk == msk->subflow->sk)
 			msk->subflow->state = SS_UNCONNECTED;
 		release_sock(ssk);
@@ -2802,6 +2802,8 @@ static void mptcp_do_fastclose(struct so
 	struct mptcp_subflow_context *subflow, *tmp;
 	struct mptcp_sock *msk = mptcp_sk(sk);
 
+	msk->fastclosing = 1;
+
 	/* Explicitly send the fastclose reset as need */
 	if (__mptcp_check_fallback(msk))
 		return;
@@ -3290,6 +3292,7 @@ static int mptcp_disconnect(struct sock
 	WRITE_ONCE(msk->csum_enabled, mptcp_is_checksum_enabled(sock_net(sk)));
 	mptcp_pm_data_reset(msk);
 	mptcp_ca_reset(sk);
+	msk->fastclosing = 0;
 
 	WRITE_ONCE(sk->sk_shutdown, 0);
 	sk_error_report(sk);
net/mptcp/protocol.h +2 -1
@@ -289,7 +289,8 @@ struct mptcp_sock {
 			nodelay:1,
 			fastopening:1,
 			in_accept_queue:1,
-			free_first:1;
+			free_first:1,
+			fastclosing:1;
 	int		keepalive_cnt;
 	int		keepalive_idle;
 	int		keepalive_intvl;

Patches currently in stable-queue which might be from [email protected] are

queue-6.1/selftests-mptcp-join-fix-local-endp-not-being-tracked.patch queue-6.1/mptcp-schedule-rtx-timer-only-after-pushing-data.patch queue-6.1/mptcp-ensure-context-reset-on-disconnect.patch queue-6.1/selftests-mptcp-pm-ensure-unknown-flags-are-ignored.patch queue-6.1/selftests-mptcp-check-no-dup-close-events-after-error.patch queue-6.1/selftests-mptcp-check-subflow-errors-in-close-events.patch

author maintainer
#7 lore raw

PATCH 4/6 selftests: mptcp: check no dup close events after error

In reply to Matthieu Baerts (NGI0)

commit 8467458dfa61b37e259e3485a5d3e415d08193c1 upstream.

This validates the previous commit: subflow closed events are re-sent with less info when the initial subflow is disconnected after an error and each time a subflow is closed after that.

In this new test, the userspace PM is involved because that's how it was discovered, but it is not specific to it. The initial subflow is terminated with a RESET, and that will cause the subflow disconnect. Then, a new subflow is initiated, but also got rejected, which cause a second subflow closed event, but not a third one.

While at it, in case of failure to get the expected amount of events, the events are printed.

The 'Fixes' tag here below is the same as the one from the previous
commit: this patch here is not fixing anything wrong in the selftests, but it validates the previous fix for an issue introduced by this commit ID.

[ Conflicts in mptcp_join.sh, because in this version, commit
20ccc7c5f7a3 ("selftests: mptcp: join: validate event numbers") has been backported with adaptations to display results correctly, see commit 5dc9170eee96 ("selftests: mptcp: join: validate event numbers") for more details. The same type of adaptations had to be made here as well, plus importing a few additional helpers: userspace_pm_add_sf, evts_get_info and get_info_value. ]

---
 .../testing/selftests/net/mptcp/mptcp_join.sh | 79 +++++++++++++++++++
 1 file changed, 79 insertions(+)
tools/testing/selftests/net/mptcp/mptcp_join.sh +79 -0
index 9f73297b69da..f5ae51dcf811 100755
@@ -3183,6 +3183,35 @@ fail_tests()
 	fi
 }
 
+# get the value of keyword $1 in the line marked by keyword $2
+get_info_value() {
+	grep "${2}" 2>/dev/null |
+		sed -n 's/.*\('"${1}"':\)\([0-9a-f:.]*\).*$/\2/p;q'
+		# the ';q' at the end limits to the first matched entry.
+}
+
+# $1: info name ; $2: evts_ns ; [$3: event type; [$4: addr]]
+evts_get_info() {
+	grep "${4:-}" "${2}" 2>/dev/null |
+		get_info_value "${1}" "^type:${3:-1},"
+}
+
+# $1: ns ; $2: addr ; $3: id
+userspace_pm_add_sf()
+{
+	local evts=$evts_ns1
+	local tk da dp
+
+	[ "$1" == "$ns2" ] && evts=$evts_ns2
+	tk=$(evts_get_info token "$evts")
+	da=$(evts_get_info daddr4 "$evts")
+	dp=$(evts_get_info dport "$evts")
+
+	ip netns exec $1 ./pm_nl_ctl csf lip $2 lid $3 \
+				rip $da rport $dp token $tk
+	sleep 1
+}
+
 # $1: ns ; $2: event type ; $3: count
 chk_evt_nr()
 {
@@ -3204,11 +3233,32 @@ chk_evt_nr()
 		echo "[fail] got $count events, expected $exp"
 		fail_test
 		dump_stats
+		cat "${evts}"
 	else
 		echo "[ ok ]"
 	fi
 }
 
+# $1: ns ; $2: event type ; $3: expected count
+wait_event()
+{
+	local ns="${1}"
+	local evt_name="${2}"
+	local exp="${3}"
+
+	local evt="${!evt_name}"
+	local evts="${evts_ns1}"
+	local count
+
+	[ "${ns}" == "ns2" ] && evts="${evts_ns2}"
+
+	for _ in $(seq 100); do
+		count=$(grep -cw "type:${evt}" "${evts}")
+		[ "${count}" -ge "${exp}" ] && break
+		sleep 0.1
+	done
+}
+
 userspace_tests()
 {
 	# userspace pm type prevents add_addr
@@ -3302,6 +3352,35 @@ userspace_tests()
 		chk_join_nr 1 1 1
 		chk_rm_nr 0 1
 	fi
+
+	# userspace pm no duplicated spurious close events after an error
+	if reset_with_events "userspace pm no dup close events after error" &&
+	   continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
+		set_userspace_pm $ns2
+		pm_nl_set_limits $ns1 0 2
+		run_tests $ns1 $ns2 10.0.1.1 128 0 0 slow 2>/dev/null &
+		local tests_pid=$!
+		wait_event ns2 MPTCP_LIB_EVENT_ESTABLISHED 1
+		userspace_pm_add_sf $ns2 10.0.3.2 20
+		chk_subflow_nr needtitle "new subflow" 2
+
+		# force quick loss
+		ip netns exec $ns2 sysctl -q net.ipv4.tcp_syn_retries=1
+		if ip netns exec "${ns1}" ${iptables} -A INPUT -s "10.0.1.2" \
+		      -p tcp --tcp-option 30 -j REJECT --reject-with tcp-reset &&
+		   ip netns exec "${ns2}" ${iptables} -A INPUT -d "10.0.1.2" \
+		      -p tcp --tcp-option 30 -j REJECT --reject-with tcp-reset; then
+			wait_event ns2 MPTCP_LIB_EVENT_SUB_CLOSED 1
+			wait_event ns1 MPTCP_LIB_EVENT_SUB_CLOSED 1
+			chk_subflow_nr "" "after reject" 1
+			userspace_pm_add_sf $ns2 10.0.1.2 0
+			wait_event ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2
+			chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2
+		fi
+		kill_wait "${tests_pid}"
+		kill_events_pids
+		kill_tests_wait
+	fi
 }
 
 endpoint_tests()
Signature · 1 line
2.51.0
maintainer Applied
#8 lore raw

Patch "selftests: mptcp: check no dup close events after error" has been added to the 6.1-stable tree

This is a note to let you know that I've just added the patch titled

selftests: mptcp: check no dup close events after error

to the 6.1-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
selftests-mptcp-check-no-dup-close-events-after-error.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

From [email protected] Wed Feb 11 20:07:02 2026
From: "Matthieu Baerts (NGI0)" <[email protected]>
Date: Wed, 11 Feb 2026 20:06:22 +0100
Subject: selftests: mptcp: check no dup close events after error
To: [email protected], [email protected], [email protected]
Cc: "Matthieu Baerts (NGI0)" <[email protected]>, [email protected], Geliang Tang <[email protected]>, Jakub Kicinski <[email protected]>
Message-ID: <[email protected]>

From: "Matthieu Baerts (NGI0)" <[email protected]>

commit 8467458dfa61b37e259e3485a5d3e415d08193c1 upstream.

This validates the previous commit: subflow closed events are re-sent with less info when the initial subflow is disconnected after an error and each time a subflow is closed after that.

In this new test, the userspace PM is involved because that's how it was discovered, but it is not specific to it. The initial subflow is terminated with a RESET, and that will cause the subflow disconnect. Then, a new subflow is initiated, but also got rejected, which cause a second subflow closed event, but not a third one.

While at it, in case of failure to get the expected amount of events, the events are printed.

The 'Fixes' tag here below is the same as the one from the previous
commit: this patch here is not fixing anything wrong in the selftests, but it validates the previous fix for an issue introduced by this commit ID.

[ Conflicts in mptcp_join.sh, because in this version, commit
20ccc7c5f7a3 ("selftests: mptcp: join: validate event numbers") has been backported with adaptations to display results correctly, see commit 5dc9170eee96 ("selftests: mptcp: join: validate event numbers") for more details. The same type of adaptations had to be made here as well, plus importing a few additional helpers: userspace_pm_add_sf, evts_get_info and get_info_value. ]

---
 tools/testing/selftests/net/mptcp/mptcp_join.sh |   79 ++++++++++++++++++++++++
 1 file changed, 79 insertions(+)
tools/testing/selftests/net/mptcp/mptcp_join.sh +79 -0
@@ -3183,6 +3183,35 @@ fail_tests()
 	fi
 }
 
+# get the value of keyword $1 in the line marked by keyword $2
+get_info_value() {
+	grep "${2}" 2>/dev/null |
+		sed -n 's/.*\('"${1}"':\)\([0-9a-f:.]*\).*$/\2/p;q'
+		# the ';q' at the end limits to the first matched entry.
+}
+
+# $1: info name ; $2: evts_ns ; [$3: event type; [$4: addr]]
+evts_get_info() {
+	grep "${4:-}" "${2}" 2>/dev/null |
+		get_info_value "${1}" "^type:${3:-1},"
+}
+
+# $1: ns ; $2: addr ; $3: id
+userspace_pm_add_sf()
+{
+	local evts=$evts_ns1
+	local tk da dp
+
+	[ "$1" == "$ns2" ] && evts=$evts_ns2
+	tk=$(evts_get_info token "$evts")
+	da=$(evts_get_info daddr4 "$evts")
+	dp=$(evts_get_info dport "$evts")
+
+	ip netns exec $1 ./pm_nl_ctl csf lip $2 lid $3 \
+				rip $da rport $dp token $tk
+	sleep 1
+}
+
 # $1: ns ; $2: event type ; $3: count
 chk_evt_nr()
 {
@@ -3204,11 +3233,32 @@ chk_evt_nr()
 		echo "[fail] got $count events, expected $exp"
 		fail_test
 		dump_stats
+		cat "${evts}"
 	else
 		echo "[ ok ]"
 	fi
 }
 
+# $1: ns ; $2: event type ; $3: expected count
+wait_event()
+{
+	local ns="${1}"
+	local evt_name="${2}"
+	local exp="${3}"
+
+	local evt="${!evt_name}"
+	local evts="${evts_ns1}"
+	local count
+
+	[ "${ns}" == "ns2" ] && evts="${evts_ns2}"
+
+	for _ in $(seq 100); do
+		count=$(grep -cw "type:${evt}" "${evts}")
+		[ "${count}" -ge "${exp}" ] && break
+		sleep 0.1
+	done
+}
+
 userspace_tests()
 {
 	# userspace pm type prevents add_addr
@@ -3302,6 +3352,35 @@ userspace_tests()
 		chk_join_nr 1 1 1
 		chk_rm_nr 0 1
 	fi
+
+	# userspace pm no duplicated spurious close events after an error
+	if reset_with_events "userspace pm no dup close events after error" &&
+	   continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
+		set_userspace_pm $ns2
+		pm_nl_set_limits $ns1 0 2
+		run_tests $ns1 $ns2 10.0.1.1 128 0 0 slow 2>/dev/null &
+		local tests_pid=$!
+		wait_event ns2 MPTCP_LIB_EVENT_ESTABLISHED 1
+		userspace_pm_add_sf $ns2 10.0.3.2 20
+		chk_subflow_nr needtitle "new subflow" 2
+
+		# force quick loss
+		ip netns exec $ns2 sysctl -q net.ipv4.tcp_syn_retries=1
+		if ip netns exec "${ns1}" ${iptables} -A INPUT -s "10.0.1.2" \
+		      -p tcp --tcp-option 30 -j REJECT --reject-with tcp-reset &&
+		   ip netns exec "${ns2}" ${iptables} -A INPUT -d "10.0.1.2" \
+		      -p tcp --tcp-option 30 -j REJECT --reject-with tcp-reset; then
+			wait_event ns2 MPTCP_LIB_EVENT_SUB_CLOSED 1
+			wait_event ns1 MPTCP_LIB_EVENT_SUB_CLOSED 1
+			chk_subflow_nr "" "after reject" 1
+			userspace_pm_add_sf $ns2 10.0.1.2 0
+			wait_event ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2
+			chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2
+		fi
+		kill_wait "${tests_pid}"
+		kill_events_pids
+		kill_tests_wait
+	fi
 }
 
 endpoint_tests()

Patches currently in stable-queue which might be from [email protected] are

queue-6.1/selftests-mptcp-join-fix-local-endp-not-being-tracked.patch queue-6.1/mptcp-schedule-rtx-timer-only-after-pushing-data.patch queue-6.1/mptcp-ensure-context-reset-on-disconnect.patch queue-6.1/selftests-mptcp-pm-ensure-unknown-flags-are-ignored.patch queue-6.1/selftests-mptcp-check-no-dup-close-events-after-error.patch queue-6.1/selftests-mptcp-check-subflow-errors-in-close-events.patch

author maintainer
#9 lore raw

PATCH 5/6 selftests: mptcp: check subflow errors in close events

In reply to Matthieu Baerts (NGI0)

commit 2ef9e3a3845d0a20b62b01f5b731debd0364688d upstream.

This validates the previous commit: subflow closed events should contain an error field when a subflow got closed with an error, e.g. reset or timeout.

For this test, the chk_evt_nr helper has been extended to check attributes in the matched events.

In this test, the 2 subflow closed events should have an error.

The 'Fixes' tag here below is the same as the one from the previous
commit: this patch here is not fixing anything wrong in the selftests, but it validates the previous fix for an issue introduced by this commit ID.

[ Conflicts in mptcp_join.sh, because in this version, commit
20ccc7c5f7a3 ("selftests: mptcp: join: validate event numbers") has been backported with adaptations to display results correctly, see commit 5dc9170eee96 ("selftests: mptcp: join: validate event numbers") for more details. The same type of adaptations had to be made here as well. ]

---
 .../testing/selftests/net/mptcp/mptcp_join.sh | 25 ++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)
tools/testing/selftests/net/mptcp/mptcp_join.sh +22 -3
index f5ae51dcf811..7d4df90d6281 100755
@@ -3212,21 +3212,28 @@ userspace_pm_add_sf()
 	sleep 1
 }
 
-# $1: ns ; $2: event type ; $3: count
+# $1: ns ; $2: event type ; $3: count ; [ $4: attr ; $5: attr count ]
 chk_evt_nr()
 {
 	local ns=${1}
 	local evt_name="${2}"
 	local exp="${3}"
+	local attr="${4}"
+	local attr_exp="${5}"
 
 	local evts="${evts_ns1}"
 	local evt="${!evt_name}"
+	local attr_name
 	local count
 
+	if [ -n "${attr}" ]; then
+		attr_name=", ${attr}: ${attr_exp}"
+	fi
+
 	evt_name="${evt_name:16}" # without MPTCP_LIB_EVENT_
 	[ "${ns}" == "ns2" ] && evts="${evts_ns2}"
 
-	printf "%-${nr_blank}s %s" " " "event ${ns} ${evt_name} (${exp})"
+	printf "%-${nr_blank}s %s" " " "event ${ns} ${evt_name} (${exp}${attr_name})"
 
 	count=$(grep -cw "type:${evt}" "${evts}")
 	if [ "${count}" != "${exp}" ]; then
@@ -3234,6 +3241,18 @@ chk_evt_nr()
 		fail_test
 		dump_stats
 		cat "${evts}"
+		return
+	elif [ -z "${attr}" ]; then
+		echo "[ ok ]"
+		return
+	fi
+
+	count=$(grep -w "type:${evt}" "${evts}" | grep -c ",${attr}:")
+	if [ "${count}" != "${attr_exp}" ]; then
+		echo "[fail] got ${count} event attributes, expected ${attr_exp}"
+		fail_test
+		dump_stats
+		grep -w "type:${evt}" "${evts}"
 	else
 		echo "[ ok ]"
 	fi
@@ -3375,7 +3394,7 @@ userspace_tests()
 			chk_subflow_nr "" "after reject" 1
 			userspace_pm_add_sf $ns2 10.0.1.2 0
 			wait_event ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2
-			chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2
+			chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2 error 2
 		fi
 		kill_wait "${tests_pid}"
 		kill_events_pids
Signature · 1 line
2.51.0
maintainer Applied
#10 lore raw

Patch "selftests: mptcp: check subflow errors in close events" has been added to the 6.1-stable tree

This is a note to let you know that I've just added the patch titled

selftests: mptcp: check subflow errors in close events

to the 6.1-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
selftests-mptcp-check-subflow-errors-in-close-events.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

From [email protected] Wed Feb 11 20:07:07 2026
From: "Matthieu Baerts (NGI0)" <[email protected]>
Date: Wed, 11 Feb 2026 20:06:23 +0100
Subject: selftests: mptcp: check subflow errors in close events
To: [email protected], [email protected], [email protected]
Cc: "Matthieu Baerts (NGI0)" <[email protected]>, [email protected], Geliang Tang <[email protected]>, Jakub Kicinski <[email protected]>
Message-ID: <[email protected]>

From: "Matthieu Baerts (NGI0)" <[email protected]>

commit 2ef9e3a3845d0a20b62b01f5b731debd0364688d upstream.

This validates the previous commit: subflow closed events should contain an error field when a subflow got closed with an error, e.g. reset or timeout.

For this test, the chk_evt_nr helper has been extended to check attributes in the matched events.

In this test, the 2 subflow closed events should have an error.

The 'Fixes' tag here below is the same as the one from the previous
commit: this patch here is not fixing anything wrong in the selftests, but it validates the previous fix for an issue introduced by this commit ID.

[ Conflicts in mptcp_join.sh, because in this version, commit
20ccc7c5f7a3 ("selftests: mptcp: join: validate event numbers") has been backported with adaptations to display results correctly, see commit 5dc9170eee96 ("selftests: mptcp: join: validate event numbers") for more details. The same type of adaptations had to be made here as well. ]

---
 tools/testing/selftests/net/mptcp/mptcp_join.sh |   25 +++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)
tools/testing/selftests/net/mptcp/mptcp_join.sh +22 -3
@@ -3212,21 +3212,28 @@ userspace_pm_add_sf()
 	sleep 1
 }
 
-# $1: ns ; $2: event type ; $3: count
+# $1: ns ; $2: event type ; $3: count ; [ $4: attr ; $5: attr count ]
 chk_evt_nr()
 {
 	local ns=${1}
 	local evt_name="${2}"
 	local exp="${3}"
+	local attr="${4}"
+	local attr_exp="${5}"
 
 	local evts="${evts_ns1}"
 	local evt="${!evt_name}"
+	local attr_name
 	local count
 
+	if [ -n "${attr}" ]; then
+		attr_name=", ${attr}: ${attr_exp}"
+	fi
+
 	evt_name="${evt_name:16}" # without MPTCP_LIB_EVENT_
 	[ "${ns}" == "ns2" ] && evts="${evts_ns2}"
 
-	printf "%-${nr_blank}s %s" " " "event ${ns} ${evt_name} (${exp})"
+	printf "%-${nr_blank}s %s" " " "event ${ns} ${evt_name} (${exp}${attr_name})"
 
 	count=$(grep -cw "type:${evt}" "${evts}")
 	if [ "${count}" != "${exp}" ]; then
@@ -3234,6 +3241,18 @@ chk_evt_nr()
 		fail_test
 		dump_stats
 		cat "${evts}"
+		return
+	elif [ -z "${attr}" ]; then
+		echo "[ ok ]"
+		return
+	fi
+
+	count=$(grep -w "type:${evt}" "${evts}" | grep -c ",${attr}:")
+	if [ "${count}" != "${attr_exp}" ]; then
+		echo "[fail] got ${count} event attributes, expected ${attr_exp}"
+		fail_test
+		dump_stats
+		grep -w "type:${evt}" "${evts}"
 	else
 		echo "[ ok ]"
 	fi
@@ -3375,7 +3394,7 @@ userspace_tests()
 			chk_subflow_nr "" "after reject" 1
 			userspace_pm_add_sf $ns2 10.0.1.2 0
 			wait_event ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2
-			chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2
+			chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2 error 2
 		fi
 		kill_wait "${tests_pid}"
 		kill_events_pids

Patches currently in stable-queue which might be from [email protected] are

queue-6.1/selftests-mptcp-join-fix-local-endp-not-being-tracked.patch queue-6.1/mptcp-schedule-rtx-timer-only-after-pushing-data.patch queue-6.1/mptcp-ensure-context-reset-on-disconnect.patch queue-6.1/selftests-mptcp-pm-ensure-unknown-flags-are-ignored.patch queue-6.1/selftests-mptcp-check-no-dup-close-events-after-error.patch queue-6.1/selftests-mptcp-check-subflow-errors-in-close-events.patch

author maintainer
#11 lore raw

PATCH 6/6 selftests: mptcp: join: fix local endp not being tracked

In reply to Matthieu Baerts (NGI0)

commit c5d5ecf21fdd9ce91e6116feb3aa83cee73352cc upstream.

When running this mptcp_join.sh selftest on older kernel versions not supporting local endpoints tracking, this test fails because 3 MP_JOIN ACKs have been received, while only 2 were expected.

It is not clear why only 2 MP_JOIN ACKs were expected on old kernel versions, while 3 MP_JOIN SYN and SYN+ACK were expected. When testing on the v5.15.197 kernel, 3 MP_JOIN ACKs are seen, which is also what is expected in the selftests included in this kernel version, see commit f4480eaad489 ("selftests: mptcp: add missing join check").

Switch the expected MP_JOIN ACKs to 3. While at it, move this chk_join_nr helper out of the special condition for older kernel versions as it is now the same as with more recent ones. Also, invert the condition to be more logical: what's expected on newer kernel versions having such helper first.

Fixes d4c81bbb8600 ("selftests: mptcp: join: support local endpoint being tracked or not")

[ Conflicts in mptcp_join.sh, because commit e571fb09c893 ("selftests:
mptcp: add speed env var") is not in this version, and caused conflicts in the context. The same modification can still be applied at the same place. ]

---
 tools/testing/selftests/net/mptcp/mptcp_join.sh | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)
tools/testing/selftests/net/mptcp/mptcp_join.sh +4 -5
index 7d4df90d6281..5a40e09e8374 100755
@@ -2181,17 +2181,16 @@ signal_address_tests()
 		# the peer could possibly miss some addr notification, allow retransmission
 		ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1
 		run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
+		chk_join_nr 3 3 3
 
 		# It is not directly linked to the commit introducing this
 		# symbol but for the parent one which is linked anyway.
-		if ! mptcp_lib_kallsyms_has "mptcp_pm_subflow_check_next$"; then
-			chk_join_nr 3 3 2
-			chk_add_nr 4 4
-		else
-			chk_join_nr 3 3 3
+		if mptcp_lib_kallsyms_has "mptcp_pm_subflow_check_next$"; then
 			# the server will not signal the address terminating
 			# the MPC subflow
 			chk_add_nr 3 3
+		else
+			chk_add_nr 4 4
 		fi
 	fi
 }
Signature · 1 line
2.51.0
maintainer Applied
#12 lore raw

Patch "selftests: mptcp: join: fix local endp not being tracked" has been added to the 6.1-stable tree

This is a note to let you know that I've just added the patch titled

selftests: mptcp: join: fix local endp not being tracked

to the 6.1-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
selftests-mptcp-join-fix-local-endp-not-being-tracked.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

From [email protected] Wed Feb 11 20:07:06 2026
From: "Matthieu Baerts (NGI0)" <[email protected]>
Date: Wed, 11 Feb 2026 20:06:24 +0100
Subject: selftests: mptcp: join: fix local endp not being tracked
To: [email protected], [email protected], [email protected]
Cc: "Matthieu Baerts (NGI0)" <[email protected]>, [email protected], Mat Martineau <[email protected]>, Jakub Kicinski <[email protected]>
Message-ID: <[email protected]>

From: "Matthieu Baerts (NGI0)" <[email protected]>

commit c5d5ecf21fdd9ce91e6116feb3aa83cee73352cc upstream.

When running this mptcp_join.sh selftest on older kernel versions not supporting local endpoints tracking, this test fails because 3 MP_JOIN ACKs have been received, while only 2 were expected.

It is not clear why only 2 MP_JOIN ACKs were expected on old kernel versions, while 3 MP_JOIN SYN and SYN+ACK were expected. When testing on the v5.15.197 kernel, 3 MP_JOIN ACKs are seen, which is also what is expected in the selftests included in this kernel version, see commit f4480eaad489 ("selftests: mptcp: add missing join check").

Switch the expected MP_JOIN ACKs to 3. While at it, move this chk_join_nr helper out of the special condition for older kernel versions as it is now the same as with more recent ones. Also, invert the condition to be more logical: what's expected on newer kernel versions having such helper first.

Fixes d4c81bbb8600 ("selftests: mptcp: join: support local endpoint being tracked or not")

[ Conflicts in mptcp_join.sh, because commit e571fb09c893 ("selftests:
mptcp: add speed env var") is not in this version, and caused conflicts in the context. The same modification can still be applied at the same place. ]

---
 tools/testing/selftests/net/mptcp/mptcp_join.sh |    9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)
tools/testing/selftests/net/mptcp/mptcp_join.sh +4 -5
@@ -2181,17 +2181,16 @@ signal_address_tests()
 		# the peer could possibly miss some addr notification, allow retransmission
 		ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1
 		run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
+		chk_join_nr 3 3 3
 
 		# It is not directly linked to the commit introducing this
 		# symbol but for the parent one which is linked anyway.
-		if ! mptcp_lib_kallsyms_has "mptcp_pm_subflow_check_next$"; then
-			chk_join_nr 3 3 2
-			chk_add_nr 4 4
-		else
-			chk_join_nr 3 3 3
+		if mptcp_lib_kallsyms_has "mptcp_pm_subflow_check_next$"; then
 			# the server will not signal the address terminating
 			# the MPC subflow
 			chk_add_nr 3 3
+		else
+			chk_add_nr 4 4
 		fi
 	fi
 }

Patches currently in stable-queue which might be from [email protected] are

queue-6.1/selftests-mptcp-join-fix-local-endp-not-being-tracked.patch queue-6.1/mptcp-schedule-rtx-timer-only-after-pushing-data.patch queue-6.1/mptcp-ensure-context-reset-on-disconnect.patch queue-6.1/selftests-mptcp-pm-ensure-unknown-flags-are-ignored.patch queue-6.1/selftests-mptcp-check-no-dup-close-events-after-error.patch queue-6.1/selftests-mptcp-check-subflow-errors-in-close-events.patch