[PATCH mptcp-net 1/2] mptcp: pm: in-kernel: always set as unavail when removing addr

Matthieu Baerts (NGI0) posted 2 patches 1 month, 3 weeks ago
There is a newer version of this series
[PATCH mptcp-net 1/2] mptcp: pm: in-kernel: always set as unavail when removing addr
Posted by Matthieu Baerts (NGI0) 1 month, 3 weeks ago
Syzkaller managed to find a combination of actions that was generating
this warning:

  WARNING: net/mptcp/pm_kernel.c:1074 at __mark_subflow_endp_available net/mptcp/pm_kernel.c:1074 [inline], CPU#1: syz.7.48/2535
  WARNING: net/mptcp/pm_kernel.c:1074 at mptcp_pm_nl_fullmesh net/mptcp/pm_kernel.c:1446 [inline], CPU#1: syz.7.48/2535
  WARNING: net/mptcp/pm_kernel.c:1074 at mptcp_pm_nl_set_flags_all net/mptcp/pm_kernel.c:1474 [inline], CPU#1: syz.7.48/2535
  WARNING: net/mptcp/pm_kernel.c:1074 at mptcp_pm_nl_set_flags+0x5de/0x640 net/mptcp/pm_kernel.c:1538, CPU#1: syz.7.48/2535
  Modules linked in:
  CPU: 1 UID: 0 PID: 2535 Comm: syz.7.48 Not tainted 6.18.0-03987-gea5f5e676cf5 #17 PREEMPT(voluntary)
  Hardware name: QEMU Ubuntu 25.10 PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
  RIP: 0010:__mark_subflow_endp_available net/mptcp/pm_kernel.c:1074 [inline]
  RIP: 0010:mptcp_pm_nl_fullmesh net/mptcp/pm_kernel.c:1446 [inline]
  RIP: 0010:mptcp_pm_nl_set_flags_all net/mptcp/pm_kernel.c:1474 [inline]
  RIP: 0010:mptcp_pm_nl_set_flags+0x5de/0x640 net/mptcp/pm_kernel.c:1538
  Code: 89 c7 e8 c5 8c 73 fe e9 f7 fd ff ff 49 83 ef 80 e8 b7 8c 73 fe 4c 89 ff be 03 00 00 00 e8 4a 29 e3 fe eb ac e8 a3 8c 73 fe 90 <0f> 0b 90 e9 3d ff ff ff e8 95 8c 73 fe b8 a1 ff ff ff eb 1a e8 89
  RSP: 0018:ffffc9001535b820 EFLAGS: 00010287
  netdevsim0: tun_chr_ioctl cmd 1074025677
  RAX: ffffffff82da294d RBX: 0000000000000001 RCX: 0000000000080000
  RDX: ffffc900096d0000 RSI: 00000000000006d6 RDI: 00000000000006d7
  netdevsim0: linktype set to 823
  RBP: ffff88802cdb2240 R08: 00000000000104ae R09: ffffffffffffffff
  R10: ffffffff82da27d4 R11: 0000000000000000 R12: 0000000000000000
  R13: ffff88801246d8c0 R14: ffffc9001535b8b8 R15: ffff88802cdb1800
  FS:  00007fc6ac5a76c0(0000) GS:ffff8880f90c8000(0000) knlGS:0000000000000000
  netlink: 'syz.3.50': attribute type 5 has an invalid length.
  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  netlink: 1232 bytes leftover after parsing attributes in process `syz.3.50'.
  CR2: 0000200000010000 CR3: 0000000025b1a000 CR4: 0000000000350ef0
  Call Trace:
   <TASK>
   mptcp_pm_set_flags net/mptcp/pm_netlink.c:277 [inline]
   mptcp_pm_nl_set_flags_doit+0x1d7/0x210 net/mptcp/pm_netlink.c:282
   genl_family_rcv_msg_doit+0x117/0x180 net/netlink/genetlink.c:1115
   genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline]
   genl_rcv_msg+0x3a8/0x3f0 net/netlink/genetlink.c:1210
   netlink_rcv_skb+0x16d/0x240 net/netlink/af_netlink.c:2550
   genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219
   netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
   netlink_unicast+0x3e9/0x4c0 net/netlink/af_netlink.c:1344
   netlink_sendmsg+0x4ab/0x5b0 net/netlink/af_netlink.c:1894
   sock_sendmsg_nosec net/socket.c:718 [inline]
   __sock_sendmsg+0xc9/0xf0 net/socket.c:733
   ____sys_sendmsg+0x272/0x3b0 net/socket.c:2608
   ___sys_sendmsg+0x2de/0x320 net/socket.c:2662
   __sys_sendmsg net/socket.c:2694 [inline]
   __do_sys_sendmsg net/socket.c:2699 [inline]
   __se_sys_sendmsg net/socket.c:2697 [inline]
   __x64_sys_sendmsg+0x110/0x1a0 net/socket.c:2697
   do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
   do_syscall_64+0xed/0x360 arch/x86/entry/syscall_64.c:94
   entry_SYSCALL_64_after_hwframe+0x77/0x7f
  RIP: 0033:0x7fc6adb66f6d
  Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
  RSP: 002b:00007fc6ac5a6ff8 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
  RAX: ffffffffffffffda RBX: 00007fc6addf5fa0 RCX: 00007fc6adb66f6d
  RDX: 0000000000048084 RSI: 00002000000002c0 RDI: 000000000000000e
  RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
  R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
  netlink: 'syz.5.51': attribute type 2 has an invalid length.
  R13: 00007fff25e91fe0 R14: 00007fc6ac5a7ce4 R15: 00007fff25e920d7
   </TASK>

The actions that caused that seem to be:

 - Create an MPTCP endpoint for address A without any flags
 - Create a new MPTCP connection from address A
 - Remove the MPTCP endpoint: the corresponding subflows will be removed
 - Recreate the endpoint with the same ID, but with the subflow flag
 - Change the same endpoint to add the fullmesh flag

In this case, msk->pm.local_addr_used has been decremented, but the
corresponding bit in msk->pm.id_avail_bitmap has not been reset.

When removing an endpoint, the corresponding endpoint ID was only marked
as available for announced addresses, not the other types. In these
cases, re-creating an endpoint with the same ID didn't signal/create
anything. Adding the fullmesh flag was creating the splat when calling
__mark_subflow_endp_available() from mptcp_pm_nl_fullmesh(), because
msk->pm.local_addr_used was set to 0 while the ID was marked as used.

Note: instead of adding a new spin_(un)lock_bh that would be taken in
all cases, do all the actions requiring the spin lock under the same
block.

This modification potentially fixes another issue reported by syzbot,
see [1]. But without a reproducer or more details about what exactly
happened before, it is hard to confirm.

Fixes: e255683c06df ("mptcp: pm: re-using ID of unused removed ADD_ADDR")
Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/606
Reported-by: syzbot+f56f7d56e2c6e11a01b6@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/68fcfc4a.050a0220.346f24.02fb.GAE@google.com [1]
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
 net/mptcp/pm_kernel.c | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c
index f59d21e7579c..51bcfcec882d 100644
--- a/net/mptcp/pm_kernel.c
+++ b/net/mptcp/pm_kernel.c
@@ -1057,10 +1057,8 @@ static bool mptcp_pm_remove_anno_addr(struct mptcp_sock *msk,
 	ret = mptcp_remove_anno_list_by_saddr(msk, addr);
 	if (ret || force) {
 		spin_lock_bh(&msk->pm.lock);
-		if (ret) {
-			__set_bit(addr->id, msk->pm.id_avail_bitmap);
+		if (ret)
 			msk->pm.add_addr_signaled--;
-		}
 		mptcp_pm_remove_addr(msk, &list);
 		spin_unlock_bh(&msk->pm.lock);
 	}
@@ -1098,17 +1096,14 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
 					  !(entry->flags & MPTCP_PM_ADDR_FLAG_IMPLICIT));
 
 		list.ids[0] = mptcp_endp_get_local_id(msk, addr);
-		if (remove_subflow) {
-			spin_lock_bh(&msk->pm.lock);
-			mptcp_pm_rm_subflow(msk, &list);
-			spin_unlock_bh(&msk->pm.lock);
-		}
 
-		if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
-			spin_lock_bh(&msk->pm.lock);
+		spin_lock_bh(&msk->pm.lock);
+		if (remove_subflow)
+			mptcp_pm_rm_subflow(msk, &list);
+		if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)
 			__mark_subflow_endp_available(msk, list.ids[0]);
-			spin_unlock_bh(&msk->pm.lock);
-		}
+		__set_bit(addr->id, msk->pm.id_avail_bitmap);
+		spin_unlock_bh(&msk->pm.lock);
 
 		if (msk->mpc_endpoint_id == entry->addr.id)
 			msk->mpc_endpoint_id = 0;

-- 
2.51.0
Re: [PATCH mptcp-net 1/2] mptcp: pm: in-kernel: always set as unavail when removing addr
Posted by Mat Martineau 3 weeks, 4 days ago
On Mon, 15 Dec 2025, Matthieu Baerts (NGI0) wrote:

> Syzkaller managed to find a combination of actions that was generating
> this warning:
>
>  WARNING: net/mptcp/pm_kernel.c:1074 at __mark_subflow_endp_available net/mptcp/pm_kernel.c:1074 [inline], CPU#1: syz.7.48/2535
>  WARNING: net/mptcp/pm_kernel.c:1074 at mptcp_pm_nl_fullmesh net/mptcp/pm_kernel.c:1446 [inline], CPU#1: syz.7.48/2535
>  WARNING: net/mptcp/pm_kernel.c:1074 at mptcp_pm_nl_set_flags_all net/mptcp/pm_kernel.c:1474 [inline], CPU#1: syz.7.48/2535
>  WARNING: net/mptcp/pm_kernel.c:1074 at mptcp_pm_nl_set_flags+0x5de/0x640 net/mptcp/pm_kernel.c:1538, CPU#1: syz.7.48/2535
>  Modules linked in:
>  CPU: 1 UID: 0 PID: 2535 Comm: syz.7.48 Not tainted 6.18.0-03987-gea5f5e676cf5 #17 PREEMPT(voluntary)
>  Hardware name: QEMU Ubuntu 25.10 PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
>  RIP: 0010:__mark_subflow_endp_available net/mptcp/pm_kernel.c:1074 [inline]
>  RIP: 0010:mptcp_pm_nl_fullmesh net/mptcp/pm_kernel.c:1446 [inline]
>  RIP: 0010:mptcp_pm_nl_set_flags_all net/mptcp/pm_kernel.c:1474 [inline]
>  RIP: 0010:mptcp_pm_nl_set_flags+0x5de/0x640 net/mptcp/pm_kernel.c:1538
>  Code: 89 c7 e8 c5 8c 73 fe e9 f7 fd ff ff 49 83 ef 80 e8 b7 8c 73 fe 4c 89 ff be 03 00 00 00 e8 4a 29 e3 fe eb ac e8 a3 8c 73 fe 90 <0f> 0b 90 e9 3d ff ff ff e8 95 8c 73 fe b8 a1 ff ff ff eb 1a e8 89
>  RSP: 0018:ffffc9001535b820 EFLAGS: 00010287
>  netdevsim0: tun_chr_ioctl cmd 1074025677
>  RAX: ffffffff82da294d RBX: 0000000000000001 RCX: 0000000000080000
>  RDX: ffffc900096d0000 RSI: 00000000000006d6 RDI: 00000000000006d7
>  netdevsim0: linktype set to 823
>  RBP: ffff88802cdb2240 R08: 00000000000104ae R09: ffffffffffffffff
>  R10: ffffffff82da27d4 R11: 0000000000000000 R12: 0000000000000000
>  R13: ffff88801246d8c0 R14: ffffc9001535b8b8 R15: ffff88802cdb1800
>  FS:  00007fc6ac5a76c0(0000) GS:ffff8880f90c8000(0000) knlGS:0000000000000000
>  netlink: 'syz.3.50': attribute type 5 has an invalid length.
>  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>  netlink: 1232 bytes leftover after parsing attributes in process `syz.3.50'.
>  CR2: 0000200000010000 CR3: 0000000025b1a000 CR4: 0000000000350ef0
>  Call Trace:
>   <TASK>
>   mptcp_pm_set_flags net/mptcp/pm_netlink.c:277 [inline]
>   mptcp_pm_nl_set_flags_doit+0x1d7/0x210 net/mptcp/pm_netlink.c:282
>   genl_family_rcv_msg_doit+0x117/0x180 net/netlink/genetlink.c:1115
>   genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline]
>   genl_rcv_msg+0x3a8/0x3f0 net/netlink/genetlink.c:1210
>   netlink_rcv_skb+0x16d/0x240 net/netlink/af_netlink.c:2550
>   genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219
>   netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
>   netlink_unicast+0x3e9/0x4c0 net/netlink/af_netlink.c:1344
>   netlink_sendmsg+0x4ab/0x5b0 net/netlink/af_netlink.c:1894
>   sock_sendmsg_nosec net/socket.c:718 [inline]
>   __sock_sendmsg+0xc9/0xf0 net/socket.c:733
>   ____sys_sendmsg+0x272/0x3b0 net/socket.c:2608
>   ___sys_sendmsg+0x2de/0x320 net/socket.c:2662
>   __sys_sendmsg net/socket.c:2694 [inline]
>   __do_sys_sendmsg net/socket.c:2699 [inline]
>   __se_sys_sendmsg net/socket.c:2697 [inline]
>   __x64_sys_sendmsg+0x110/0x1a0 net/socket.c:2697
>   do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
>   do_syscall_64+0xed/0x360 arch/x86/entry/syscall_64.c:94
>   entry_SYSCALL_64_after_hwframe+0x77/0x7f
>  RIP: 0033:0x7fc6adb66f6d
>  Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
>  RSP: 002b:00007fc6ac5a6ff8 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
>  RAX: ffffffffffffffda RBX: 00007fc6addf5fa0 RCX: 00007fc6adb66f6d
>  RDX: 0000000000048084 RSI: 00002000000002c0 RDI: 000000000000000e
>  RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
>  R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
>  netlink: 'syz.5.51': attribute type 2 has an invalid length.
>  R13: 00007fff25e91fe0 R14: 00007fc6ac5a7ce4 R15: 00007fff25e920d7
>   </TASK>
>
> The actions that caused that seem to be:
>
> - Create an MPTCP endpoint for address A without any flags
> - Create a new MPTCP connection from address A
> - Remove the MPTCP endpoint: the corresponding subflows will be removed
> - Recreate the endpoint with the same ID, but with the subflow flag
> - Change the same endpoint to add the fullmesh flag
>
> In this case, msk->pm.local_addr_used has been decremented, but the
> corresponding bit in msk->pm.id_avail_bitmap has not been reset.
>
> When removing an endpoint, the corresponding endpoint ID was only marked
> as available for announced addresses, not the other types. In these
> cases, re-creating an endpoint with the same ID didn't signal/create
> anything. Adding the fullmesh flag was creating the splat when calling
> __mark_subflow_endp_available() from mptcp_pm_nl_fullmesh(), because
> msk->pm.local_addr_used was set to 0 while the ID was marked as used.
>
> Note: instead of adding a new spin_(un)lock_bh that would be taken in
> all cases, do all the actions requiring the spin lock under the same
> block.
>
> This modification potentially fixes another issue reported by syzbot,
> see [1]. But without a reproducer or more details about what exactly
> happened before, it is hard to confirm.
>
> Fixes: e255683c06df ("mptcp: pm: re-using ID of unused removed ADD_ADDR")
> Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/606
> Reported-by: syzbot+f56f7d56e2c6e11a01b6@syzkaller.appspotmail.com
> Closes: https://lore.kernel.org/68fcfc4a.050a0220.346f24.02fb.GAE@google.com [1]
> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
> ---
> net/mptcp/pm_kernel.c | 19 +++++++------------
> 1 file changed, 7 insertions(+), 12 deletions(-)
>
> diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c
> index f59d21e7579c..51bcfcec882d 100644
> --- a/net/mptcp/pm_kernel.c
> +++ b/net/mptcp/pm_kernel.c
> @@ -1057,10 +1057,8 @@ static bool mptcp_pm_remove_anno_addr(struct mptcp_sock *msk,
> 	ret = mptcp_remove_anno_list_by_saddr(msk, addr);
> 	if (ret || force) {
> 		spin_lock_bh(&msk->pm.lock);
> -		if (ret) {
> -			__set_bit(addr->id, msk->pm.id_avail_bitmap);
> +		if (ret)
> 			msk->pm.add_addr_signaled--;
> -		}
> 		mptcp_pm_remove_addr(msk, &list);
> 		spin_unlock_bh(&msk->pm.lock);
> 	}
> @@ -1098,17 +1096,14 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
> 					  !(entry->flags & MPTCP_PM_ADDR_FLAG_IMPLICIT));
>
> 		list.ids[0] = mptcp_endp_get_local_id(msk, addr);
> -		if (remove_subflow) {
> -			spin_lock_bh(&msk->pm.lock);
> -			mptcp_pm_rm_subflow(msk, &list);
> -			spin_unlock_bh(&msk->pm.lock);
> -		}
>
> -		if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
> -			spin_lock_bh(&msk->pm.lock);
> +		spin_lock_bh(&msk->pm.lock);
> +		if (remove_subflow)
> +			mptcp_pm_rm_subflow(msk, &list);
> +		if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)
> 			__mark_subflow_endp_available(msk, list.ids[0]);
> -			spin_unlock_bh(&msk->pm.lock);
> -		}
> +		__set_bit(addr->id, msk->pm.id_avail_bitmap);

