RDMA/ucma: Add ability to query GID addresses
authorSean Hefty <sean.hefty@intel.com>
Wed, 29 May 2013 17:09:29 +0000 (10:09 -0700)
committerRoland Dreier <roland@purestorage.com>
Fri, 21 Jun 2013 06:35:42 +0000 (23:35 -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>
Signed-off-by: Roland Dreier <roland@purestorage.com>
drivers/infiniband/core/ucma.c
include/uapi/rdma/rdma_user_cm.h

index 722f2ff0400fe50bc415700cf19c6a1e12097f1a..45bb052f573e1c9910c995daa304ed6c759b2324 100644 (file)
@@ -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;
index 07eb6cfa926c266feca3e82e672e781996bbe175..ea79253ceb135dc83ac3c8b6d4b0e22b02b1091f 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 {