RDMA/cma: Introduce API to read GIDs for multiple transports
authorParav Pandit <parav@mellanox.com>
Thu, 18 Jan 2018 08:11:16 +0000 (10:11 +0200)
committerJason Gunthorpe <jgg@mellanox.com>
Fri, 19 Jan 2018 20:05:38 +0000 (13:05 -0700)
This patch introduces an API that allows legacy applications to query
GIDs for a rdma_cm_id which is used during connection establishment.

GIDs are stored and created differently for iWarp, IB and RoCE transports.
Therefore rdma_read_gids() returns GID for all the transports hiding
such internal details to caller.
It is usable for client side and server side connections.

In general continued use of GID based addressing outside of IB is
discouraged, so rdma_read_gids() should not be used by any new ULPs.

Signed-off-by: Parav Pandit <parav@mellanox.com>
Reviewed-by: Daniel Jurgens <danielj@mellanox.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/core/cma.c
include/rdma/rdma_cm.h

index 30d1c32a816f91b4e9fcd7bf1dd00b3a801ff655..66590a4c612dc3f3df7f7f560ca1dec45dcbcf4f 100644 (file)
@@ -2036,6 +2036,33 @@ __be64 rdma_get_service_id(struct rdma_cm_id *id, struct sockaddr *addr)
 }
 EXPORT_SYMBOL(rdma_get_service_id);
 
+void rdma_read_gids(struct rdma_cm_id *cm_id, union ib_gid *sgid,
+                   union ib_gid *dgid)
+{
+       struct rdma_addr *addr = &cm_id->route.addr;
+
+       if (!cm_id->device) {
+               if (sgid)
+                       memset(sgid, 0, sizeof(*sgid));
+               if (dgid)
+                       memset(dgid, 0, sizeof(*dgid));
+               return;
+       }
+
+       if (rdma_protocol_roce(cm_id->device, cm_id->port_num)) {
+               if (sgid)
+                       rdma_ip2gid((struct sockaddr *)&addr->src_addr, sgid);
+               if (dgid)
+                       rdma_ip2gid((struct sockaddr *)&addr->dst_addr, dgid);
+       } else {
+               if (sgid)
+                       rdma_addr_get_sgid(&addr->dev_addr, sgid);
+               if (dgid)
+                       rdma_addr_get_dgid(&addr->dev_addr, dgid);
+       }
+}
+EXPORT_SYMBOL(rdma_read_gids);
+
 static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event)
 {
        struct rdma_id_private *id_priv = iw_id->context;
index 3d2eed3c4e7512b6f6d1592d296e7187ba183404..6538a5cc27b6a2031f96fc2611fb3ea210743088 100644 (file)
@@ -413,4 +413,23 @@ bool rdma_is_consumer_reject(struct rdma_cm_id *id, int reason);
 const void *rdma_consumer_reject_data(struct rdma_cm_id *id,
                                      struct rdma_cm_event *ev, u8 *data_len);
 
+/**
+ * rdma_read_gids - Return the SGID and DGID used for establishing
+ *                  connection. This can be used after rdma_resolve_addr()
+ *                  on client side. This can be use on new connection
+ *                  on server side. This is applicable to IB, RoCE, iWarp.
+ *                  If cm_id is not bound yet to the RDMA device, it doesn't
+ *                  copy and SGID or DGID to the given pointers.
+ * @id: Communication identifier whose GIDs are queried.
+ * @sgid: Pointer to SGID where SGID will be returned. It is optional.
+ * @dgid: Pointer to DGID where DGID will be returned. It is optional.
+ * Note: This API should not be used by any new ULPs or new code.
+ * Instead, users interested in querying GIDs should refer to path record
+ * of the rdma_cm_id to query the GIDs.
+ * This API is provided for compatibility for existing users.
+ */
+
+void rdma_read_gids(struct rdma_cm_id *cm_id, union ib_gid *sgid,
+                   union ib_gid *dgid);
+
 #endif /* RDMA_CM_H */