36
36
#include <asm-generic/sizes.h>
37
37
#include <rdma/rdma_cm_ib.h>
38
38
#include <rdma/ib_cache.h>
39
+ #include <rdma/ib_cm.h>
39
40
40
41
#include "rds.h"
41
42
#include "ib.h"
@@ -192,6 +193,54 @@ static inline void rds_ib_init_ic_frag(struct rds_ib_connection *ic)
192
193
ic -> i_frag_sz = ib_init_frag_size ;
193
194
}
194
195
196
+ /*
197
+ * 0 - all good
198
+ * 1 - acl is not enabled
199
+ * -1 - acl match failed
200
+ */
201
+ static int rds_ib_match_acl (struct rdma_cm_id * cm_id , __be32 saddr )
202
+ {
203
+ struct ib_cm_acl * acl = 0 ;
204
+ struct ib_cm_acl_elem * acl_elem = 0 ;
205
+ __be64 fguid = cm_id -> route .path_rec -> dgid .global .interface_id ;
206
+ __be64 fsubnet = cm_id -> route .path_rec -> dgid .global .subnet_prefix ;
207
+ struct ib_cm_dpp dpp ;
208
+ u32 addr ;
209
+
210
+ ib_cm_dpp_init (& dpp , cm_id -> device , cm_id -> port_num ,
211
+ ntohs (cm_id -> route .path_rec -> pkey ));
212
+ acl = ib_cm_dpp_acl_lookup (& dpp );
213
+ if (!acl )
214
+ goto out ;
215
+
216
+ if (!acl -> enabled )
217
+ return 0 ;
218
+
219
+ acl_elem = ib_cm_acl_lookup (acl , be64_to_cpu (fsubnet ),
220
+ be64_to_cpu (fguid ));
221
+ if (!acl_elem ) {
222
+ pr_err_ratelimited ("RDS/IB: GUID ib_cm_acl_lookup() failed\n" );
223
+ goto out ;
224
+ }
225
+
226
+ addr = be32_to_cpu (saddr );
227
+ if (!addr )
228
+ goto out ;
229
+
230
+ acl_elem = ib_cm_acl_lookup_uuid_ip (acl , acl_elem -> uuid , addr );
231
+ if (!acl_elem ) {
232
+ pr_err_ratelimited ("RDS/IB: IP %pI4 ib_cm_acl_lookup_uuid_ip() failed\n" ,
233
+ & saddr );
234
+ goto out ;
235
+ }
236
+
237
+ return 1 ;
238
+ out :
239
+ pr_err_ratelimited ("RDS/IB: %s failed due to ACLs. Check ACLs\n" ,
240
+ __func__ );
241
+ return -1 ;
242
+ }
243
+
195
244
/*
196
245
* Connection established.
197
246
* We get here for both outgoing and incoming connection.
@@ -231,13 +280,14 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even
231
280
}
232
281
}
233
282
234
- printk (KERN_NOTICE "RDS/IB: %s conn %p i_cm_id %p, frag %dKB, connected <%pI4,%pI4,%d> version %u.%u%s\n" ,
283
+ printk (KERN_NOTICE "RDS/IB: %s conn %p i_cm_id %p, frag %dKB, connected <%pI4,%pI4,%d> version %u.%u%s%s \n" ,
235
284
ic -> i_active_side ? "Active " : "Passive" ,
236
285
conn , ic -> i_cm_id , ic -> i_frag_sz / SZ_1K ,
237
286
& conn -> c_laddr , & conn -> c_faddr , conn -> c_tos ,
238
287
RDS_PROTOCOL_MAJOR (conn -> c_version ),
239
288
RDS_PROTOCOL_MINOR (conn -> c_version ),
240
- ic -> i_flowctl ? ", flow control" : "" );
289
+ ic -> i_flowctl ? ", flow control" : "" ,
290
+ conn -> c_acl_en ? ", ACL Enabled" : "" );
241
291
242
292
/* The connection might have been dropped under us*/
243
293
if (!ic -> i_cm_id ) {
@@ -822,6 +872,7 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
822
872
struct rdma_conn_param conn_param ;
823
873
u32 version ;
824
874
int err = 1 , destroy = 1 ;
875
+ int acl_ret = 0 ;
825
876
826
877
/* Check whether the remote protocol version matches ours. */
827
878
version = rds_ib_protocol_compatible (event );
@@ -837,6 +888,13 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
837
888
(unsigned long long )be64_to_cpu (fguid ),
838
889
dp -> dp_tos );
839
890
891
+ acl_ret = rds_ib_match_acl (cm_id , dp -> dp_saddr );
892
+ if (acl_ret < 0 ) {
893
+ rdma_reject (cm_id , & acl_ret , sizeof (int ));
894
+ rdsdebug ("RDS: IB: rds_ib_match_acl failed\n" );
895
+ goto out ;
896
+ }
897
+
840
898
/* RDS/IB is not currently netns aware, thus init_net */
841
899
conn = rds_conn_create (& init_net , dp -> dp_daddr , dp -> dp_saddr ,
842
900
& rds_ib_transport , dp -> dp_tos , GFP_KERNEL );
@@ -850,6 +908,9 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
850
908
rds_ib_set_protocol (conn , version );
851
909
rds_ib_set_frag_size (conn , be16_to_cpu (dp -> dp_frag_sz ));
852
910
911
+ conn -> c_acl_en = acl_ret ;
912
+ conn -> c_acl_init = 1 ;
913
+
853
914
if (dp -> dp_tos && !conn -> c_base_conn ) {
854
915
conn -> c_base_conn = rds_conn_create (& init_net ,
855
916
dp -> dp_daddr , dp -> dp_saddr ,
@@ -1019,6 +1080,18 @@ int rds_ib_cm_initiate_connect(struct rdma_cm_id *cm_id)
1019
1080
struct rds_ib_connect_private dp ;
1020
1081
int ret ;
1021
1082
1083
+ ret = rds_ib_match_acl (ic -> i_cm_id , conn -> c_faddr );
1084
+ if (ret < 0 ) {
1085
+ pr_err ("RDS: IB: active conn=%p, <%u.%u.%u.%u,%u.%u.%u.%u,%d> destroyed due ACL violation\n" ,
1086
+ conn , NIPQUAD (conn -> c_laddr ), NIPQUAD (conn -> c_faddr ),
1087
+ conn -> c_tos );
1088
+ rds_ib_conn_destroy_init (conn );
1089
+ return 0 ;
1090
+ }
1091
+
1092
+ conn -> c_acl_en = ret ;
1093
+ conn -> c_acl_init = 1 ;
1094
+
1022
1095
rds_ib_set_protocol (conn , RDS_PROTOCOL_4_1 );
1023
1096
ic -> i_flowctl = rds_ib_sysctl_flow_control ; /* advertise flow control */
1024
1097
/* Use ic->i_flowctl as the first post credit to enable
0 commit comments