@@ -717,34 +717,40 @@ void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk)
717717 }
718718}
719719
720- static int mptcp_pm_nl_mp_prio_send_ack (struct mptcp_sock * msk ,
721- struct mptcp_addr_info * addr ,
722- u8 bkup )
720+ int mptcp_pm_nl_mp_prio_send_ack (struct mptcp_sock * msk ,
721+ struct mptcp_addr_info * addr ,
722+ struct mptcp_addr_info * rem ,
723+ u8 bkup )
723724{
724725 struct mptcp_subflow_context * subflow ;
725726
726727 pr_debug ("bkup=%d" , bkup );
727728
728729 mptcp_for_each_subflow (msk , subflow ) {
729730 struct sock * ssk = mptcp_subflow_tcp_sock (subflow );
730- struct sock * sk = ( struct sock * ) msk ;
731- struct mptcp_addr_info local ;
731+ struct mptcp_addr_info local , remote ;
732+ bool slow ;
732733
733734 local_address ((struct sock_common * )ssk , & local );
734735 if (!mptcp_addresses_equal (& local , addr , addr -> port ))
735736 continue ;
736737
738+ if (rem && rem -> family != AF_UNSPEC ) {
739+ remote_address ((struct sock_common * )ssk , & remote );
740+ if (!mptcp_addresses_equal (& remote , rem , rem -> port ))
741+ continue ;
742+ }
743+
744+ slow = lock_sock_fast (ssk );
737745 if (subflow -> backup != bkup )
738746 msk -> last_snd = NULL ;
739747 subflow -> backup = bkup ;
740748 subflow -> send_mp_prio = 1 ;
741749 subflow -> request_bkup = bkup ;
742- __MPTCP_INC_STATS (sock_net (sk ), MPTCP_MIB_MPPRIOTX );
743750
744- spin_unlock_bh (& msk -> pm .lock );
745751 pr_debug ("send ack for mp_prio" );
746- mptcp_subflow_send_ack (ssk );
747- spin_lock_bh ( & msk -> pm . lock );
752+ __mptcp_subflow_send_ack (ssk );
753+ unlock_sock_fast ( ssk , slow );
748754
749755 return 0 ;
750756 }
@@ -801,7 +807,8 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
801807 removed = true;
802808 __MPTCP_INC_STATS (sock_net (sk ), rm_type );
803809 }
804- __set_bit (rm_list -> ids [i ], msk -> pm .id_avail_bitmap );
810+ if (rm_type == MPTCP_MIB_RMSUBFLOW )
811+ __set_bit (rm_list -> ids [i ], msk -> pm .id_avail_bitmap );
805812 if (!removed )
806813 continue ;
807814
@@ -1816,8 +1823,10 @@ static void mptcp_pm_nl_fullmesh(struct mptcp_sock *msk,
18161823
18171824 list .ids [list .nr ++ ] = addr -> id ;
18181825
1826+ spin_lock_bh (& msk -> pm .lock );
18191827 mptcp_pm_nl_rm_subflow_received (msk , & list );
18201828 mptcp_pm_create_subflow_or_signal_addr (msk );
1829+ spin_unlock_bh (& msk -> pm .lock );
18211830}
18221831
18231832static int mptcp_nl_set_flags (struct net * net ,
@@ -1835,12 +1844,10 @@ static int mptcp_nl_set_flags(struct net *net,
18351844 goto next ;
18361845
18371846 lock_sock (sk );
1838- spin_lock_bh (& msk -> pm .lock );
18391847 if (changed & MPTCP_PM_ADDR_FLAG_BACKUP )
1840- ret = mptcp_pm_nl_mp_prio_send_ack (msk , addr , bkup );
1848+ ret = mptcp_pm_nl_mp_prio_send_ack (msk , addr , NULL , bkup );
18411849 if (changed & MPTCP_PM_ADDR_FLAG_FULLMESH )
18421850 mptcp_pm_nl_fullmesh (msk , addr );
1843- spin_unlock_bh (& msk -> pm .lock );
18441851 release_sock (sk );
18451852
18461853next :
@@ -1854,6 +1861,9 @@ static int mptcp_nl_set_flags(struct net *net,
18541861static int mptcp_nl_cmd_set_flags (struct sk_buff * skb , struct genl_info * info )
18551862{
18561863 struct mptcp_pm_addr_entry addr = { .addr = { .family = AF_UNSPEC }, }, * entry ;
1864+ struct mptcp_pm_addr_entry remote = { .addr = { .family = AF_UNSPEC }, };
1865+ struct nlattr * attr_rem = info -> attrs [MPTCP_PM_ATTR_ADDR_REMOTE ];
1866+ struct nlattr * token = info -> attrs [MPTCP_PM_ATTR_TOKEN ];
18571867 struct nlattr * attr = info -> attrs [MPTCP_PM_ATTR_ADDR ];
18581868 struct pm_nl_pernet * pernet = genl_info_pm_nl (info );
18591869 u8 changed , mask = MPTCP_PM_ADDR_FLAG_BACKUP |
@@ -1866,6 +1876,12 @@ static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info)
18661876 if (ret < 0 )
18671877 return ret ;
18681878
1879+ if (attr_rem ) {
1880+ ret = mptcp_pm_parse_entry (attr_rem , info , false, & remote );
1881+ if (ret < 0 )
1882+ return ret ;
1883+ }
1884+
18691885 if (addr .flags & MPTCP_PM_ADDR_FLAG_BACKUP )
18701886 bkup = 1 ;
18711887 if (addr .addr .family == AF_UNSPEC ) {
@@ -1874,6 +1890,10 @@ static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info)
18741890 return - EOPNOTSUPP ;
18751891 }
18761892
1893+ if (token )
1894+ return mptcp_userspace_pm_set_flags (sock_net (skb -> sk ),
1895+ token , & addr , & remote , bkup );
1896+
18771897 spin_lock_bh (& pernet -> lock );
18781898 entry = __lookup_addr (pernet , & addr .addr , lookup_by_id );
18791899 if (!entry ) {
0 commit comments