FAILED: patch "[PATCH] mptcp: pm: kernel: drop pending ADD_ADDR when removing ID0" failed to apply to 6.1-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.1.y
git checkout FETCH_HEAD
git cherry-pick -x 2ac7d6e620764f1fc79eb4edd3610a7a661981ca
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026091604-overhung-liqueur-670b@gregkh' --subject-prefix 'PATCH 6.1.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 2ac7d6e620764f1fc79eb4edd3610a7a661981ca Mon Sep 17 00:00:00 2001
From: Kalpan Jani <[email protected]>
Date: Tue, 8 Sep 2026 16:07:09 +0200
Subject: [PATCH] mptcp: pm: kernel: drop pending ADD_ADDR when removing ID0
The in-kernel MPTCP path manager can leave a stale ADD_ADDR announcement entry alive when removing the id 0 endpoint. This happens because the id 0 removal path does not tear down pending announcements, unlike the non-zero id path.
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_announced_alloc().
Root cause: asymmetry between removal paths.
- Non-zero id path: mptcp_nl_remove_subflow_and_signal_addr() calls mptcp_pm_remove_announced() to clean up.
- Id 0 path: mptcp_nl_remove_id_zero_address() skips cleanup entirely.
Fix by making the id 0 path symmetric: call mptcp_pm_announced_remove() and decrement add_addr_signaled before queuing the RM_ADDR.
Subtle detail: signal endpoints are stored in anno_list with port 0, but msk_local carries the connection's local port. In other words, entries linked to ID0 paths should have port == 0. A follow-up patch will ensure that. mptcp_pm_announced_remove() uses use_port=true for comparison. So clear the port before the lookup.
net/mptcp/pm_kernel.c +8 -0
@@ -1137,6 +1137,8 @@ static int mptcp_nl_remove_id_zero_address(struct net *net,while ((msk =mptcp_token_iter_next (net, &s_slot, &s_num)) !=NULL ) {struct sock *sk = (struct sock *)msk;struct mptcp_addr_info msk_local; +struct mptcp_addr_info anno_addr; +bool announced;if (list_empty (&msk->conn_list) ||mptcp_pm_is_userspace (msk)) goto next;
@@ -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);spin_lock_bh (&msk->pm.lock); +if (announced) + msk->pm.add_addr_signaled--;mptcp_pm_remove_addr (msk, &list);mptcp_pm_rm_subflow (msk, &list);__mark_subflow_endp_available (msk,0 );
Sasha Levin
maintainerPATCH 1/2 mptcp: pm: uniform announced addresses helpers
From: "Matthieu Baerts (NGI0)" <[email protected]>
[ Upstream commit 7d4dacc8ccca8e40fcb5f2ece9ea3e502da1bd3f ]
Similar to the previous commit, only using the 'add' or 'anno' prefixes is confusing -- generally associated to the action of adding something, or the Latin name for "year" -- and lack of uniformity.
This has been causing issues in the past, e.g. del_add_timer seemed to suggest the goal is to delete a previously added timer.
Instead, use the mptcp_pm_announced_ prefix.
While at it, slightly improves some helpers:
- mptcp_lookup_anno_list_by_saddr: no need to specify what is used to do the lookup: mptcp_pm_announced_lookup.
- mptcp_pm_sport_in_anno_list: it doesn't just compare the port, but the whole address linked to the sublow: mptcp_pm_announced_has_ssk.
- mptcp_pm_alloc_anno_list: it allocates one item of the list, not a whole list: mptcp_pm_announced_alloc.
Backport to 6.1:
The stable tree still keeps the announcement helpers and in-kernel path manager in pm_netlink.c. Rename that existing file to pm_kernel.c and update the Makefile so target commit 2ac7d6e62076 applies at its original path. Keep the 6.1 implementation, data types, locking and teardown guard.
Apply the announcement-helper renames to the existing definitions, callers and declarations, including the destructor in protocol.c. Rename the existing static remove_anno_list_by_saddr() helper to mptcp_pm_announced_remove(); it need not be exported on this tree. The upstream userspace removal hunk is handled by the existing shared removal code, without importing the newer userspace implementation.
Also rename the existing mptcp_pm_nl_rm_subflow_received() helper and its callers to mptcp_pm_rm_subflow() to match the target patch context. No functions or behavior are added; the ID0 cleanup is left to the target.
Stable-dep-of: 2ac7d6e62076 ("mptcp: pm: kernel: drop pending ADD_ADDR when removing ID0")
---
net/mptcp/Makefile | 2 +-
net/mptcp/options.c | 2 +-
net/mptcp/pm.c | 4 +-
net/mptcp/{pm_netlink.c => pm_kernel.c} | 51 ++++++++++++-------------
net/mptcp/pm_userspace.c | 2 +-
net/mptcp/protocol.c | 2 +-
net/mptcp/protocol.h | 14 +++----
net/mptcp/subflow.c | 4 +-
8 files changed, 40 insertions(+), 41 deletions(-)
rename net/mptcp/{pm_netlink.c => pm_kernel.c} (98%)net/mptcp/Makefile +1 -1
@@ -2,7 +2,7 @@ obj-$(CONFIG_MPTCP) += mptcp.o mptcp-y := protocol.o subflow.o options.o token.o crypto.o ctrl.o pm.o diag.o \ - mib.o pm_netlink.o sockopt.o pm_userspace.o + mib.o pm_kernel.o sockopt.o pm_userspace.o obj-$(CONFIG_SYN_COOKIES) += syncookies.o obj-$(CONFIG_INET_MPTCP_DIAG) += mptcp_diag.o
net/mptcp/options.c +1 -1
@@ -1195,7 +1195,7 @@ bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)MPTCP_INC_STATS (sock_net (sk),MPTCP_MIB_ADDADDR ); }else {mptcp_pm_add_addr_echoed (msk, &mp_opt.addr); -mptcp_pm_del_add_timer (msk, &mp_opt.addr, true); +mptcp_pm_announced_del_timer (msk, &mp_opt.addr, true);MPTCP_INC_STATS (sock_net (sk),MPTCP_MIB_ECHOADD ); }
net/mptcp/pm.c +2 -2
@@ -251,7 +251,7 @@ void mptcp_pm_add_addr_echoed(struct mptcp_sock *msk,spin_lock_bh (&pm->lock); -if (mptcp_lookup_anno_list_by_saddr (msk, addr) &&READ_ONCE (pm->work_pending)) +if (mptcp_pm_announced_lookup (msk, addr) &&READ_ONCE (pm->work_pending))mptcp_pm_schedule_work (msk,MPTCP_PM_SUBFLOW_ESTABLISHED );spin_unlock_bh (&pm->lock);
@@ -396,7 +396,7 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, const struct sk_buff *skb,* let the PM state machine progress. */ if (skip_add_addr) { -mptcp_pm_del_add_timer (msk, addr, true); +mptcp_pm_announced_del_timer (msk, addr, true);mptcp_pm_subflow_established (msk); }return ret;
net/mptcp/pm_kernel.c renamed from net/mptcp/pm_netlink.c +25 -26
180 lines not on this page · raw message
net/mptcp/pm_userspace.c +1 -1
@@ -240,7 +240,7 @@ int mptcp_nl_cmd_announce(struct sk_buff *skb, struct genl_info *info)lock_sock (sk);spin_lock_bh (&msk->pm.lock); -if (mptcp_pm_alloc_anno_list (msk, &addr_val.addr)) { +if (mptcp_pm_announced_alloc (msk, &addr_val.addr)) { msk->pm.add_addr_signaled++;mptcp_pm_announce_addr (msk, &addr_val.addr, false);mptcp_pm_nl_addr_send_ack (msk);
net/mptcp/protocol.c +1 -1
@@ -3545,7 +3545,7 @@ void mptcp_destroy_common(struct mptcp_sock *msk) msk->pm.status |=BIT (MPTCP_PM_DESTROYING );spin_unlock_bh (&msk->pm.lock); -mptcp_pm_free_anno_list (msk); +mptcp_pm_free_announced_list (msk);mptcp_free_local_addr_list (msk); }
net/mptcp/protocol.h +7 -7
@@ -830,16 +830,16 @@ int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,struct mptcp_addr_info *addr, struct mptcp_addr_info *rem, u8 bkup); -bool mptcp_pm_alloc_anno_list (struct mptcp_sock *msk, +bool mptcp_pm_announced_alloc (struct mptcp_sock *msk,const struct mptcp_addr_info *addr); -void mptcp_pm_free_anno_list (struct mptcp_sock *msk); -bool mptcp_pm_sport_in_anno_list (struct mptcp_sock *msk,const struct sock *sk); +void mptcp_pm_free_announced_list (struct mptcp_sock *msk); +bool mptcp_pm_announced_has_ssk (struct mptcp_sock *msk,const struct sock *ssk);struct mptcp_pm_add_entry * -mptcp_pm_del_add_timer (struct mptcp_sock *msk, -const struct mptcp_addr_info *addr,bool check_id); +mptcp_pm_announced_del_timer (struct mptcp_sock *msk, +const struct mptcp_addr_info *addr,bool check_id);struct mptcp_pm_add_entry * -mptcp_lookup_anno_list_by_saddr (const struct mptcp_sock *msk, -const struct mptcp_addr_info *addr); +mptcp_pm_announced_lookup (const struct mptcp_sock *msk, +const struct mptcp_addr_info *addr);int mptcp_pm_get_flags_and_ifindex_by_id (struct mptcp_sock *msk,unsigned int id,u8 *flags,int *ifindex);
net/mptcp/subflow.c +2 -2
@@ -232,7 +232,7 @@ static int subflow_check_req(struct request_sock *req,pr_debug ("syn inet_sport=%d %d\n" ,ntohs (inet_sk (sk_listener)->inet_sport),ntohs (inet_sk ((struct sock *)subflow_req->msk)->inet_sport)); -if (!mptcp_pm_sport_in_anno_list (subflow_req->msk, sk_listener)) { +if (!mptcp_pm_announced_has_ssk (subflow_req->msk, sk_listener)) {SUBFLOW_REQ_INC_STATS (req,MPTCP_MIB_MISMATCHPORTSYNRX );return -EPERM ; }
@@ -815,7 +815,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,pr_debug ("ack inet_sport=%d %d\n" ,ntohs (inet_sk (sk)->inet_sport),ntohs (inet_sk ((struct sock *)owner)->inet_sport)); -if (!mptcp_pm_sport_in_anno_list (owner, sk)) { +if (!mptcp_pm_announced_has_ssk (owner, sk)) {SUBFLOW_REQ_INC_STATS (req,MPTCP_MIB_MISMATCHPORTACKRX ); goto dispose_child; }
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 mptcp: pm: kernel: drop pending ADD_ADDR when removing ID0
From: Kalpan Jani <[email protected]>
[ Upstream commit 2ac7d6e620764f1fc79eb4edd3610a7a661981ca ]
The in-kernel MPTCP path manager can leave a stale ADD_ADDR announcement entry alive when removing the id 0 endpoint. This happens because the id 0 removal path does not tear down pending announcements, unlike the non-zero id path.
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_announced_alloc().
Root cause: asymmetry between removal paths.
- Non-zero id path: mptcp_nl_remove_subflow_and_signal_addr() calls mptcp_pm_remove_announced() to clean up.
- Id 0 path: mptcp_nl_remove_id_zero_address() skips cleanup entirely.
Fix by making the id 0 path symmetric: call mptcp_pm_announced_remove() and decrement add_addr_signaled before queuing the RM_ADDR.
Subtle detail: signal endpoints are stored in anno_list with port 0, but msk_local carries the connection's local port. In other words, entries linked to ID0 paths should have port == 0. A follow-up patch will ensure that. mptcp_pm_announced_remove() uses use_port=true for comparison. So clear the port before the lookup.
--- net/mptcp/pm_kernel.c | 8 ++++++++ 1 file changed, 8 insertions(+)
net/mptcp/pm_kernel.c +8 -0
@@ -1720,6 +1720,8 @@ static int mptcp_nl_remove_id_zero_address(struct net *net,while ((msk =mptcp_token_iter_next (net, &s_slot, &s_num)) !=NULL ) {struct sock *sk = (struct sock *)msk;struct mptcp_addr_info msk_local; +struct mptcp_addr_info anno_addr; +bool announced;if (list_empty (&msk->conn_list) ||mptcp_pm_is_userspace (msk)) goto next;
@@ -1729,7 +1731,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);spin_lock_bh (&msk->pm.lock); +if (announced) + msk->pm.add_addr_signaled--;mptcp_pm_remove_addr (msk, &list);mptcp_pm_rm_subflow (msk, &list);__mark_subflow_endp_available (msk,0 );
Signature · 1 line
2.53.0