]> git.openfabrics.org - ~shefty/rdma-dev.git/commitdiff
rdma/ucm: add ability to query GID addresses
authorSean Hefty <sean.hefty@intel.com>
Wed, 7 Apr 2010 00:22:41 +0000 (17:22 -0700)
committerSean Hefty <sean.hefty@intel.com>
Thu, 13 May 2010 01:05:54 +0000 (18:05 -0700)
Part of address resolution is mapping IP addresses to IB GIDs.
With the changes to support querying larger addresses and more
path records, also provide a way to query IB GIDs after
resolution completes.

Signed-off-by: Sean Hefty <sean.hefty@intel.com>
drivers/infiniband/core/ucma.c
include/rdma/rdma_user_cm.h

index d55f1a9ee09b75431180f54643606d14838c97c0..4cde0b8951055ea3b993a989a4959401a4401178 100644 (file)
@@ -46,6 +46,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");
@@ -729,6 +730,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)
@@ -753,6 +800,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;
index 28a5d907ac63b2fa5a1d8007f42749b189c22885..ccf635d005ad762d9acb16723ea3242d69cf3110 100644 (file)
@@ -116,7 +116,8 @@ struct rdma_ucm_resolve_route {
 
 enum {
        RDMA_USER_CM_QUERY_ADDR,
-       RDMA_USER_CM_QUERY_PATH
+       RDMA_USER_CM_QUERY_PATH,
+       RDMA_USER_CM_QUERY_GID
 };
 
 struct rdma_ucm_query {