44
44
#include <linux/module.h>
45
45
#include <net/route.h>
46
46
47
+ #include <net/net_namespace.h>
48
+ #include <net/netns/generic.h>
47
49
#include <net/tcp.h>
48
50
#include <net/ipv6.h>
49
51
#include <net/ip_fib.h>
@@ -110,22 +112,33 @@ static LIST_HEAD(dev_list);
110
112
static LIST_HEAD (listen_any_list );
111
113
static DEFINE_MUTEX (lock );
112
114
static struct workqueue_struct * cma_wq ;
113
- static DEFINE_IDR (tcp_ps );
114
- static DEFINE_IDR (udp_ps );
115
- static DEFINE_IDR (ipoib_ps );
116
- static DEFINE_IDR (ib_ps );
115
+ static int cma_pernet_id ;
117
116
118
- static struct idr * cma_idr (enum rdma_port_space ps )
117
+ struct cma_pernet {
118
+ struct idr tcp_ps ;
119
+ struct idr udp_ps ;
120
+ struct idr ipoib_ps ;
121
+ struct idr ib_ps ;
122
+ };
123
+
124
+ static struct cma_pernet * cma_pernet (struct net * net )
125
+ {
126
+ return net_generic (net , cma_pernet_id );
127
+ }
128
+
129
+ static struct idr * cma_pernet_idr (struct net * net , enum rdma_port_space ps )
119
130
{
131
+ struct cma_pernet * pernet = cma_pernet (net );
132
+
120
133
switch (ps ) {
121
134
case RDMA_PS_TCP :
122
- return & tcp_ps ;
135
+ return & pernet -> tcp_ps ;
123
136
case RDMA_PS_UDP :
124
- return & udp_ps ;
137
+ return & pernet -> udp_ps ;
125
138
case RDMA_PS_IPOIB :
126
- return & ipoib_ps ;
139
+ return & pernet -> ipoib_ps ;
127
140
case RDMA_PS_IB :
128
- return & ib_ps ;
141
+ return & pernet -> ib_ps ;
129
142
default :
130
143
return NULL ;
131
144
}
@@ -145,24 +158,25 @@ struct rdma_bind_list {
145
158
unsigned short port ;
146
159
};
147
160
148
- static int cma_ps_alloc (enum rdma_port_space ps ,
161
+ static int cma_ps_alloc (struct net * net , enum rdma_port_space ps ,
149
162
struct rdma_bind_list * bind_list , int snum )
150
163
{
151
- struct idr * idr = cma_idr ( ps );
164
+ struct idr * idr = cma_pernet_idr ( net , ps );
152
165
153
166
return idr_alloc (idr , bind_list , snum , snum + 1 , GFP_KERNEL );
154
167
}
155
168
156
- static struct rdma_bind_list * cma_ps_find (enum rdma_port_space ps , int snum )
169
+ static struct rdma_bind_list * cma_ps_find (struct net * net ,
170
+ enum rdma_port_space ps , int snum )
157
171
{
158
- struct idr * idr = cma_idr ( ps );
172
+ struct idr * idr = cma_pernet_idr ( net , ps );
159
173
160
174
return idr_find (idr , snum );
161
175
}
162
176
163
- static void cma_ps_remove (enum rdma_port_space ps , int snum )
177
+ static void cma_ps_remove (struct net * net , enum rdma_port_space ps , int snum )
164
178
{
165
- struct idr * idr = cma_idr ( ps );
179
+ struct idr * idr = cma_pernet_idr ( net , ps );
166
180
167
181
idr_remove (idr , snum );
168
182
}
@@ -1325,7 +1339,8 @@ static struct rdma_id_private *cma_id_from_event(struct ib_cm_id *cm_id,
1325
1339
}
1326
1340
}
1327
1341
1328
- bind_list = cma_ps_find (rdma_ps_from_service_id (req .service_id ),
1342
+ bind_list = cma_ps_find (& init_net ,
1343
+ rdma_ps_from_service_id (req .service_id ),
1329
1344
cma_port_from_service_id (req .service_id ));
1330
1345
id_priv = cma_find_listener (bind_list , cm_id , ib_event , & req , * net_dev );
1331
1346
if (IS_ERR (id_priv ) && * net_dev ) {
@@ -1403,7 +1418,7 @@ static void cma_release_port(struct rdma_id_private *id_priv)
1403
1418
mutex_lock (& lock );
1404
1419
hlist_del (& id_priv -> node );
1405
1420
if (hlist_empty (& bind_list -> owners )) {
1406
- cma_ps_remove (bind_list -> ps , bind_list -> port );
1421
+ cma_ps_remove (& init_net , bind_list -> ps , bind_list -> port );
1407
1422
kfree (bind_list );
1408
1423
}
1409
1424
mutex_unlock (& lock );
@@ -2693,7 +2708,7 @@ static int cma_alloc_port(enum rdma_port_space ps,
2693
2708
if (!bind_list )
2694
2709
return - ENOMEM ;
2695
2710
2696
- ret = cma_ps_alloc (ps , bind_list , snum );
2711
+ ret = cma_ps_alloc (& init_net , ps , bind_list , snum );
2697
2712
if (ret < 0 )
2698
2713
goto err ;
2699
2714
@@ -2718,7 +2733,7 @@ static int cma_alloc_any_port(enum rdma_port_space ps,
2718
2733
rover = prandom_u32 () % remaining + low ;
2719
2734
retry :
2720
2735
if (last_used_port != rover &&
2721
- !cma_ps_find (ps , (unsigned short )rover )) {
2736
+ !cma_ps_find (& init_net , ps , (unsigned short )rover )) {
2722
2737
int ret = cma_alloc_port (ps , id_priv , rover );
2723
2738
/*
2724
2739
* Remember previously used port number in order to avoid
@@ -2784,7 +2799,7 @@ static int cma_use_port(enum rdma_port_space ps,
2784
2799
if (snum < PROT_SOCK && !capable (CAP_NET_BIND_SERVICE ))
2785
2800
return - EACCES ;
2786
2801
2787
- bind_list = cma_ps_find (ps , snum );
2802
+ bind_list = cma_ps_find (& init_net , ps , snum );
2788
2803
if (!bind_list ) {
2789
2804
ret = cma_alloc_port (ps , id_priv , snum );
2790
2805
} else {
@@ -4004,6 +4019,35 @@ static const struct ibnl_client_cbs cma_cb_table[] = {
4004
4019
.module = THIS_MODULE },
4005
4020
};
4006
4021
4022
+ static int cma_init_net (struct net * net )
4023
+ {
4024
+ struct cma_pernet * pernet = cma_pernet (net );
4025
+
4026
+ idr_init (& pernet -> tcp_ps );
4027
+ idr_init (& pernet -> udp_ps );
4028
+ idr_init (& pernet -> ipoib_ps );
4029
+ idr_init (& pernet -> ib_ps );
4030
+
4031
+ return 0 ;
4032
+ }
4033
+
4034
+ static void cma_exit_net (struct net * net )
4035
+ {
4036
+ struct cma_pernet * pernet = cma_pernet (net );
4037
+
4038
+ idr_destroy (& pernet -> tcp_ps );
4039
+ idr_destroy (& pernet -> udp_ps );
4040
+ idr_destroy (& pernet -> ipoib_ps );
4041
+ idr_destroy (& pernet -> ib_ps );
4042
+ }
4043
+
4044
+ static struct pernet_operations cma_pernet_operations = {
4045
+ .init = cma_init_net ,
4046
+ .exit = cma_exit_net ,
4047
+ .id = & cma_pernet_id ,
4048
+ .size = sizeof (struct cma_pernet ),
4049
+ };
4050
+
4007
4051
static int __init cma_init (void )
4008
4052
{
4009
4053
int ret ;
@@ -4012,6 +4056,10 @@ static int __init cma_init(void)
4012
4056
if (!cma_wq )
4013
4057
return - ENOMEM ;
4014
4058
4059
+ ret = register_pernet_subsys (& cma_pernet_operations );
4060
+ if (ret )
4061
+ goto err_wq ;
4062
+
4015
4063
ib_sa_register_client (& sa_client );
4016
4064
rdma_addr_register_client (& addr_client );
4017
4065
register_netdevice_notifier (& cma_nb );
@@ -4029,6 +4077,7 @@ static int __init cma_init(void)
4029
4077
unregister_netdevice_notifier (& cma_nb );
4030
4078
rdma_addr_unregister_client (& addr_client );
4031
4079
ib_sa_unregister_client (& sa_client );
4080
+ err_wq :
4032
4081
destroy_workqueue (cma_wq );
4033
4082
return ret ;
4034
4083
}
@@ -4040,11 +4089,8 @@ static void __exit cma_cleanup(void)
4040
4089
unregister_netdevice_notifier (& cma_nb );
4041
4090
rdma_addr_unregister_client (& addr_client );
4042
4091
ib_sa_unregister_client (& sa_client );
4092
+ unregister_pernet_subsys (& cma_pernet_operations );
4043
4093
destroy_workqueue (cma_wq );
4044
- idr_destroy (& tcp_ps );
4045
- idr_destroy (& udp_ps );
4046
- idr_destroy (& ipoib_ps );
4047
- idr_destroy (& ib_ps );
4048
4094
}
4049
4095
4050
4096
module_init (cma_init );
0 commit comments