@@ -438,6 +438,61 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv)
438
438
return ret ;
439
439
}
440
440
441
+ /*
442
+ * Select the source IB device and address to reach the destination IB address.
443
+ */
444
+ static int cma_resolve_ib_dev (struct rdma_id_private * id_priv )
445
+ {
446
+ struct cma_device * cma_dev , * cur_dev ;
447
+ struct sockaddr_ib * addr ;
448
+ union ib_gid gid , sgid , * dgid ;
449
+ u16 pkey , index ;
450
+ u8 port , p ;
451
+ int i ;
452
+
453
+ cma_dev = NULL ;
454
+ addr = (struct sockaddr_ib * ) cma_dst_addr (id_priv );
455
+ dgid = (union ib_gid * ) & addr -> sib_addr ;
456
+ pkey = ntohs (addr -> sib_pkey );
457
+
458
+ list_for_each_entry (cur_dev , & dev_list , list ) {
459
+ if (rdma_node_get_transport (cur_dev -> device -> node_type ) != RDMA_TRANSPORT_IB )
460
+ continue ;
461
+
462
+ for (p = 1 ; p <= cur_dev -> device -> phys_port_cnt ; ++ p ) {
463
+ if (ib_find_cached_pkey (cur_dev -> device , p , pkey , & index ))
464
+ continue ;
465
+
466
+ for (i = 0 ; !ib_get_cached_gid (cur_dev -> device , p , i , & gid ); i ++ ) {
467
+ if (!memcmp (& gid , dgid , sizeof (gid ))) {
468
+ cma_dev = cur_dev ;
469
+ sgid = gid ;
470
+ port = p ;
471
+ goto found ;
472
+ }
473
+
474
+ if (!cma_dev && (gid .global .subnet_prefix ==
475
+ dgid -> global .subnet_prefix )) {
476
+ cma_dev = cur_dev ;
477
+ sgid = gid ;
478
+ port = p ;
479
+ }
480
+ }
481
+ }
482
+ }
483
+
484
+ if (!cma_dev )
485
+ return - ENODEV ;
486
+
487
+ found :
488
+ cma_attach_to_dev (id_priv , cma_dev );
489
+ id_priv -> id .port_num = port ;
490
+ addr = (struct sockaddr_ib * ) cma_src_addr (id_priv );
491
+ memcpy (& addr -> sib_addr , & sgid , sizeof sgid );
492
+ cma_translate_ib (addr , & id_priv -> id .route .addr .dev_addr );
493
+ return 0 ;
494
+ }
495
+
441
496
static void cma_deref_id (struct rdma_id_private * id_priv )
442
497
{
443
498
if (atomic_dec_and_test (& id_priv -> refcount ))
@@ -2101,14 +2156,48 @@ static int cma_resolve_loopback(struct rdma_id_private *id_priv)
2101
2156
return ret ;
2102
2157
}
2103
2158
2159
+ static int cma_resolve_ib_addr (struct rdma_id_private * id_priv )
2160
+ {
2161
+ struct cma_work * work ;
2162
+ int ret ;
2163
+
2164
+ work = kzalloc (sizeof * work , GFP_KERNEL );
2165
+ if (!work )
2166
+ return - ENOMEM ;
2167
+
2168
+ if (!id_priv -> cma_dev ) {
2169
+ ret = cma_resolve_ib_dev (id_priv );
2170
+ if (ret )
2171
+ goto err ;
2172
+ }
2173
+
2174
+ rdma_addr_set_dgid (& id_priv -> id .route .addr .dev_addr , (union ib_gid * )
2175
+ & (((struct sockaddr_ib * ) & id_priv -> id .route .addr .dst_addr )-> sib_addr ));
2176
+
2177
+ work -> id = id_priv ;
2178
+ INIT_WORK (& work -> work , cma_work_handler );
2179
+ work -> old_state = RDMA_CM_ADDR_QUERY ;
2180
+ work -> new_state = RDMA_CM_ADDR_RESOLVED ;
2181
+ work -> event .event = RDMA_CM_EVENT_ADDR_RESOLVED ;
2182
+ queue_work (cma_wq , & work -> work );
2183
+ return 0 ;
2184
+ err :
2185
+ kfree (work );
2186
+ return ret ;
2187
+ }
2188
+
2104
2189
static int cma_bind_addr (struct rdma_cm_id * id , struct sockaddr * src_addr ,
2105
2190
struct sockaddr * dst_addr )
2106
2191
{
2107
2192
if (!src_addr || !src_addr -> sa_family ) {
2108
2193
src_addr = (struct sockaddr * ) & id -> route .addr .src_addr ;
2109
- if ((src_addr -> sa_family = dst_addr -> sa_family ) == AF_INET6 ) {
2194
+ src_addr -> sa_family = dst_addr -> sa_family ;
2195
+ if (dst_addr -> sa_family == AF_INET6 ) {
2110
2196
((struct sockaddr_in6 * ) src_addr )-> sin6_scope_id =
2111
2197
((struct sockaddr_in6 * ) dst_addr )-> sin6_scope_id ;
2198
+ } else if (dst_addr -> sa_family == AF_IB ) {
2199
+ ((struct sockaddr_ib * ) src_addr )-> sib_pkey =
2200
+ ((struct sockaddr_ib * ) dst_addr )-> sib_pkey ;
2112
2201
}
2113
2202
}
2114
2203
return rdma_bind_addr (id , src_addr );
@@ -2135,12 +2224,17 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
2135
2224
2136
2225
atomic_inc (& id_priv -> refcount );
2137
2226
memcpy (cma_dst_addr (id_priv ), dst_addr , rdma_addr_size (dst_addr ));
2138
- if (cma_any_addr (dst_addr ))
2227
+ if (cma_any_addr (dst_addr )) {
2139
2228
ret = cma_resolve_loopback (id_priv );
2140
- else
2141
- ret = rdma_resolve_ip (& addr_client , cma_src_addr (id_priv ),
2142
- dst_addr , & id -> route .addr .dev_addr ,
2143
- timeout_ms , addr_handler , id_priv );
2229
+ } else {
2230
+ if (dst_addr -> sa_family == AF_IB ) {
2231
+ ret = cma_resolve_ib_addr (id_priv );
2232
+ } else {
2233
+ ret = rdma_resolve_ip (& addr_client , cma_src_addr (id_priv ),
2234
+ dst_addr , & id -> route .addr .dev_addr ,
2235
+ timeout_ms , addr_handler , id_priv );
2236
+ }
2237
+ }
2144
2238
if (ret )
2145
2239
goto err ;
2146
2240
0 commit comments