There's not any harm in setting this bit a second time if it was also set 
in __mark_subflow_endp_available().

However, __mark_subflow_endp_available() has some logic around ID 0 and 
mpc_endpoint_id. Is that relevant in this code path or is the new 
__set_bit() doing the correct thing by always clearing based on addr->id?

- Mat


> +		spin_unlock_bh(&msk->pm.lock);
>
> 		if (msk->mpc_endpoint_id == entry->addr.id)
> 			msk->mpc_endpoint_id = 0;
>
> -- 
> 2.51.0
>
>
>
Re: [PATCH mptcp-net 1/2] mptcp: pm: in-kernel: always set as unavail when removing addr
Posted by Matthieu Baerts 1 week, 6 days ago
Hi Mat,

Thank you for the review!

On 15/01/2026 05:56, Mat Martineau wrote:
> On Mon, 15 Dec 2025, Matthieu Baerts (NGI0) wrote:
> 
>> Syzkaller managed to find a combination of actions that was generating
>> this warning:

(...)

>> diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c
>> index f59d21e7579c..51bcfcec882d 100644
>> --- a/net/mptcp/pm_kernel.c
>> +++ b/net/mptcp/pm_kernel.c
>> @@ -1057,10 +1057,8 @@ static bool mptcp_pm_remove_anno_addr(struct
>> mptcp_sock *msk,
>>     ret = mptcp_remove_anno_list_by_saddr(msk, addr);
>>     if (ret || force) {
>>         spin_lock_bh(&msk->pm.lock);
>> -        if (ret) {
>> -            __set_bit(addr->id, msk->pm.id_avail_bitmap);
>> +        if (ret)
>>             msk->pm.add_addr_signaled--;
>> -        }
>>         mptcp_pm_remove_addr(msk, &list);
>>         spin_unlock_bh(&msk->pm.lock);
>>     }
>> @@ -1098,17 +1096,14 @@ static int
>> mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
>>                       !(entry->flags & MPTCP_PM_ADDR_FLAG_IMPLICIT));
>>
>>         list.ids[0] = mptcp_endp_get_local_id(msk, addr);
>> -        if (remove_subflow) {
>> -            spin_lock_bh(&msk->pm.lock);
>> -            mptcp_pm_rm_subflow(msk, &list);
>> -            spin_unlock_bh(&msk->pm.lock);
>> -        }
>>
>> -        if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
>> -            spin_lock_bh(&msk->pm.lock);
>> +        spin_lock_bh(&msk->pm.lock);
>> +        if (remove_subflow)
>> +            mptcp_pm_rm_subflow(msk, &list);
>> +        if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)
>>             __mark_subflow_endp_available(msk, list.ids[0]);
>> -            spin_unlock_bh(&msk->pm.lock);
>> -        }
>> +        __set_bit(addr->id, msk->pm.id_avail_bitmap);
> 
> There's not any harm in setting this bit a second time if it was also
> set in __mark_subflow_endp_available().
> 
> However, __mark_subflow_endp_available() has some logic around ID 0 and
> mpc_endpoint_id. Is that relevant in this code path or is the new
> __set_bit() doing the correct thing by always clearing based on addr->id?

