diff mbox

[2/2] rdma/cm: allow user to specify IP to DGID mapping

Message ID F451C333D8CB45E4B4642C6BD1EDD3C3@amr.corp.intel.com (mailing list archive)
State RFC
Headers show

Commit Message

Hefty, Sean Oct. 5, 2009, 5:45 p.m. UTC
None
diff mbox

Patch

diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 0753178..9adf8fb 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -1919,6 +1919,21 @@  err:
 }
 EXPORT_SYMBOL(rdma_resolve_addr);
 
+int rdma_set_ib_dest(struct rdma_cm_id *id, struct sockaddr *dst_addr,
+		     union ib_gid *dgid)
+{
+	struct rdma_id_private *id_priv;
+
+	id_priv = container_of(id, struct rdma_id_private, id);
+	if (!cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_ADDR_RESOLVED))
+		return -EINVAL;
+
+	memcpy(&id->route.addr.dst_addr, dst_addr, ip_addr_size(dst_addr));
+	ib_addr_set_dgid(&id->route.addr.dev_addr, dgid);
+	return 0;
+}
+EXPORT_SYMBOL(rdma_set_ib_dest);
+
 static void cma_bind_port(struct rdma_bind_list *bind_list,
 			  struct rdma_id_private *id_priv)
 {
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 1359727..3a252e6 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -832,12 +832,35 @@  static int ucma_set_ib_path(struct ucma_context *ctx,
 	return ucma_event_handler(ctx->cm_id, &event);
 }
 
+static int ucma_set_ib_dest(struct ucma_context *ctx,
+			    struct rdma_ucm_ib_dest *ib_dest, size_t optlen)
+{
+	union ib_gid dgid;
+	struct rdma_cm_event event;
+	int ret;
+
+	if (optlen < sizeof(*ib_dest))
+		return -EINVAL;
+
+	memcpy(&dgid, ib_dest->dgid, sizeof dgid);
+	ret = rdma_set_ib_dest(ctx->cm_id, (struct sockaddr *) &ib_dest->dst_addr, &dgid);
+	if (ret)
+		return ret;
+
+	memset(&event, 0, sizeof event);
+	event.event = RDMA_CM_EVENT_ADDR_RESOLVED;
+	return ucma_event_handler(ctx->cm_id, &event);
+}
+
 static int ucma_set_option_ib(struct ucma_context *ctx, int optname,
 			      void *optval, size_t optlen)
 {
 	int ret;
 
 	switch (optname) {
+	case RDMA_OPTION_IB_DEST:
+		ret = ucma_set_ib_dest(ctx, optval, optlen);
+		break;
 	case RDMA_OPTION_IB_PATH:
 		ret = ucma_set_ib_path(ctx, optval, optlen);
 		break;
diff --git a/include/rdma/rdma_cm_ib.h b/include/rdma/rdma_cm_ib.h
index 2389c3b..7326d35 100644
--- a/include/rdma/rdma_cm_ib.h
+++ b/include/rdma/rdma_cm_ib.h
@@ -48,6 +48,20 @@ 
 int rdma_set_ib_paths(struct rdma_cm_id *id,
 		      struct ib_sa_path_rec *path_rec, int num_paths);
 
+/**
+ * rdma_set_ib_dest - Manually set the destination address
+ * @id: Connection identifier associated with the request.
+ * @dst_addr: Destination address information.
+ * @dgid: Destination device address information.
+ *
+ * This call allows the user to specify address mappings for rdma_cm_id's
+ * bound to an Infiniband device.  It is called on the client side of a
+ * connection and combined with rdma_bind_addr, replaces the call to
+ * rdma_resolve_addr.
+ */
+int rdma_set_ib_dest(struct rdma_cm_id *id, struct sockaddr *dst_addr,
+		     union ib_gid *dgid);
+
 /* Global qkey for UDP QPs and multicast groups. */
 #define RDMA_UDP_QKEY 0x01234567
 
diff --git a/include/rdma/rdma_user_cm.h b/include/rdma/rdma_user_cm.h
index d7829f4..a908b89 100644
--- a/include/rdma/rdma_user_cm.h
+++ b/include/rdma/rdma_user_cm.h
@@ -223,6 +223,7 @@  enum {
 enum {
 	RDMA_OPTION_ID_TOS	= 0,
 
+	RDMA_OPTION_IB_DEST	= 0,
 	RDMA_OPTION_IB_PATH	= 1
 };
 
@@ -234,6 +235,11 @@  struct rdma_ucm_set_option {
 	__u32 optlen;
 };
 
+struct rdma_ucm_ib_dest {
+	__u8 dgid[16];
+	struct sockaddr_in6 dst_addr;
+};
+
 struct rdma_ucm_migrate_id {
 	__u64 response;
 	__u32 id;