If IB ACM route resolution succeeds, provide the user with AF_IB addresses, rather than AF_INET or AF_INET6 addressing. AF_IB identifies the local and remote devices directly, eliminating the need to perform address resolution a second time via rdma_resolve_addr.
AF_IB addresses are returned using sockaddr_ib as part of rdma_getaddrinfo. Signed-off-by: Sean Hefty <[email protected]> --- src/acm.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/cma.h | 1 + 2 files changed, 66 insertions(+), 0 deletions(-) diff --git a/src/acm.c b/src/acm.c index 34fdf3c..5dd8899 100644 --- a/src/acm.c +++ b/src/acm.c @@ -83,9 +83,69 @@ void ucma_ib_cleanup(void) } } +static void ucma_set_sid(enum rdma_port_space ps, struct sockaddr *addr, + struct sockaddr_ib *sib) +{ + uint16_t port; + + if (addr->sa_family == AF_INET) + port = ((struct sockaddr_in *) addr)->sin_port; + else + port = ((struct sockaddr_in6 *) addr)->sin6_port; + + sib->sib_sid = htonll(((uint64_t) ps << 16) + ntohs(port)); + if (port) + sib->sib_sid_mask = ~0ULL; + else + sib->sib_sid_mask = htonll(RDMA_IB_IP_PS_MASK); +} + +static void ucma_ib_convert_addr(struct rdma_addrinfo *rai, + struct ib_path_record *path) +{ + struct sockaddr_ib *src, *dst; + + if (!path) + return; + + src = zalloc(sizeof *src); + if (!src) + return; + + dst = zalloc(sizeof *dst); + if (!dst) { + free(src); + return; + } + + src->sib_family = AF_IB; + src->sib_pkey = path->pkey; + src->sib_flowinfo = htonl(ntohl(path->flowlabel_hoplimit) >> 8); + memcpy(&src->sib_addr, &path->sgid, 16); + ucma_set_sid(rai->ai_port_space, rai->ai_src_addr, src); + + dst->sib_family = AF_IB; + dst->sib_pkey = path->pkey; + dst->sib_flowinfo = htonl(ntohl(path->flowlabel_hoplimit) >> 8); + memcpy(&dst->sib_addr, &path->dgid, 16); + ucma_set_sid(rai->ai_port_space, rai->ai_dst_addr, dst); + + free(rai->ai_src_addr); + rai->ai_src_addr = (struct sockaddr *) src; + rai->ai_src_len = sizeof(*src); + + free(rai->ai_dst_addr); + rai->ai_dst_addr = (struct sockaddr *) dst; + rai->ai_dst_len = sizeof(*dst); + + rai->ai_family = AF_IB; + rai->ai_port_space = RDMA_PS_IB; +} + static void ucma_ib_save_resp(struct rdma_addrinfo *rai, struct acm_resolve_msg *msg) { struct ib_path_data *path_data = NULL; + struct ib_path_record *pri_path; int len, i, cnt; len = msg->hdr.length - ACM_MSG_HDR_LENGTH; @@ -98,11 +158,16 @@ static void ucma_ib_save_resp(struct rdma_addrinfo *rai, struct acm_resolve_msg for (i = 0; i < cnt; i++) { if (msg->data[i].type != ACM_EP_INFO_PATH) goto err; + if (path_data[i].flags | + (IB_PATH_FLAG_PRIMARY | IB_PATH_FLAG_OUTBOUND)) + pri_path = &path_data[i].path; path_data[i].reserved = 0; } rai->ai_route = path_data; rai->ai_route_len = len; + if (af_ib_support) + ucma_ib_convert_addr(rai, pri_path); return; err: free(path_data); diff --git a/src/cma.h b/src/cma.h index 62785de..1e0c571 100644 --- a/src/cma.h +++ b/src/cma.h @@ -85,6 +85,7 @@ static inline void *zalloc(size_t size) } int ucma_init(); +extern int af_ib_support; #ifdef USE_IB_ACM void ucma_ib_init(); -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