Good point. Even if there is no harm, no need to set the bit for ID 0. I
will look at that!

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.

Re: [PATCH mptcp-net 1/2] mptcp: pm: in-kernel: always set as unavail when removing addr
Posted by Matthieu Baerts 1 week, 3 days ago
Hi Mat,

On 26/01/2026 19:34, Matthieu Baerts wrote:
> Hi Mat,
> 
> Thank you for the review!
> 
> On 15/01/2026 05:56, Mat Martineau wrote:
>> On Mon, 15 Dec 2025, Matthieu Baerts (NGI0) wrote:
>>
>>> Syzkaller managed to find a combination of actions that was generating
>>> this warning:
> 
> (...)
> 
>>> diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c
>>> index f59d21e7579c..51bcfcec882d 100644
>>> --- a/net/mptcp/pm_kernel.c
>>> +++ b/net/mptcp/pm_kernel.c
>>> @@ -1057,10 +1057,8 @@ static bool mptcp_pm_remove_anno_addr(struct
>>> mptcp_sock *msk,
>>>     ret = mptcp_remove_anno_list_by_saddr(msk, addr);
>>>     if (ret || force) {
>>>         spin_lock_bh(&msk->pm.lock);
>>> -        if (ret) {
>>> -            __set_bit(addr->id, msk->pm.id_avail_bitmap);
>>> +        if (ret)
>>>             msk->pm.add_addr_signaled--;
>>> -        }
>>>         mptcp_pm_remove_addr(msk, &list);
>>>         spin_unlock_bh(&msk->pm.lock);
>>>     }
>>> @@ -1098,17 +1096,14 @@ static int
>>> mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
>>>                       !(entry->flags & MPTCP_PM_ADDR_FLAG_IMPLICIT));
>>>
>>>         list.ids[0] = mptcp_endp_get_local_id(msk, addr);
>>> -        if (remove_subflow) {
>>> -            spin_lock_bh(&msk->pm.lock);
>>> -            mptcp_pm_rm_subflow(msk, &list);
>>> -            spin_unlock_bh(&msk->pm.lock);
>>> -        }
>>>
>>> -        if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
>>> -            spin_lock_bh(&msk->pm.lock);
>>> +        spin_lock_bh(&msk->pm.lock);
>>> +        if (remove_subflow)
>>> +            mptcp_pm_rm_subflow(msk, &list);
>>> +        if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)
>>>             __mark_subflow_endp_available(msk, list.ids[0]);
>>> -            spin_unlock_bh(&msk->pm.lock);
>>> -        }
>>> +        __set_bit(addr->id, msk->pm.id_avail_bitmap);
>>
>> There's not any harm in setting this bit a second time if it was also
>> set in __mark_subflow_endp_available().
>>
>> However, __mark_subflow_endp_available() has some logic around ID 0 and
>> mpc_endpoint_id. Is that relevant in this code path or is the new
>> __set_bit() doing the correct thing by always clearing based on addr->id?
> 
> Good point. Even if there is no harm, no need to set the bit for ID 0. I
> will look at that!

I just re-checked this: addr->id here is always positive because that's
the endpoint ID, not the ID used on the wire (list.ids[0]) which can be
0 if this endpoint is linked to the initial subflow. So we don't need
the same logic around ID 0 and mpc_endpoint_id.

Still, I can add this before calling __set_bit() not to clear the bit a
second time:

  else /* mark endp ID as available, e.g. Signal or MPC endp */

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.