@@ -26,6 +26,7 @@ struct mptcp_pm_addr_entry {
26
26
struct list_head list ;
27
27
struct mptcp_addr_info addr ;
28
28
struct rcu_head rcu ;
29
+ struct socket * lsk ;
29
30
};
30
31
31
32
struct mptcp_pm_add_entry {
@@ -678,6 +679,53 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
678
679
return ret ;
679
680
}
680
681
682
+ static int mptcp_pm_nl_create_listen_socket (struct sock * sk ,
683
+ struct mptcp_pm_addr_entry * entry )
684
+ {
685
+ struct sockaddr_storage addr ;
686
+ struct mptcp_sock * msk ;
687
+ struct socket * ssock ;
688
+ int backlog = 1024 ;
689
+ int err ;
690
+
691
+ err = sock_create_kern (sock_net (sk ), entry -> addr .family ,
692
+ SOCK_STREAM , IPPROTO_MPTCP , & entry -> lsk );
693
+ if (err )
694
+ return err ;
695
+
696
+ msk = mptcp_sk (entry -> lsk -> sk );
697
+ if (!msk ) {
698
+ err = - EINVAL ;
699
+ goto out ;
700
+ }
701
+
702
+ ssock = __mptcp_nmpc_socket (msk );
703
+ if (!ssock ) {
704
+ err = - EINVAL ;
705
+ goto out ;
706
+ }
707
+
708
+ mptcp_info2sockaddr (& entry -> addr , & addr , entry -> addr .family );
709
+ err = kernel_bind (ssock , (struct sockaddr * )& addr ,
710
+ sizeof (struct sockaddr_in ));
711
+ if (err ) {
712
+ pr_warn ("kernel_bind error, err=%d" , err );
713
+ goto out ;
714
+ }
715
+
716
+ err = kernel_listen (ssock , backlog );
717
+ if (err ) {
718
+ pr_warn ("kernel_listen error, err=%d" , err );
719
+ goto out ;
720
+ }
721
+
722
+ return 0 ;
723
+
724
+ out :
725
+ sock_release (entry -> lsk );
726
+ return err ;
727
+ }
728
+
681
729
int mptcp_pm_nl_get_local_id (struct mptcp_sock * msk , struct sock_common * skc )
682
730
{
683
731
struct mptcp_pm_addr_entry * entry ;
@@ -722,6 +770,8 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
722
770
entry -> addr .ifindex = 0 ;
723
771
entry -> addr .flags = 0 ;
724
772
entry -> addr .id = 0 ;
773
+ entry -> addr .port = 0 ;
774
+ entry -> lsk = NULL ;
725
775
ret = mptcp_pm_nl_append_new_local_addr (pernet , entry );
726
776
if (ret < 0 )
727
777
kfree (entry );
@@ -891,9 +941,19 @@ static int mptcp_nl_cmd_add_addr(struct sk_buff *skb, struct genl_info *info)
891
941
}
892
942
893
943
* entry = addr ;
944
+ if (entry -> addr .port ) {
945
+ ret = mptcp_pm_nl_create_listen_socket (skb -> sk , entry );
946
+ if (ret ) {
947
+ GENL_SET_ERR_MSG (info , "create listen socket error" );
948
+ kfree (entry );
949
+ return ret ;
950
+ }
951
+ }
894
952
ret = mptcp_pm_nl_append_new_local_addr (pernet , entry );
895
953
if (ret < 0 ) {
896
954
GENL_SET_ERR_MSG (info , "too many addresses or duplicate one" );
955
+ if (entry -> lsk )
956
+ sock_release (entry -> lsk );
897
957
kfree (entry );
898
958
return ret ;
899
959
}
@@ -977,6 +1037,38 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
977
1037
return 0 ;
978
1038
}
979
1039
1040
+ struct addr_entry_release_work {
1041
+ struct rcu_work rwork ;
1042
+ struct mptcp_pm_addr_entry * entry ;
1043
+ };
1044
+
1045
+ static void mptcp_pm_release_addr_entry (struct work_struct * work )
1046
+ {
1047
+ struct addr_entry_release_work * w ;
1048
+ struct mptcp_pm_addr_entry * entry ;
1049
+
1050
+ w = container_of (to_rcu_work (work ), struct addr_entry_release_work , rwork );
1051
+ entry = w -> entry ;
1052
+ if (entry ) {
1053
+ if (entry -> lsk )
1054
+ sock_release (entry -> lsk );
1055
+ kfree (entry );
1056
+ }
1057
+ kfree (w );
1058
+ }
1059
+
1060
+ static void mptcp_pm_free_addr_entry (struct mptcp_pm_addr_entry * entry )
1061
+ {
1062
+ struct addr_entry_release_work * w ;
1063
+
1064
+ w = kmalloc (sizeof (* w ), GFP_ATOMIC );
1065
+ if (w ) {
1066
+ INIT_RCU_WORK (& w -> rwork , mptcp_pm_release_addr_entry );
1067
+ w -> entry = entry ;
1068
+ queue_rcu_work (system_wq , & w -> rwork );
1069
+ }
1070
+ }
1071
+
980
1072
static int mptcp_nl_cmd_del_addr (struct sk_buff * skb , struct genl_info * info )
981
1073
{
982
1074
struct nlattr * attr = info -> attrs [MPTCP_PM_ATTR_ADDR ];
@@ -1011,7 +1103,7 @@ static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info)
1011
1103
spin_unlock_bh (& pernet -> lock );
1012
1104
1013
1105
mptcp_nl_remove_subflow_and_signal_addr (sock_net (skb -> sk ), & entry -> addr );
1014
- kfree_rcu (entry , rcu );
1106
+ mptcp_pm_free_addr_entry (entry );
1015
1107
1016
1108
return ret ;
1017
1109
}
@@ -1025,7 +1117,7 @@ static void __flush_addrs(struct net *net, struct list_head *list)
1025
1117
struct mptcp_pm_addr_entry , list );
1026
1118
mptcp_nl_remove_subflow_and_signal_addr (net , & cur -> addr );
1027
1119
list_del_rcu (& cur -> list );
1028
- kfree_rcu (cur , rcu );
1120
+ mptcp_pm_free_addr_entry (cur );
1029
1121
}
1030
1122
}
1031
1123
0 commit comments