@@ -69,6 +69,7 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
6969 MPTCP_PM_MAX_ADDR_ID + 1 ,
7070 1 );
7171 list_add_tail_rcu (& e -> list , & msk -> pm .userspace_pm_local_addr_list );
72+ msk -> pm .local_addr_used ++ ;
7273 ret = e -> addr .id ;
7374 } else if (match ) {
7475 ret = entry -> addr .id ;
@@ -79,6 +80,31 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
7980 return ret ;
8081}
8182
83+ /* If the subflow is closed from the other peer (not via a
84+ * subflow destroy command then), we want to keep the entry
85+ * not to assign the same ID to another address and to be
86+ * able to send RM_ADDR after the removal of the subflow.
87+ */
88+ static int mptcp_userspace_pm_delete_local_addr (struct mptcp_sock * msk ,
89+ struct mptcp_pm_addr_entry * addr )
90+ {
91+ struct mptcp_pm_addr_entry * entry , * tmp ;
92+
93+ list_for_each_entry_safe (entry , tmp , & msk -> pm .userspace_pm_local_addr_list , list ) {
94+ if (mptcp_addresses_equal (& entry -> addr , & addr -> addr , false)) {
95+ /* TODO: a refcount is needed because the entry can
96+ * be used multiple times (e.g. fullmesh mode).
97+ */
98+ list_del_rcu (& entry -> list );
99+ kfree (entry );
100+ msk -> pm .local_addr_used -- ;
101+ return 0 ;
102+ }
103+ }
104+
105+ return - EINVAL ;
106+ }
107+
82108int mptcp_userspace_pm_get_flags_and_ifindex_by_id (struct mptcp_sock * msk ,
83109 unsigned int id ,
84110 u8 * flags , int * ifindex )
@@ -171,6 +197,7 @@ int mptcp_nl_cmd_announce(struct sk_buff *skb, struct genl_info *info)
171197 spin_lock_bh (& msk -> pm .lock );
172198
173199 if (mptcp_pm_alloc_anno_list (msk , & addr_val )) {
200+ msk -> pm .add_addr_signaled ++ ;
174201 mptcp_pm_announce_addr (msk , & addr_val .addr , false);
175202 mptcp_pm_nl_addr_send_ack (msk );
176203 }
@@ -232,7 +259,7 @@ int mptcp_nl_cmd_remove(struct sk_buff *skb, struct genl_info *info)
232259
233260 list_move (& match -> list , & free_list );
234261
235- mptcp_pm_remove_addrs_and_subflows (msk , & free_list );
262+ mptcp_pm_remove_addrs (msk , & free_list );
236263
237264 release_sock ((struct sock * )msk );
238265
@@ -251,6 +278,7 @@ int mptcp_nl_cmd_sf_create(struct sk_buff *skb, struct genl_info *info)
251278 struct nlattr * raddr = info -> attrs [MPTCP_PM_ATTR_ADDR_REMOTE ];
252279 struct nlattr * token = info -> attrs [MPTCP_PM_ATTR_TOKEN ];
253280 struct nlattr * laddr = info -> attrs [MPTCP_PM_ATTR_ADDR ];
281+ struct mptcp_pm_addr_entry local = { 0 };
254282 struct mptcp_addr_info addr_r ;
255283 struct mptcp_addr_info addr_l ;
256284 struct mptcp_sock * msk ;
@@ -302,12 +330,26 @@ int mptcp_nl_cmd_sf_create(struct sk_buff *skb, struct genl_info *info)
302330 goto create_err ;
303331 }
304332
333+ local .addr = addr_l ;
334+ err = mptcp_userspace_pm_append_new_local_addr (msk , & local );
335+ if (err < 0 ) {
336+ GENL_SET_ERR_MSG (info , "did not match address and id" );
337+ goto create_err ;
338+ }
339+
305340 lock_sock (sk );
306341
307342 err = __mptcp_subflow_connect (sk , & addr_l , & addr_r );
308343
309344 release_sock (sk );
310345
346+ spin_lock_bh (& msk -> pm .lock );
347+ if (err )
348+ mptcp_userspace_pm_delete_local_addr (msk , & local );
349+ else
350+ msk -> pm .subflows ++ ;
351+ spin_unlock_bh (& msk -> pm .lock );
352+
311353 create_err :
312354 sock_put ((struct sock * )msk );
313355 return err ;
@@ -420,7 +462,11 @@ int mptcp_nl_cmd_sf_destroy(struct sk_buff *skb, struct genl_info *info)
420462 ssk = mptcp_nl_find_ssk (msk , & addr_l , & addr_r );
421463 if (ssk ) {
422464 struct mptcp_subflow_context * subflow = mptcp_subflow_ctx (ssk );
465+ struct mptcp_pm_addr_entry entry = { .addr = addr_l };
423466
467+ spin_lock_bh (& msk -> pm .lock );
468+ mptcp_userspace_pm_delete_local_addr (msk , & entry );
469+ spin_unlock_bh (& msk -> pm .lock );
424470 mptcp_subflow_shutdown (sk , ssk , RCV_SHUTDOWN | SEND_SHUTDOWN );
425471 mptcp_close_ssk (sk , ssk , subflow );
426472 MPTCP_INC_STATS (sock_net (sk ), MPTCP_MIB_RMSUBFLOW );
0 commit comments