@@ -3251,3 +3251,122 @@ int rdma_query_addrinfo(struct rdma_cm_id *id, struct rdma_addrinfo **info)
3251
3251
pthread_mutex_unlock (& id_priv -> mut );
3252
3252
return 0 ;
3253
3253
}
3254
+
3255
+ static int resolve_sa_on_gid (union ibv_gid * gid , struct rdma_event_channel * ech ,
3256
+ const char * service , struct rdma_addrinfo * * res )
3257
+ {
3258
+ struct sockaddr_ib sib = {}, * psib ;
3259
+ struct cma_id_private * id_priv ;
3260
+ struct rdma_cm_id * cm_id ;
3261
+ struct rdma_addrinfo * ai ;
3262
+ struct rdma_cm_event * e ;
3263
+ int ret ;
3264
+
3265
+ ret = rdma_create_id (ech , & cm_id , NULL , RDMA_PS_IB );
3266
+ if (ret )
3267
+ return ret ;
3268
+
3269
+ sib .sib_family = AF_IB ;
3270
+ memcpy (& sib .sib_addr , gid , sizeof (sib .sib_addr ));
3271
+ ret = rdma_bind_addr (cm_id , (struct sockaddr * )& sib );
3272
+ if (ret )
3273
+ goto out ;
3274
+
3275
+ id_priv = container_of (cm_id , struct cma_id_private , id );
3276
+ ret = resolve_ai_sa (id_priv , service );
3277
+ if (ret )
3278
+ goto out ;
3279
+
3280
+ ret = rdma_get_cm_event (ech , & e );
3281
+ if (ret ) {
3282
+ rdma_ack_cm_event (e );
3283
+ goto out ;
3284
+ }
3285
+ if (e -> event != RDMA_CM_EVENT_ADDRINFO_RESOLVED ) {
3286
+ rdma_ack_cm_event (e );
3287
+ ret = ENOENT ;
3288
+ goto out ;
3289
+ }
3290
+
3291
+ rdma_ack_cm_event (e );
3292
+
3293
+ ai = id_priv -> resolved_ai ;
3294
+ while (ai ) {
3295
+ psib = calloc (1 , sizeof (* psib ));
3296
+ if (!psib ) {
3297
+ ret = errno ;
3298
+ goto out ;
3299
+ }
3300
+
3301
+ psib -> sib_family = AF_IB ;
3302
+ memcpy (& psib -> sib_addr , gid , sizeof (psib -> sib_addr ));
3303
+ ucma_set_sid (RDMA_PS_IB , NULL , psib );
3304
+ psib -> sib_pkey =
3305
+ ((struct sockaddr_ib * )ai -> ai_dst_addr )-> sib_pkey ;
3306
+
3307
+ ai -> ai_src_addr = (struct sockaddr * )psib ;
3308
+ ai -> ai_src_len = sizeof (* psib );
3309
+ ai = ai -> ai_next ;
3310
+ }
3311
+
3312
+ * res = id_priv -> resolved_ai ;
3313
+ id_priv -> resolved_ai = NULL ;
3314
+ out :
3315
+ rdma_destroy_id (cm_id );
3316
+ return ret ;
3317
+ }
3318
+
3319
+ int ucma_getaddrinfo_sa (const char * service , struct rdma_addrinfo * * res )
3320
+ {
3321
+ struct ibv_device_attr dev_attr = {};
3322
+ struct ibv_port_attr port_attr = {};
3323
+ struct rdma_event_channel * ech ;
3324
+ struct ibv_context * ibctx ;
3325
+ int i , j , ret , found = 0 ;
3326
+ union ibv_gid gid ;
3327
+
3328
+ if (!service || !res )
3329
+ return ERR (EINVAL );
3330
+
3331
+ ech = rdma_create_event_channel ();
3332
+ if (!ech )
3333
+ return -1 ;
3334
+
3335
+ for (i = 0 ; dev_list [i ] != NULL ; i ++ ) {
3336
+ ibctx = ibv_open_device (dev_list [i ]);
3337
+ if (!ibctx )
3338
+ continue ;
3339
+
3340
+ ret = ibv_query_device (ibctx , & dev_attr );
3341
+ if (ret )
3342
+ goto next ;
3343
+
3344
+ for (j = 0 ; j < dev_attr .phys_port_cnt ; j ++ ) {
3345
+ ret = ibv_query_port (ibctx , j + 1 , & port_attr );
3346
+ if (ret )
3347
+ continue ;
3348
+
3349
+ if ((port_attr .link_layer != IBV_LINK_LAYER_INFINIBAND ) ||
3350
+ (port_attr .state < IBV_PORT_ACTIVE ))
3351
+ continue ;
3352
+
3353
+ ret = ibv_query_gid (ibctx , j + 1 , 0 , & gid );
3354
+ if (ret )
3355
+ continue ;
3356
+
3357
+ ret = resolve_sa_on_gid (& gid , ech , service , res );
3358
+ if (!ret ) {
3359
+ found = 1 ;
3360
+ break ;
3361
+ }
3362
+ }
3363
+
3364
+ next :
3365
+ ibv_close_device (ibctx );
3366
+ if (found )
3367
+ break ;
3368
+ }
3369
+
3370
+ rdma_destroy_event_channel (ech );
3371
+ return found ? 0 : ERR (ENOENT );
3372
+ }
0 commit comments