From: Jakub Kicinski <kuba@kernel.org>
To: matttbe@kernel.org
Cc: Jakub Kicinski <kuba@kernel.org>,
martineau@kernel.org, geliang@kernel.org, davem@davemloft.net,
edumazet@google.com, pabeni@redhat.com, horms@kernel.org,
netdev@vger.kernel.org, mptcp@lists.linux.dev,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: Re: [PATCH net 04/14] mptcp: pm: kernel: drop pending ADD_ADDR when removing ID0
Date: Thu, 27 Aug 2026 12:07:26 -0700 [thread overview]
Message-ID: <20260827190726.3998256-1-kuba@kernel.org> (raw)
In-Reply-To: <20260824-net-mptcp-misc-fixes-7-3-rc1-v1-4-a92309d121ca@kernel.org>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
mptcp: pm: kernel: drop pending ADD_ADDR when removing ID0
This makes the in-kernel path manager's id 0 removal path tear down a
pending ADD_ADDR announcement, matching what the non-zero id path already
does, and decrements pm.add_addr_signaled when an entry was removed.
The lookup key is built from the msk local address with the port forced to
zero.
Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/620
A few questions on the changelog and on the new lookup key.
> When the PM later reselects id 0 after adding another signal endpoint, it
> finds the stale anno_list entry and hits WARN_ON_ONCE(mptcp_pm_is_kernel())
> in mptcp_pm_alloc_anno_list().
>
> Root cause: asymmetry between removal paths.
> - Non-zero id path: mptcp_nl_remove_subflow_and_signal_addr() calls
> mptcp_pm_remove_anno_addr() to clean up.
[Severity: Low]
Do these two helper names exist in this tree? Grepping for
mptcp_pm_alloc_anno_list and mptcp_pm_remove_anno_addr at this commit
returns no matches.
The WARN_ON_ONCE(mptcp_pm_is_kernel(msk)) described here lives in
mptcp_pm_announced_alloc() in net/mptcp/pm.c, and the non-zero id path
calls mptcp_pm_remove_announced() from
mptcp_nl_remove_subflow_and_signal_addr() in net/mptcp/pm_kernel.c.
The mechanism described looks right, so should the names be updated to the
current spelling?
> diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c
> index 424f1a7f92482..1a77508132354 100644
> --- a/net/mptcp/pm_kernel.c
> +++ b/net/mptcp/pm_kernel.c
[ ... ]
> @@ -1146,7 +1148,13 @@ static int mptcp_nl_remove_id_zero_address(struct net *net,
> goto next;
>
> lock_sock(sk);
> + /* Drop a possibly pending ADD_ADDR for this address. */
> + anno_addr = msk_local;
> + anno_addr.port = 0;
> + announced = mptcp_pm_announced_remove(msk, &anno_addr);
[Severity: Medium]
This isn't a bug introduced by this patch, since before it the id 0 path
removed no announcement at all, but does forcing the port to zero here miss
signal endpoints that carry a port?
The commit message says:
Subtle detail: signal endpoints are stored in anno_list with port 0
Is that always true? mptcp_pm_nl_add_addr_doit() explicitly accepts a
non-zero port for signal-only endpoints:
if (addr.addr.port && !address_use_port(&addr)) {
NL_SET_ERR_MSG_ATTR(info->extack, attr,
"flags must have signal and not subflow when using port");
and mptcp_pm_nl_append_new_local_addr() only zeroes the port when
!address_use_port(), so an endpoint A:P can end up announced as A:P in
anno_list. mptcp_pm_announced_lookup() always compares the port:
net/mptcp/pm.c:mptcp_pm_announced_lookup() {
list_for_each_entry(entry, &msk->pm.anno_list, list) {
if (mptcp_addresses_equal(&entry->addr, addr, true))
return entry;
}
For an msk accepted on an MPTCP listener bound to A:P, msk_local is A:P and
mptcp_mpc_endpoint_setup() -> __lookup_addr() can match that endpoint
(use_port = entry->addr.port), so mpc_endpoint_id becomes its id and the
announcement is stored with port P.
In that case the port-zeroed key never matches, announced stays false and
the entry stays linked, while __mark_subflow_endp_available(msk, 0) still
re-arms the mpc_endpoint_id bit. On the next pass select_signal_address()
reselects that endpoint (port-carrying endpoints are put at the head of
endp_list by mptcp_pm_nl_append_new_local_addr()), and
mptcp_pm_announced_alloc() finds the surviving entry:
net/mptcp/pm.c:mptcp_pm_announced_alloc() {
add_entry = mptcp_pm_announced_lookup(msk, addr);
if (add_entry) {
if (WARN_ON_ONCE(mptcp_pm_is_kernel(msk)))
return false;
Is that the same splat the patch is meant to remove, and would a
port-insensitive lookup (or a second lookup with the original port) close
this case too?
> spin_lock_bh(&msk->pm.lock);
> + if (announced)
> + msk->pm.add_addr_signaled--;
> mptcp_pm_remove_addr(msk, &list);
[Severity: Medium]
Can the entry freed here belong to a different id than the RM_ADDR that is
queued right after?
mptcp_pm_announced_remove() passes check_id == false, so
mptcp_pm_announced_del_timer() unlinks whatever address matches, regardless
of the announced id:
net/mptcp/pm.c:mptcp_pm_announced_del_timer() {
entry = mptcp_pm_announced_lookup(msk, addr);
if (entry && (!check_id || entry->addr.id == addr->id)) {
...
if (!check_id && entry)
list_del(&entry->list);
}
while mptcp_nl_remove_id_zero_address() always queues id 0:
list.ids[list.nr++] = 0;
With a signal endpoint A:P (id M) matched as mpc_endpoint_id, and a second
signal endpoint A with port 0 (id N), mptcp_pm_create_subflow_or_signal_addr()
keeps id N because endp_id != mpc_endpoint_id:
endp_id = local.addr.id;
if (endp_id == msk->mpc_endpoint_id)
local.addr.id = 0;
so anno_list holds {A, port 0, id N}. A following del id 0 A matches this
msk and the port-zeroed, id-agnostic lookup frees that id N entry and
decrements add_addr_signaled for it, while the peer is only told id 0 was
removed.
If endpoint N is deleted later at a moment when no subflow in conn_list has
saddr A, mptcp_pm_remove_announced() sees announced == false and force ==
false, so no RM_ADDR is sent:
announced = mptcp_pm_announced_remove(msk, addr);
if (announced || force) {
Does the peer then keep advertising that address indefinitely? The commit
message describes the change only as making the id 0 path symmetric and does
not mention this cross-id effect.
> mptcp_pm_rm_subflow(msk, &list);
> __mark_subflow_endp_available(msk, 0);
next prev parent reply other threads:[~2026-08-27 19:07 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-24 16:48 [PATCH net 00/14] mptcp: misc fixes for v7.3-rc1 Matthieu Baerts (NGI0)
2026-08-24 16:48 ` [PATCH net 01/14] mptcp: do not reschedule the RTX timer for fallback sockets Matthieu Baerts (NGI0)
2026-08-25 16:49 ` sashiko-bot
2026-08-27 19:07 ` Jakub Kicinski
2026-08-28 6:35 ` Paolo Abeni
2026-08-24 16:48 ` [PATCH net 02/14] mptcp: subflow: no need to copy thmac during ulp_clone Matthieu Baerts (NGI0)
2026-08-27 19:07 ` Jakub Kicinski
2026-08-28 9:58 ` Matthieu Baerts
2026-08-24 16:48 ` [PATCH net 03/14] mptcp: syncookies: remember the request backup flag Matthieu Baerts (NGI0)
2026-08-24 16:48 ` [PATCH net 04/14] mptcp: pm: kernel: drop pending ADD_ADDR when removing ID0 Matthieu Baerts (NGI0)
2026-08-25 16:49 ` sashiko-bot
2026-08-27 19:07 ` Jakub Kicinski [this message]
2026-08-24 16:48 ` [PATCH net 05/14] mptcp: options: handle MPC data + csum reqd + no csum Matthieu Baerts (NGI0)
2026-08-27 19:07 ` Jakub Kicinski
2026-08-24 16:48 ` [PATCH net 06/14] selftests: mptcp: fix an UAF in mptcp_connect.c Matthieu Baerts (NGI0)
2026-08-24 16:48 ` [PATCH net 07/14] mptcp: pm: userspace: fix address ID overflow Matthieu Baerts (NGI0)
2026-08-25 16:49 ` sashiko-bot
2026-08-24 16:48 ` [PATCH net 08/14] mptcp: pm: reset retrans_time when ADD_ADDR entry is reused Matthieu Baerts (NGI0)
2026-08-27 19:07 ` Jakub Kicinski
2026-08-24 16:48 ` [PATCH net 09/14] mptcp: remove unneeded READ_ONCE() annotation Matthieu Baerts (NGI0)
2026-08-24 16:48 ` [PATCH net 10/14] selftests: mptcp: lib: dump nstat for the right test Matthieu Baerts (NGI0)
2026-08-24 16:48 ` [PATCH net 11/14] selftests: mptcp: lib: get counters " Matthieu Baerts (NGI0)
2026-08-24 16:48 ` [PATCH net 12/14] mptcp: options: fix uninit-value in mptcp_write_data_fin Matthieu Baerts (NGI0)
2026-08-24 16:48 ` [PATCH net 13/14] mptcp: being below memory limit is a likely() condition Matthieu Baerts (NGI0)
2026-08-24 16:48 ` [PATCH net 14/14] mptcp: avoid pruning for OoW data Matthieu Baerts (NGI0)
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=20260827190726.3998256-1-kuba@kernel.org \
--to=kuba@kernel.org \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=geliang@kernel.org \
--cc=horms@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=martineau@kernel.org \
--cc=matttbe@kernel.org \
--cc=mptcp@lists.linux.dev \
--cc=netdev@vger.kernel.org \
--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.