* [PATCH mptcp-next RFC v5 1/3] mptcp: add MPFailFallback MIB counter
2026-08-19 11:21 [PATCH mptcp-next RFC v5 0/3] mptcp: fallback to TCP on MP_FAIL with a single subflow Chenguang Zhao
@ 2026-08-19 11:21 ` Chenguang Zhao
2026-08-19 11:27 ` sashiko-bot
2026-08-19 11:21 ` [PATCH mptcp-next RFC v5 2/3] mptcp: fallback immediately on MP_FAIL reception Chenguang Zhao
` (2 subsequent siblings)
3 siblings, 1 reply; 7+ messages in thread
From: Chenguang Zhao @ 2026-08-19 11:21 UTC (permalink / raw)
To: mptcp; +Cc: chenguang.zhao, Chenguang Zhao
From: Chenguang Zhao <zhaochenguang@kylinos.cn>
Track fallback triggered by MP_FAIL reception.
Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn>
---
net/mptcp/mib.c | 1 +
net/mptcp/mib.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/net/mptcp/mib.c b/net/mptcp/mib.c
index 608cb568897c..e1211ad621c9 100644
--- a/net/mptcp/mib.c
+++ b/net/mptcp/mib.c
@@ -91,6 +91,7 @@ static const struct snmp_mib mptcp_snmp_list[] = {
SNMP_MIB_ITEM("DssReset", MPTCP_MIB_DSSRESET),
SNMP_MIB_ITEM("SimultConnectFallback", MPTCP_MIB_SIMULTCONNFALLBACK),
SNMP_MIB_ITEM("FallbackFailed", MPTCP_MIB_FALLBACKFAILED),
+ SNMP_MIB_ITEM("MPFailFallback", MPTCP_MIB_MPFAILFALLBACK),
SNMP_MIB_ITEM("WinProbe", MPTCP_MIB_WINPROBE),
SNMP_MIB_ITEM("BacklogDrop", MPTCP_MIB_BACKLOGDROP),
SNMP_MIB_ITEM("RcvPruned", MPTCP_MIB_RCVPRUNED),
diff --git a/net/mptcp/mib.h b/net/mptcp/mib.h
index 1ebdb55e9534..b006fc8cc848 100644
--- a/net/mptcp/mib.h
+++ b/net/mptcp/mib.h
@@ -94,6 +94,7 @@ enum linux_mptcp_mib_field {
MPTCP_MIB_DSSRESET, /* MP_RST: bad data mapping */
MPTCP_MIB_SIMULTCONNFALLBACK, /* Simultaneous connect */
MPTCP_MIB_FALLBACKFAILED, /* Can't fallback due to msk status */
+ MPTCP_MIB_MPFAILFALLBACK, /* Fallback after MP_FAIL received */
MPTCP_MIB_WINPROBE, /* MPTCP-level zero window probe */
MPTCP_MIB_BACKLOGDROP, /* Backlog over memory limit */
MPTCP_MIB_RCVPRUNED, /* Dropped due to memory constraints */
--
2.25.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH mptcp-next RFC v5 1/3] mptcp: add MPFailFallback MIB counter
2026-08-19 11:21 ` [PATCH mptcp-next RFC v5 1/3] mptcp: add MPFailFallback MIB counter Chenguang Zhao
@ 2026-08-19 11:27 ` sashiko-bot
0 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-08-19 11:27 UTC (permalink / raw)
To: Chenguang Zhao; +Cc: mptcp
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The newly added MIB counter MPFailFallback is never actually incremented, rendering the feature non-functional.
--
--- Patch [1]: [PATCH mptcp-next RFC v5 1/3] mptcp: add MPFailFallback MIB counter ---
commit 1a92bfe5b7b4b89111b623a355d85f37a5901375
Author: Chenguang Zhao <zhaochenguang@kylinos.cn>
mptcp: add MPFailFallback MIB counter
Track fallback triggered by MP_FAIL reception.
> diff --git a/net/mptcp/mib.c b/net/mptcp/mib.c
> index 608cb568897cf..e1211ad621c9b 100644
> --- a/net/mptcp/mib.c
> +++ b/net/mptcp/mib.c
> @@ -91,6 +91,7 @@ static const struct snmp_mib mptcp_snmp_list[] = {
> SNMP_MIB_ITEM("DssReset", MPTCP_MIB_DSSRESET),
> SNMP_MIB_ITEM("SimultConnectFallback", MPTCP_MIB_SIMULTCONNFALLBACK),
> SNMP_MIB_ITEM("FallbackFailed", MPTCP_MIB_FALLBACKFAILED),
> + SNMP_MIB_ITEM("MPFailFallback", MPTCP_MIB_MPFAILFALLBACK),
> SNMP_MIB_ITEM("WinProbe", MPTCP_MIB_WINPROBE),
> SNMP_MIB_ITEM("BacklogDrop", MPTCP_MIB_BACKLOGDROP),
> SNMP_MIB_ITEM("RcvPruned", MPTCP_MIB_RCVPRUNED),
> diff --git a/net/mptcp/mib.h b/net/mptcp/mib.h
> index 1ebdb55e95343..b006fc8cc848b 100644
> --- a/net/mptcp/mib.h
> +++ b/net/mptcp/mib.h
> @@ -94,6 +94,7 @@ enum linux_mptcp_mib_field {
> MPTCP_MIB_DSSRESET, /* MP_RST: bad data mapping */
> MPTCP_MIB_SIMULTCONNFALLBACK, /* Simultaneous connect */
> MPTCP_MIB_FALLBACKFAILED, /* Can't fallback due to msk status */
> + MPTCP_MIB_MPFAILFALLBACK, /* Fallback after MP_FAIL received */
[Severity: Medium]
Is there missing instrumentation for this new counter?
The commit adds the MPTCP_MIB_MPFAILFALLBACK counter to mptcp_snmp_list and
linux_mptcp_mib_field, but there doesn't appear to be any code in this patch
that actually increments it. When an MP_FAIL reception triggers a fallback,
should there be a call to update this counter?
Without an increment, it seems the counter will perpetually remain at 0 and
won't accurately track the fallbacks.
> MPTCP_MIB_WINPROBE, /* MPTCP-level zero window probe */
> MPTCP_MIB_BACKLOGDROP, /* Backlog over memory limit */
> MPTCP_MIB_RCVPRUNED, /* Dropped due to memory constraints */
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260819112112.1985121-1-chenguang.zhao@linux.dev?part=1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH mptcp-next RFC v5 2/3] mptcp: fallback immediately on MP_FAIL reception
2026-08-19 11:21 [PATCH mptcp-next RFC v5 0/3] mptcp: fallback to TCP on MP_FAIL with a single subflow Chenguang Zhao
2026-08-19 11:21 ` [PATCH mptcp-next RFC v5 1/3] mptcp: add MPFailFallback MIB counter Chenguang Zhao
@ 2026-08-19 11:21 ` Chenguang Zhao
2026-08-19 11:43 ` sashiko-bot
2026-08-19 11:21 ` [PATCH mptcp-next RFC v5 3/3] mptcp: reject new subflows after fallback Chenguang Zhao
2026-08-19 13:32 ` [PATCH mptcp-next RFC v5 0/3] mptcp: fallback to TCP on MP_FAIL with a single subflow MPTCP CI
3 siblings, 1 reply; 7+ messages in thread
From: Chenguang Zhao @ 2026-08-19 11:21 UTC (permalink / raw)
To: mptcp; +Cc: chenguang.zhao, Chenguang Zhao
From: Chenguang Zhao <zhaochenguang@kylinos.cn>
Call mptcp_try_fallback() right after the MP_FAIL response
ACK, and simplify mptcp_update_infinite_map() accordingly.
Fixes: 1e39e5a32ad7 ("mptcp: infinite mapping sending")
Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn>
---
net/mptcp/pm.c | 5 +++++
net/mptcp/protocol.c | 8 +-------
2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index ba7c6f80a183..69701ac7e436 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -895,6 +895,11 @@ void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq)
pr_debug("MP_FAIL response received\n");
WRITE_ONCE(subflow->fail_tout, 0);
}
+
+ if (!mptcp_try_fallback(sk, MPTCP_MIB_MPFAILFALLBACK)) {
+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FALLBACKFAILED);
+ mptcp_subflow_reset(sk);
+ }
}
static int mptcp_add_addr_len(int family, bool echo, bool port)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index f879b1061f2d..abe45a31ca5f 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1417,13 +1417,7 @@ static void mptcp_update_infinite_map(struct mptcp_sock *msk,
mpext->infinite_map = 1;
mpext->data_len = 0;
-
- if (!mptcp_try_fallback(ssk, MPTCP_MIB_INFINITEMAPTX)) {
- MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_FALLBACKFAILED);
- mptcp_subflow_reset(ssk);
- return;
- }
-
+ MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_INFINITEMAPTX);
mptcp_subflow_ctx(ssk)->send_infinite_map = 0;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH mptcp-next RFC v5 2/3] mptcp: fallback immediately on MP_FAIL reception
2026-08-19 11:21 ` [PATCH mptcp-next RFC v5 2/3] mptcp: fallback immediately on MP_FAIL reception Chenguang Zhao
@ 2026-08-19 11:43 ` sashiko-bot
0 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-08-19 11:43 UTC (permalink / raw)
To: Chenguang Zhao; +Cc: mptcp
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] State Machine Violation: Executing receive logic and queueing data on a closed socket
- [High] Logic Bug: Premature fallback evaluation uses stale MPTCP queue state
--
--- Patch [2]: [PATCH mptcp-next RFC v5 2/3] mptcp: fallback immediately on MP_FAIL reception ---
commit 293c264f04a7af047f95b678acf86f3fe06f4d7d
Author: Chenguang Zhao <zhaochenguang@kylinos.cn>
mptcp: fallback immediately on MP_FAIL reception
Call mptcp_try_fallback() right after the MP_FAIL response
ACK, and simplify mptcp_update_infinite_map() accordingly.
> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> index d7c5b50b34cc9..351f9c998d7b6 100644
> --- a/net/mptcp/pm.c
> +++ b/net/mptcp/pm.c
> @@ -895,6 +895,11 @@ void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq)
> pr_debug("MP_FAIL response received\n");
> WRITE_ONCE(subflow->fail_tout, 0);
> }
> +
> + if (!mptcp_try_fallback(sk, MPTCP_MIB_MPFAILFALLBACK)) {
> + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FALLBACKFAILED);
> + mptcp_subflow_reset(sk);
[Severity: High]
Does this synchronously reset the socket to TCP_CLOSE during the RX path?
If mptcp_try_fallback() fails, we call mptcp_subflow_reset() which sets
the socket state to TCP_CLOSE. However, this is called from
mptcp_incoming_options() when parsing the MP_FAIL option:
net/mptcp/options.c:mptcp_incoming_options() {
...
if (mp_opt.suboptions & OPTION_MPTCP_FAIL) {
mptcp_pm_mp_fail_received(sk, mp_opt.fail_seq);
MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFAILRX);
}
...
if (!(mp_opt.suboptions & OPTION_MPTCP_DSS))
return true;
}
If mptcp_incoming_options() then returns true without checking if the socket
was closed, won't the TCP stack continue normal packet processing? This could
cause tcp_data_queue() to queue the packet's payload onto the closed socket,
and tcp_rcv_established() to proceed with an invalid state.
[Severity: High]
Does premature fallback evaluation here use stale MPTCP queue state?
Evaluating mptcp_try_fallback() synchronously in the softirq receive path
creates a race condition with the asynchronous MPTCP worker.
mptcp_try_fallback() checks if msk->out_of_order_queue is empty, but because
MPTCP queues are populated asynchronously by the MPTCP worker, this state is
inherently stale.
Since the current packet hasn't even been added to the TCP receive queue
yet, couldn't a gap be correctly filled by data sitting in the subflow's TCP
queue that hasn't been pulled into the MPTCP queue yet? This would cause
fallback to erroneously fail and lead to unwarranted subflow resets.
> + }
> }
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260819112112.1985121-1-chenguang.zhao@linux.dev?part=2
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH mptcp-next RFC v5 3/3] mptcp: reject new subflows after fallback
2026-08-19 11:21 [PATCH mptcp-next RFC v5 0/3] mptcp: fallback to TCP on MP_FAIL with a single subflow Chenguang Zhao
2026-08-19 11:21 ` [PATCH mptcp-next RFC v5 1/3] mptcp: add MPFailFallback MIB counter Chenguang Zhao
2026-08-19 11:21 ` [PATCH mptcp-next RFC v5 2/3] mptcp: fallback immediately on MP_FAIL reception Chenguang Zhao
@ 2026-08-19 11:21 ` Chenguang Zhao
2026-08-19 13:32 ` [PATCH mptcp-next RFC v5 0/3] mptcp: fallback to TCP on MP_FAIL with a single subflow MPTCP CI
3 siblings, 0 replies; 7+ messages in thread
From: Chenguang Zhao @ 2026-08-19 11:21 UTC (permalink / raw)
To: mptcp; +Cc: chenguang.zhao, Chenguang Zhao
From: Chenguang Zhao <zhaochenguang@kylinos.cn>
Check FALLBACK_DONE in mptcp_can_accept_new_subflow() so that
MP_JOIN is rejected after the connection has fallen back to TCP.
Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn>
---
net/mptcp/subflow.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index af81ad5e699d..c35f3bfda535 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -61,6 +61,7 @@ static void subflow_generate_hmac(u64 key1, u64 key2, u32 nonce1, u32 nonce2,
static bool mptcp_can_accept_new_subflow(const struct mptcp_sock *msk)
{
return mptcp_is_fully_established((void *)msk) &&
+ !__mptcp_check_fallback(msk) &&
((mptcp_pm_is_userspace(msk) &&
mptcp_userspace_pm_active(msk)) ||
READ_ONCE(msk->pm.accept_subflow));
--
2.25.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH mptcp-next RFC v5 0/3] mptcp: fallback to TCP on MP_FAIL with a single subflow
2026-08-19 11:21 [PATCH mptcp-next RFC v5 0/3] mptcp: fallback to TCP on MP_FAIL with a single subflow Chenguang Zhao
` (2 preceding siblings ...)
2026-08-19 11:21 ` [PATCH mptcp-next RFC v5 3/3] mptcp: reject new subflows after fallback Chenguang Zhao
@ 2026-08-19 13:32 ` MPTCP CI
3 siblings, 0 replies; 7+ messages in thread
From: MPTCP CI @ 2026-08-19 13:32 UTC (permalink / raw)
To: Chenguang Zhao; +Cc: mptcp
Hi Chenguang,
Thank you for your modifications, that's great!
Our CI did some validations and here is its report:
- KVM Validation: normal (except selftest_mptcp_join): Critical: Global Timeout - Notice: Call Traces at boot time, rebooted and continued ❌
- KVM Validation: normal (only selftest_mptcp_join): Success! ✅
- KVM Validation: debug (except selftest_mptcp_join): Success! ✅
- KVM Validation: debug (only selftest_mptcp_join): Success! ✅
- KVM Validation: btf-normal (only bpftest_all): Success! ✅
- KVM Validation: btf-debug (only bpftest_all): Success! ✅
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/32248415369
Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/b728684acecf
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1148433
If there are some issues, you can reproduce them using the same environment as
the one used by the CI thanks to a docker image, e.g.:
$ cd [kernel source code]
$ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \
--pull always mptcp/mptcp-upstream-virtme-docker:latest \
auto-normal
For more details:
https://github.com/multipath-tcp/mptcp-upstream-virtme-docker
Please note that despite all the efforts that have been already done to have a
stable tests suite when executed on a public CI like here, it is possible some
reported issues are not due to your modifications. Still, do not hesitate to
help us improve that ;-)
Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (NGI0 Core)
^ permalink raw reply [flat|nested] 7+ messages in thread