@@ -1514,6 +1514,28 @@ static void __mark_subflow_endp_available(struct mptcp_sock *msk, u8 id)
15141514 msk -> pm .local_addr_used -- ;
15151515}
15161516
1517+ static void mptcp_nl_remove_id_zero_address (struct mptcp_sock * msk ,
1518+ const struct mptcp_addr_info * addr )
1519+ {
1520+ struct mptcp_rm_list list = { .nr = 0 };
1521+ struct mptcp_addr_info msk_local ;
1522+
1523+ if (list_empty (& msk -> conn_list ))
1524+ return ;
1525+
1526+ mptcp_local_address ((struct sock_common * )msk , & msk_local );
1527+ if (!mptcp_addresses_equal (& msk_local , addr , addr -> port ))
1528+ return ;
1529+
1530+ list .ids [list .nr ++ ] = 0 ;
1531+
1532+ spin_lock_bh (& msk -> pm .lock );
1533+ mptcp_pm_remove_addr (msk , & list );
1534+ mptcp_pm_nl_rm_subflow_received (msk , & list );
1535+ __mark_subflow_endp_available (msk , 0 );
1536+ spin_unlock_bh (& msk -> pm .lock );
1537+ }
1538+
15171539static int mptcp_nl_remove_subflow_and_signal_addr (struct net * net ,
15181540 const struct mptcp_pm_addr_entry * entry )
15191541{
@@ -1532,6 +1554,11 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
15321554 goto next ;
15331555
15341556 lock_sock (sk );
1557+ if (entry -> addr .id == 0 ) {
1558+ mptcp_nl_remove_id_zero_address (msk , & entry -> addr );
1559+ goto out ;
1560+ }
1561+
15351562 remove_subflow = mptcp_lookup_subflow_by_saddr (& msk -> conn_list , addr );
15361563 mptcp_pm_remove_anno_addr (msk , addr , remove_subflow &&
15371564 !(entry -> flags & MPTCP_PM_ADDR_FLAG_IMPLICIT ));
@@ -1551,42 +1578,7 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
15511578
15521579 if (msk -> mpc_endpoint_id == entry -> addr .id )
15531580 msk -> mpc_endpoint_id = 0 ;
1554- release_sock (sk );
1555-
1556- next :
1557- sock_put (sk );
1558- cond_resched ();
1559- }
1560-
1561- return 0 ;
1562- }
1563-
1564- static int mptcp_nl_remove_id_zero_address (struct net * net ,
1565- struct mptcp_addr_info * addr )
1566- {
1567- struct mptcp_rm_list list = { .nr = 0 };
1568- long s_slot = 0 , s_num = 0 ;
1569- struct mptcp_sock * msk ;
1570-
1571- list .ids [list .nr ++ ] = 0 ;
1572-
1573- while ((msk = mptcp_token_iter_next (net , & s_slot , & s_num )) != NULL ) {
1574- struct sock * sk = (struct sock * )msk ;
1575- struct mptcp_addr_info msk_local ;
1576-
1577- if (list_empty (& msk -> conn_list ) || mptcp_pm_is_userspace (msk ))
1578- goto next ;
1579-
1580- mptcp_local_address ((struct sock_common * )msk , & msk_local );
1581- if (!mptcp_addresses_equal (& msk_local , addr , addr -> port ))
1582- goto next ;
1583-
1584- lock_sock (sk );
1585- spin_lock_bh (& msk -> pm .lock );
1586- mptcp_pm_remove_addr (msk , & list );
1587- mptcp_pm_nl_rm_subflow_received (msk , & list );
1588- __mark_subflow_endp_available (msk , 0 );
1589- spin_unlock_bh (& msk -> pm .lock );
1581+ out :
15901582 release_sock (sk );
15911583
15921584next :
@@ -1618,8 +1610,10 @@ int mptcp_pm_nl_del_addr_doit(struct sk_buff *skb, struct genl_info *info)
16181610 * id addresses. Additionally zero id is not accounted for in id_bitmap.
16191611 * Let's use an 'mptcp_rm_list' instead of the common remove code.
16201612 */
1621- if (addr .addr .id == 0 )
1622- return mptcp_nl_remove_id_zero_address (sock_net (skb -> sk ), & addr .addr );
1613+ if (addr .addr .id == 0 ) {
1614+ entry = & addr ;
1615+ goto del_addr ;
1616+ }
16231617
16241618 spin_lock_bh (& pernet -> lock );
16251619 entry = __lookup_addr_by_id (pernet , addr .addr .id );
@@ -1642,9 +1636,12 @@ int mptcp_pm_nl_del_addr_doit(struct sk_buff *skb, struct genl_info *info)
16421636 __clear_bit (entry -> addr .id , pernet -> id_bitmap );
16431637 spin_unlock_bh (& pernet -> lock );
16441638
1639+ del_addr :
16451640 mptcp_nl_remove_subflow_and_signal_addr (sock_net (skb -> sk ), entry );
1646- synchronize_rcu ();
1647- __mptcp_pm_release_addr_entry (entry );
1641+ if (entry -> addr .id ) {
1642+ synchronize_rcu ();
1643+ __mptcp_pm_release_addr_entry (entry );
1644+ }
16481645
16491646 return ret ;
16501647}
0 commit comments