]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
mptcp: pm: re-using ID of unused removed subflows
authorMatthieu Baerts (NGI0) <matttbe@kernel.org>
Mon, 19 Aug 2024 19:45:21 +0000 (21:45 +0200)
committerJakub Kicinski <kuba@kernel.org>
Wed, 21 Aug 2024 00:40:12 +0000 (17:40 -0700)
If no subflow is attached to the 'subflow' endpoint that is being
removed, the addr ID will not be marked as available again.

Mark the linked ID as available when removing the 'subflow' endpoint if
no subflow is attached to it.

While at it, the local_addr_used counter is decremented if the ID was
marked as being used to reflect the reality, but also to allow adding
new endpoints after that.

Fixes: b6c08380860b ("mptcp: remove addr and subflow in PM netlink")
Cc: stable@vger.kernel.org
Reviewed-by: Mat Martineau <martineau@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20240819-net-mptcp-pm-reusing-id-v1-3-38035d40de5b@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/mptcp/pm_netlink.c

index 26f0329e16bbf67e38483dd3fade7fb52847caa2..8b232a210a066e0c67c3277e95dd6a41e0ee2a70 100644 (file)
@@ -1469,8 +1469,17 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
                remove_subflow = lookup_subflow_by_saddr(&msk->conn_list, addr);
                mptcp_pm_remove_anno_addr(msk, addr, remove_subflow &&
                                          !(entry->flags & MPTCP_PM_ADDR_FLAG_IMPLICIT));
-               if (remove_subflow)
+
+               if (remove_subflow) {
                        mptcp_pm_remove_subflow(msk, &list);
+               } else if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
+                       /* If the subflow has been used, but now closed */
+                       spin_lock_bh(&msk->pm.lock);
+                       if (!__test_and_set_bit(entry->addr.id, msk->pm.id_avail_bitmap))
+                               msk->pm.local_addr_used--;
+                       spin_unlock_bh(&msk->pm.lock);
+               }
+
                release_sock(sk);
 
 next: