|
@@ -48,6 +48,7 @@
|
|
|
#include <rdma/rdma_cm.h>
|
|
|
#include <rdma/rdma_cm_ib.h>
|
|
|
#include <rdma/ib_addr.h>
|
|
|
+#include <rdma/ib.h>
|
|
|
|
|
|
MODULE_AUTHOR("Sean Hefty");
|
|
|
MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access");
|
|
@@ -782,6 +783,52 @@ static ssize_t ucma_query_path(struct ucma_context *ctx,
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static ssize_t ucma_query_gid(struct ucma_context *ctx,
|
|
|
+ void __user *response, int out_len)
|
|
|
+{
|
|
|
+ struct rdma_ucm_query_addr_resp resp;
|
|
|
+ struct sockaddr_ib *addr;
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+ if (out_len < sizeof(resp))
|
|
|
+ return -ENOSPC;
|
|
|
+
|
|
|
+ memset(&resp, 0, sizeof resp);
|
|
|
+
|
|
|
+ ucma_query_device_addr(ctx->cm_id, &resp);
|
|
|
+
|
|
|
+ addr = (struct sockaddr_ib *) &resp.src_addr;
|
|
|
+ resp.src_size = sizeof(*addr);
|
|
|
+ if (ctx->cm_id->route.addr.src_addr.ss_family == AF_IB) {
|
|
|
+ memcpy(addr, &ctx->cm_id->route.addr.src_addr, resp.src_size);
|
|
|
+ } else {
|
|
|
+ addr->sib_family = AF_IB;
|
|
|
+ addr->sib_pkey = (__force __be16) resp.pkey;
|
|
|
+ rdma_addr_get_sgid(&ctx->cm_id->route.addr.dev_addr,
|
|
|
+ (union ib_gid *) &addr->sib_addr);
|
|
|
+ addr->sib_sid = rdma_get_service_id(ctx->cm_id, (struct sockaddr *)
|
|
|
+ &ctx->cm_id->route.addr.src_addr);
|
|
|
+ }
|
|
|
+
|
|
|
+ addr = (struct sockaddr_ib *) &resp.dst_addr;
|
|
|
+ resp.dst_size = sizeof(*addr);
|
|
|
+ if (ctx->cm_id->route.addr.dst_addr.ss_family == AF_IB) {
|
|
|
+ memcpy(addr, &ctx->cm_id->route.addr.dst_addr, resp.dst_size);
|
|
|
+ } else {
|
|
|
+ addr->sib_family = AF_IB;
|
|
|
+ addr->sib_pkey = (__force __be16) resp.pkey;
|
|
|
+ rdma_addr_get_dgid(&ctx->cm_id->route.addr.dev_addr,
|
|
|
+ (union ib_gid *) &addr->sib_addr);
|
|
|
+ addr->sib_sid = rdma_get_service_id(ctx->cm_id, (struct sockaddr *)
|
|
|
+ &ctx->cm_id->route.addr.dst_addr);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (copy_to_user(response, &resp, sizeof(resp)))
|
|
|
+ ret = -EFAULT;
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
static ssize_t ucma_query(struct ucma_file *file,
|
|
|
const char __user *inbuf,
|
|
|
int in_len, int out_len)
|
|
@@ -806,6 +853,9 @@ static ssize_t ucma_query(struct ucma_file *file,
|
|
|
case RDMA_USER_CM_QUERY_PATH:
|
|
|
ret = ucma_query_path(ctx, response, out_len);
|
|
|
break;
|
|
|
+ case RDMA_USER_CM_QUERY_GID:
|
|
|
+ ret = ucma_query_gid(ctx, response, out_len);
|
|
|
+ break;
|
|
|
default:
|
|
|
ret = -ENOSYS;
|
|
|
break;
|