@@ -977,7 +977,7 @@ static void __mptcp_pm_release_addr_entry(struct mptcp_pm_addr_entry *entry)
977977
978978static int mptcp_pm_nl_append_new_local_addr (struct pm_nl_pernet * pernet ,
979979 struct mptcp_pm_addr_entry * entry ,
980- bool needs_id )
980+ bool needs_id , bool replace )
981981{
982982 struct mptcp_pm_addr_entry * cur , * del_entry = NULL ;
983983 unsigned int addr_max ;
@@ -1017,6 +1017,17 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
10171017 if (entry -> addr .id )
10181018 goto out ;
10191019
1020+ /* allow callers that only need to look up the local
1021+ * addr's id to skip replacement. This allows them to
1022+ * avoid calling synchronize_rcu in the packet recv
1023+ * path.
1024+ */
1025+ if (!replace ) {
1026+ kfree (entry );
1027+ ret = cur -> addr .id ;
1028+ goto out ;
1029+ }
1030+
10201031 pernet -> addrs -- ;
10211032 entry -> addr .id = cur -> addr .id ;
10221033 list_del_rcu (& cur -> list );
@@ -1165,7 +1176,7 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc
11651176 entry -> ifindex = 0 ;
11661177 entry -> flags = MPTCP_PM_ADDR_FLAG_IMPLICIT ;
11671178 entry -> lsk = NULL ;
1168- ret = mptcp_pm_nl_append_new_local_addr (pernet , entry , true);
1179+ ret = mptcp_pm_nl_append_new_local_addr (pernet , entry , true, false );
11691180 if (ret < 0 )
11701181 kfree (entry );
11711182
@@ -1440,7 +1451,8 @@ int mptcp_pm_nl_add_addr_doit(struct sk_buff *skb, struct genl_info *info)
14401451 }
14411452 }
14421453 ret = mptcp_pm_nl_append_new_local_addr (pernet , entry ,
1443- !mptcp_pm_has_addr_attr_id (attr , info ));
1454+ !mptcp_pm_has_addr_attr_id (attr , info ),
1455+ true);
14441456 if (ret < 0 ) {
14451457 GENL_SET_ERR_MSG_FMT (info , "too many addresses or duplicate one: %d" , ret );
14461458 goto out_free ;
0 commit comments