/*
- * Copyright (c) 2010 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010-2012 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
}
}
-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 int ucma_ib_set_addr(struct rdma_addrinfo *ib_rai,
struct rdma_addrinfo *rai)
{
{
struct ib_connect_hdr *hdr;
+ if (rai->ai_family == AF_IB)
+ return 0;
+
hdr = calloc(1, sizeof *hdr);
if (!hdr)
return ERR(ENOMEM);
if (ucma_inet_addr((*rai)->ai_dst_addr, (*rai)->ai_dst_len)) {
data->flags = ACM_EP_FLAG_DEST;
- if ((*rai)->ai_flags & (RAI_NUMERICHOST | RAI_NOROUTE))
+ if (hints->ai_flags & (RAI_NUMERICHOST | RAI_NOROUTE))
data->flags |= ACM_FLAGS_NODELAY;
ucma_set_ep_addr(data, (*rai)->ai_dst_addr);
data++;
msg.hdr.length += ACM_MSG_EP_LENGTH;
}
- if (hints && (hints->ai_route_len ||
+ if (hints->ai_route_len ||
ucma_ib_addr((*rai)->ai_src_addr, (*rai)->ai_src_len) ||
- ucma_ib_addr((*rai)->ai_dst_addr, (*rai)->ai_dst_len))) {
+ ucma_ib_addr((*rai)->ai_dst_addr, (*rai)->ai_dst_len)) {
struct ibv_path_record *path;
if (hints->ai_route_len == sizeof(struct ibv_path_record))
ucma_ib_save_resp(*rai, &msg);
- if (af_ib_support && !((*rai)->ai_flags & RAI_ROUTEONLY) &&
- (*rai)->ai_route_len && ((*rai)->ai_family != AF_IB))
+ if (af_ib_support && !(hints->ai_flags & RAI_ROUTEONLY) && (*rai)->ai_route_len)
ucma_resolve_af_ib(rai);
}
#define RDMA_QPT_XRC_RECV 10
#endif
+struct rdma_addrinfo nohints;
+
static void ucma_convert_to_ai(struct addrinfo *ai, struct rdma_addrinfo *rai)
{
memset(ai, 0, sizeof *ai);
- ai->ai_flags = (rai->ai_flags & RAI_PASSIVE) ? AI_PASSIVE : 0;
- ai->ai_flags |= (rai->ai_flags & RAI_NUMERICHOST) ? AI_NUMERICHOST : 0;
- ai->ai_family = rai->ai_family;
+ if (rai->ai_flags & RAI_PASSIVE)
+ ai->ai_flags = AI_PASSIVE;
+ if (rai->ai_flags & RAI_NUMERICHOST)
+ ai->ai_flags |= AI_NUMERICHOST;
+ if (rai->ai_family != AF_IB)
+ ai->ai_family = rai->ai_family;
switch (rai->ai_qp_type) {
case IBV_QPT_RC:
ai->ai_next = NULL;
}
+static int ucma_copy_addr(struct sockaddr **dst, socklen_t *dst_len,
+ struct sockaddr *src, socklen_t src_len)
+{
+ *dst = malloc(src_len);
+ if (!(*dst))
+ return ERR(ENOMEM);
+
+ memcpy(*dst, src, src_len);
+ *dst_len = src_len;
+ return 0;
+}
+
+void ucma_set_sid(enum rdma_port_space ps, struct sockaddr *addr,
+ struct sockaddr_ib *sib)
+{
+ uint16_t port;
+
+ port = addr ? ucma_get_port(addr) : 0;
+ sib->sib_sid = htonll(((uint64_t) ps << 16) + ntohs(port));
+
+ if (ps)
+ sib->sib_sid_mask = htonll(RDMA_IB_IP_PS_MASK);
+ if (port)
+ sib->sib_sid_mask |= htonll(RDMA_IB_IP_PORT_MASK);
+}
+
+static int ucma_convert_in6(int ps, struct sockaddr_ib **dst, socklen_t *dst_len,
+ struct sockaddr_in6 *src, socklen_t src_len)
+{
+ *dst = calloc(1, sizeof(struct sockaddr_ib));
+ if (!(*dst))
+ return ERR(ENOMEM);
+printf("converting ipv6 to ib\n");
+
+ (*dst)->sib_family = AF_IB;
+ (*dst)->sib_pkey = 0xFFFF;
+ (*dst)->sib_flowinfo = src->sin6_flowinfo;
+ ib_addr_set(&(*dst)->sib_addr, src->sin6_addr.s6_addr32[0],
+ src->sin6_addr.s6_addr32[1], src->sin6_addr.s6_addr32[2],
+ src->sin6_addr.s6_addr32[3]);
+ ucma_set_sid(ps, (struct sockaddr *) src, *dst);
+printf("sid %llx %llx\n", (*dst)->sib_sid, (*dst)->sib_sid_mask);
+ (*dst)->sib_scope_id = src->sin6_scope_id;
+
+ *dst_len = sizeof(struct sockaddr_ib);
+ return 0;
+}
+
static int ucma_convert_to_rai(struct rdma_addrinfo *rai,
struct rdma_addrinfo *hints, struct addrinfo *ai)
{
- struct sockaddr *addr;
- char *canonname;
-
- rai->ai_family = ai->ai_family;
+ int ret;
- if (hints && hints->ai_qp_type) {
+ if (hints->ai_qp_type) {
rai->ai_qp_type = hints->ai_qp_type;
} else {
switch (ai->ai_socktype) {
break;
}
}
+printf("qp type %d\n", rai->ai_qp_type);
- if (hints && hints->ai_port_space) {
+ if (hints->ai_port_space) {
rai->ai_port_space = hints->ai_port_space;
} else {
switch (ai->ai_protocol) {
break;
}
}
-
- addr = malloc(ai->ai_addrlen);
- if (!addr)
- return ERR(ENOMEM);
-
- canonname = ai->ai_canonname ? strdup(ai->ai_canonname) : NULL;
-
- memcpy(addr, ai->ai_addr, ai->ai_addrlen);
- if (ai->ai_flags & RAI_PASSIVE) {
- rai->ai_src_addr = addr;
- rai->ai_src_len = ai->ai_addrlen;
- rai->ai_src_canonname = canonname;
+printf("port space %d\n", rai->ai_port_space);
+
+ if (ai->ai_flags & AI_PASSIVE) {
+ rai->ai_flags = RAI_PASSIVE;
+ if (ai->ai_canonname)
+ rai->ai_src_canonname = strdup(ai->ai_canonname);
+
+ if ((hints->ai_flags & RAI_FAMILY) && (hints->ai_family == AF_IB) &&
+ (hints->ai_flags & RAI_NUMERICHOST)) {
+ rai->ai_family = AF_IB;
+ ret = ucma_convert_in6(rai->ai_port_space,
+ (struct sockaddr_ib **) &rai->ai_src_addr,
+ &rai->ai_src_len,
+ (struct sockaddr_in6 *) ai->ai_addr,
+ ai->ai_addrlen);
+printf("using af ib \n");
+ } else {
+ rai->ai_family = ai->ai_family;
+printf("af %d\n", rai->ai_family);
+ ret = ucma_copy_addr(&rai->ai_src_addr, &rai->ai_src_len,
+ ai->ai_addr, ai->ai_addrlen);
+ }
} else {
- rai->ai_dst_addr = addr;
- rai->ai_dst_len = ai->ai_addrlen;
- rai->ai_dst_canonname = canonname;
+ if (ai->ai_canonname)
+ rai->ai_dst_canonname = strdup(ai->ai_canonname);
+
+ if ((hints->ai_flags & RAI_FAMILY) && (hints->ai_family == AF_IB) &&
+ (hints->ai_flags & RAI_NUMERICHOST)) {
+ rai->ai_family = AF_IB;
+ ret = ucma_convert_in6(rai->ai_port_space,
+ (struct sockaddr_ib **) &rai->ai_dst_addr,
+ &rai->ai_dst_len,
+ (struct sockaddr_in6 *) ai->ai_addr,
+ ai->ai_addrlen);
+ } else {
+ rai->ai_family = ai->ai_family;
+ ret = ucma_copy_addr(&rai->ai_dst_addr, &rai->ai_dst_len,
+ ai->ai_addr, ai->ai_addrlen);
+ }
}
-
- return 0;
+ return ret;
}
-static int ucma_convert_gai(char *node, char *service,
+static int ucma_getaddrinfo(char *node, char *service,
struct rdma_addrinfo *hints,
struct rdma_addrinfo *rai)
{
struct addrinfo ai_hints;
- struct addrinfo *ai, *aih;
+ struct addrinfo *ai;
int ret;
- if (hints) {
+ if (hints != &nohints) {
ucma_convert_to_ai(&ai_hints, hints);
- rai->ai_flags = hints->ai_flags;
- aih = &ai_hints;
+ ret = getaddrinfo(node, service, &ai_hints, &ai);
} else {
- aih = NULL;
+ ret = getaddrinfo(node, service, NULL, &ai);
}
-
- ret = getaddrinfo(node, service, aih, &ai);
if (ret)
return ret;
return ret;
}
-static int ucma_copy_ai_addr(struct sockaddr **dst, socklen_t *dst_len,
- struct sockaddr *src, socklen_t src_len)
-{
- *dst = calloc(1, src_len);
- if (!(*dst))
- return ERR(ENOMEM);
-
- memcpy(*dst, src, src_len);
- *dst_len = src_len;
- return 0;
-}
-
int rdma_getaddrinfo(char *node, char *service,
struct rdma_addrinfo *hints,
struct rdma_addrinfo **res)
if (!rai)
return ERR(ENOMEM);
+ if (!hints)
+ hints = &nohints;
+
if (node || service) {
- ret = ucma_convert_gai(node, service, hints, rai);
+ ret = ucma_getaddrinfo(node, service, hints, rai);
} else {
rai->ai_flags = hints->ai_flags;
rai->ai_family = hints->ai_family;
rai->ai_qp_type = hints->ai_qp_type;
rai->ai_port_space = hints->ai_port_space;
if (hints->ai_dst_len) {
- ret = ucma_copy_ai_addr(&rai->ai_dst_addr, &rai->ai_dst_len,
- hints->ai_dst_addr, hints->ai_dst_len);
+ ret = ucma_copy_addr(&rai->ai_dst_addr, &rai->ai_dst_len,
+ hints->ai_dst_addr, hints->ai_dst_len);
}
}
if (ret)
goto err;
- if (!rai->ai_src_len && hints && hints->ai_src_len) {
- ret = ucma_copy_ai_addr(&rai->ai_src_addr, &rai->ai_src_len,
- hints->ai_src_addr, hints->ai_src_len);
+ if (!rai->ai_src_len && hints->ai_src_len) {
+ ret = ucma_copy_addr(&rai->ai_src_addr, &rai->ai_src_len,
+ hints->ai_src_addr, hints->ai_src_len);
if (ret)
goto err;
}