Signed-off-by: Sean Hefty <[email protected]>
---

 src/acm.c |   59 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 src/cma.c |   32 +++++++++++++++++++++++++++++---
 2 files changed, 81 insertions(+), 10 deletions(-)

diff --git a/src/acm.c b/src/acm.c
index 5dd8899..8975b97 100644
--- a/src/acm.c
+++ b/src/acm.c
@@ -51,6 +51,18 @@ static pthread_mutex_t acm_lock = PTHREAD_MUTEX_INITIALIZER;
 static int sock;
 static short server_port = 6125;
 
+struct ib_connect_hdr {
+       uint8_t  cma_version;
+       uint8_t  ip_version; /* IP version: 7:4 */
+       uint16_t port;
+       uint32_t src_addr[4];
+       uint32_t dst_addr[4];
+#define cma_src_ip4 src_addr[3]
+#define cma_src_ip6 src_addr[0]
+#define cma_dst_ip4 dst_addr[3]
+#define cma_dst_ip6 dst_addr[0]
+};
+
 void ucma_ib_init(void)
 {
        struct sockaddr_in addr;
@@ -100,22 +112,22 @@ static void ucma_set_sid(enum rdma_port_space ps, struct 
sockaddr *addr,
                sib->sib_sid_mask = htonll(RDMA_IB_IP_PS_MASK);
 }
 
-static void ucma_ib_convert_addr(struct rdma_addrinfo *rai,
-                                struct ib_path_record *path)
+static int ucma_ib_convert_addr(struct rdma_addrinfo *rai,
+                               struct ib_path_record *path)
 {
        struct sockaddr_ib *src, *dst;
 
        if (!path)
-               return;
+               return ERR(ENODATA);
 
        src = zalloc(sizeof *src);
        if (!src)
-               return;
+               return ERR(ENOMEM);
 
        dst = zalloc(sizeof *dst);
        if (!dst) {
                free(src);
-               return;
+               return ERR(ENOMEM);
        }
 
        src->sib_family = AF_IB;
@@ -140,6 +152,33 @@ static void ucma_ib_convert_addr(struct rdma_addrinfo *rai,
 
        rai->ai_family = AF_IB;
        rai->ai_port_space = RDMA_PS_IB;
+       return 0;
+}
+                                
+static void ucma_ib_format_connect(struct rdma_addrinfo *rai)
+{
+       struct ib_connect_hdr *hdr;
+
+       hdr = zalloc(sizeof *hdr);
+       if (!hdr)
+               return;
+
+       if (rai->ai_family == AF_INET) {
+               hdr->ip_version = 4 << 4;
+               memcpy(&hdr->cma_src_ip4,
+                      &((struct sockaddr_in *) rai->ai_src_addr)->sin_addr, 4);
+               memcpy(&hdr->cma_dst_ip4,
+                      &((struct sockaddr_in *) rai->ai_dst_addr)->sin_addr, 4);
+       } else {
+               hdr->ip_version = 6 << 4;
+               memcpy(&hdr->cma_src_ip6,
+                      &((struct sockaddr_in6 *) rai->ai_src_addr)->sin6_addr, 
16);
+               memcpy(&hdr->cma_dst_ip6,
+                      &((struct sockaddr_in6 *) rai->ai_dst_addr)->sin6_addr, 
16);
+       }
+
+       rai->ai_connect = hdr;
+       rai->ai_connect_len = sizeof(*hdr);
 }
 
 static void ucma_ib_save_resp(struct rdma_addrinfo *rai, struct 
acm_resolve_msg *msg)
@@ -166,8 +205,14 @@ static void ucma_ib_save_resp(struct rdma_addrinfo *rai, 
struct acm_resolve_msg
 
        rai->ai_route = path_data;
        rai->ai_route_len = len;
-       if (af_ib_support)
-               ucma_ib_convert_addr(rai, pri_path);
+       if (af_ib_support) {
+               ucma_ib_format_connect(rai);
+               if (ucma_ib_convert_addr(rai, pri_path) &&
+                   rai->ai_connect) {
+                       free(rai->ai_connect);
+                       rai->ai_connect_len = 0;
+               }
+       }
        return;
 err:
        free(path_data);
diff --git a/src/cma.c b/src/cma.c
index 6ac949a..faf4264 100644
--- a/src/cma.c
+++ b/src/cma.c
@@ -106,6 +106,8 @@ struct cma_device {
 struct cma_id_private {
        struct rdma_cm_id       id;
        struct cma_device       *cma_dev;
+       void                    *connect;
+       size_t                  connect_len;
        int                     events_completed;
        int                     connect_error;
        int                     sync;
@@ -363,6 +365,8 @@ static void ucma_free_id(struct cma_id_private *id_priv)
 
        if (id_priv->sync)
                rdma_destroy_event_channel(id_priv->id.channel);
+       if (id_priv->connect)
+               free(id_priv->connect);
        free(id_priv);
 }
 
@@ -1186,15 +1190,20 @@ static void ucma_copy_conn_param_to_kern(struct 
cma_id_private *id_priv,
        dst->initiator_depth = id_priv->initiator_depth;
        dst->valid = 1;
 
+       if (id_priv->connect_len) {
+               memcpy(dst->private_data, id_priv->connect, 
id_priv->connect_len);
+               dst->private_data_len = id_priv->connect_len;
+       }
+
        if (src) {
                dst->flow_control = src->flow_control;
                dst->retry_count = src->retry_count;
                dst->rnr_retry_count = src->rnr_retry_count;
 
                if (src->private_data && src->private_data_len) {
-                       memcpy(dst->private_data, src->private_data,
-                              src->private_data_len);
-                       dst->private_data_len = src->private_data_len;
+                       memcpy(dst->private_data + dst->private_data_len,
+                              src->private_data, src->private_data_len);
+                       dst->private_data_len += src->private_data_len;
                }
        } else {
                dst->retry_count = 7;
@@ -1238,6 +1247,11 @@ int rdma_connect(struct rdma_cm_id *id, struct 
rdma_conn_param *conn_param)
        if (ret != size)
                return (ret >= 0) ? ERR(ENODATA) : -1;
 
+       if (id_priv->connect) {
+               free(id_priv->connect);
+               id_priv->connect_len = 0;
+       }
+
        return ucma_complete(id_priv);
 }
 
@@ -2038,6 +2052,7 @@ int rdma_create_ep(struct rdma_cm_id **id, struct 
rdma_addrinfo *res,
                   struct ibv_pd *pd, struct ibv_qp_init_attr *qp_init_attr)
 {
        struct rdma_cm_id *cm_id;
+       struct cma_id_private *id_priv;
        int ret;
 
        ret = rdma_create_id2(NULL, &cm_id, NULL, res->ai_port_space, 
res->ai_qp_type);
@@ -2075,6 +2090,17 @@ int rdma_create_ep(struct rdma_cm_id **id, struct 
rdma_addrinfo *res,
        if (ret)
                goto err;
 
+       if (res->ai_connect_len) {
+               id_priv = container_of(cm_id, struct cma_id_private, id);
+               id_priv->connect = malloc(res->ai_connect_len);
+               if (!id_priv->connect) {
+                       ret = ERR(ENOMEM);
+                       goto err;
+               }
+               memcpy(id_priv->connect, res->ai_connect, res->ai_connect_len);
+               id_priv->connect_len = res->ai_connect_len;
+       }
+
 out:
        *id = cm_id;
        return 0;



--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to