Skip to content

Commit add369c

Browse files
MarkZhang81shefty
authored andcommitted
librdmacm: Support IB SA resolve in rdma_getaddrinfo()
Allow rdma_getaddrinfo() to support IB SA resolve when RAI_SA flag is set in the hints. It resolves the requested IB service on all IB ports one by one, and returns on the first successful resolve. Signed-off-by: Mark Zhang <[email protected]>
1 parent 8ae785a commit add369c

File tree

3 files changed

+127
-0
lines changed

3 files changed

+127
-0
lines changed

librdmacm/addrinfo.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,13 @@ int rdma_getaddrinfo(const char *node, const char *service,
248248
if (ret)
249249
return ret;
250250

251+
if (hints && hints->ai_flags & RAI_SA) {
252+
if (node || (hints->ai_flags & RAI_DNS))
253+
return ERR(EOPNOTSUPP);
254+
255+
return ucma_getaddrinfo_sa(service, res);
256+
}
257+
251258
rai = calloc(1, sizeof(*rai));
252259
if (!rai)
253260
return ERR(ENOMEM);

librdmacm/cma.c

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3251,3 +3251,122 @@ int rdma_query_addrinfo(struct rdma_cm_id *id, struct rdma_addrinfo **info)
32513251
pthread_mutex_unlock(&id_priv->mut);
32523252
return 0;
32533253
}
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+
}

librdmacm/cma.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,5 @@ struct ib_connect_hdr {
114114
#define cma_dst_ip6 dst_addr[0]
115115
};
116116

117+
int ucma_getaddrinfo_sa(const char *service, struct rdma_addrinfo **res);
117118
#endif /* CMA_H */

0 commit comments

Comments
 (0)