From: Abdul Wasey <w453y.me@gmail.com>
To: mptcp@lists.linux.dev
Cc: Matthieu Baerts <matttbe@kernel.org>,
Mat Martineau <martineau@kernel.org>,
Geliang Tang <geliang@kernel.org>,
Paolo Abeni <pabeni@redhat.com>,
stable@vger.kernel.org
Subject: [PATCH mptcp-net v6 1/2] mptcp: pm: in-kernel: fullmesh: skip closed subflows
Date: Thu, 22 Oct 2026 08:50:40 +0000 [thread overview]
Message-ID: <20261022085041.211318-2-w453y.me@gmail.com> (raw)
In-Reply-To: <20261022085041.211318-1-w453y.me@gmail.com>
With fullmesh endpoints, if the endpoint used by the initial subflow is
removed and then added back, no new subflow is created from it: the
connection never uses this local address again.
The initial subflow is kept in the conn_list once closed. If it was
still established when closed, it keeps the local ID 0, which is also
the ID used by the re-added endpoint, and
fill_remote_addresses_fullmesh() then marks its remote ID as
unavailable. If it was already in TCP_CLOSE, e.g. after a reset, it is
disconnected and its context is reset: the 'closing' flag and the remote
ID are cleared, and its destination port is zeroed. It is then picked as
a remote address, with the port 0 and the ID 0, which also marks the
remote ID 0 as unavailable. In both cases, when the peer has a single
address, all subflows use the remote ID 0, and no valid remote address
is left.
Skip the subflows being closed or in TCP_CLOSE state, both when looking
for the remote IDs already in use and when picking the remote addresses.
__mptcp_subflow_active() cannot be used here: subflows still being
established have to keep their remote ID marked as in use, to avoid
creating duplicated subflows.
When no subflow is left to take the remote ID 0 address from, e.g. when
the initial subflow was the only one, use the remote address of the MPTCP
socket, as fill_remote_addr() does for non-fullmesh endpoints. Before,
re-adding the initial endpoint created no subflow in this case either,
and another endpoint only worked by picking the closed initial subflow.
Without the fullmesh flag, the remote address is taken from the MPTCP
socket, so this issue is specific to fullmesh endpoints.
Fixes: 045e9d812868 ("mptcp: fix duplicate subflow creation")
Cc: stable@vger.kernel.org
Signed-off-by: Abdul Wasey <w453y.me@gmail.com>
---
net/mptcp/pm_kernel.c | 33 ++++++++++++++++++++++++++++++++-
1 file changed, 32 insertions(+), 1 deletion(-)
diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c
index 1a7750813..c240c1056 100644
--- a/net/mptcp/pm_kernel.c
+++ b/net/mptcp/pm_kernel.c
@@ -199,6 +199,16 @@ fill_remote_addr(struct mptcp_sock *msk, struct mptcp_addr_info *local,
return 1;
}
+/* Closed subflows can stay in the conn_list, e.g. the initial one: their
+ * addresses and IDs are not reliable, possibly even reset.
+ */
+static bool mptcp_subflow_is_closed(struct mptcp_subflow_context *subflow)
+{
+ struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
+
+ return subflow->closing || inet_sk_state_load(ssk) == TCP_CLOSE;
+}
+
static unsigned int
fill_remote_addresses_fullmesh(struct mptcp_sock *msk,
struct mptcp_addr_info *local,
@@ -216,11 +226,18 @@ fill_remote_addresses_fullmesh(struct mptcp_sock *msk,
* already created by incoming ADD_ADDR
*/
bitmap_zero(unavail_id, MPTCP_PM_MAX_ADDR_ID + 1);
- mptcp_for_each_subflow(msk, subflow)
+ mptcp_for_each_subflow(msk, subflow) {
+ if (mptcp_subflow_is_closed(subflow))
+ continue;
+
if (READ_ONCE(subflow->local_id) == local->id)
__set_bit(subflow->remote_id, unavail_id);
+ }
mptcp_for_each_subflow(msk, subflow) {
+ if (mptcp_subflow_is_closed(subflow))
+ continue;
+
ssk = mptcp_subflow_tcp_sock(subflow);
mptcp_remote_address((struct sock_common *)ssk, &addrs[i]);
addrs[i].id = READ_ONCE(subflow->remote_id);
@@ -243,6 +260,20 @@ fill_remote_addresses_fullmesh(struct mptcp_sock *msk,
break;
}
+ /* The initial subflow can be closed: like fill_remote_addr(), use the
+ * remote address of the MPTCP socket for the remote ID 0.
+ */
+ if (!deny_id0 && !test_bit(0, unavail_id) && i < addrs_size &&
+ msk->pm.extra_subflows < limit_extra_subflows) {
+ struct mptcp_addr_info remote = { 0 };
+
+ mptcp_remote_address((struct sock_common *)sk, &remote);
+ if (mptcp_pm_addr_families_match(sk, local, &remote)) {
+ addrs[i++] = remote;
+ msk->pm.extra_subflows++;
+ }
+ }
+
return i;
}
--
2.43.0
next prev parent reply other threads:[~2026-10-22 8:50 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-22 8:50 [PATCH mptcp-net v6 0/2] mptcp: pm: in-kernel: fullmesh: re-add of the initial subflow endp Abdul Wasey
2026-10-22 8:50 ` Abdul Wasey [this message]
2026-10-22 8:50 ` [PATCH mptcp-net v6 2/2] selftests: mptcp: join: re-add the initial subflow endp with fullmesh Abdul Wasey
2026-10-23 22:08 ` netdev-bot+sashiko
2026-10-22 10:05 ` [PATCH mptcp-net v6 0/2] mptcp: pm: in-kernel: fullmesh: re-add of the initial subflow endp MPTCP CI
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261022085041.211318-2-w453y.me@gmail.com \
--to=w453y.me@gmail.com \
--cc=geliang@kernel.org \
--cc=martineau@kernel.org \
--cc=matttbe@kernel.org \
--cc=mptcp@lists.linux.dev \
--cc=pabeni@redhat.com \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.