This patch records and retrieves IP addresses from the private data
of the CM REQ message.  The format of the data is based on:

http://openib.org/pipermail/openib-general/2005-August/010318.html

It has not yet been committed.  Comments?

Signed-off-by: Sean Hefty <[EMAIL PROTECTED]>


Index: ulp/cma/cma.c
===================================================================
--- ulp/cma/cma.c       (revision 3524)
+++ ulp/cma/cma.c       (working copy)
@@ -51,8 +51,15 @@ struct cma_id_private {
 };
 
 struct cma_addr {
-       /* 128 bit IPv6 src IP */
-       /* 128 bit IPv6 dest IP */
+       struct {
+               union {
+                       struct in6_addr ip6;
+                       struct {
+                               __be32 pad[3];
+                               __be32 addr;
+                       } ip4;
+               } ver;
+       } src_addr, dst_addr;
        u8 version;     /* version: 7:4, reserved: 3:0 */
        u8 reserved;
        __be16 port;
@@ -121,12 +128,31 @@ static int cma_modify_qp_err(struct rdma
        return ib_modify_qp(cma_id->qp, &qp_attr, IB_QP_STATE);
 }
 
+static int cma_verify_addr(struct cma_addr *addr,
+                          struct sockaddr_in *dst_ip)
+{
+       if (cma_get_version(addr) != 4)
+               return -EINVAL;
+
+       if (dst_ip->sin_port != be16_to_cpu(addr->port) ||
+           dst_ip->sin_addr.s_addr != be32_to_cpu(addr->dst_addr.ver.ip4.addr))
+               return -EINVAL;
+
+       return 0;
+}
+
 static struct cma_id_private* cma_req_recv(struct cma_id_private *listen_id,
                                           struct ib_cm_event *ib_event)
 {
        struct cma_id_private *cma_id_priv;
        struct rdma_route *route;
        struct cma_addr *addr;
+       struct sockaddr_in *dst_ip;
+
+       addr = ib_event->private_data;
+       dst_ip = (struct sockaddr_in *) &listen_id->cma_id.route.src_addr;
+       if (cma_verify_addr(addr, dst_ip))
+               return NULL;
 
        cma_id_priv = cma_alloc_id(listen_id->cma_id.device,
                                   listen_id->cma_id.context,
@@ -135,14 +161,17 @@ static struct cma_id_private* cma_req_re
                return NULL;
 
        route = &cma_id_priv->cma_id.route;
+       route->src_addr = listen_id->cma_id.route.src_addr;
+       route->dst_addr.sa_family = dst_ip->sin_family;
+       ((struct sockaddr_in *) &route->dst_addr)->sin_addr.s_addr =
+                               be32_to_cpu(addr->src_addr.ver.ip4.addr);
+
        route->num_paths = 1 + (ib_event->param.req_rcvd.alternate_path != 
NULL);
        route->path_rec = kmalloc(sizeof *route->path_rec * route->num_paths,
                                  GFP_KERNEL);
        if (!route->path_rec)
                goto err;
 
-       /* TODO: get route information from private data */
-       addr = ib_event->private_data;
        ib_event->private_data += sizeof *addr;
 
        route->path_rec[0] = *ib_event->param.req_rcvd.primary_path;
@@ -305,6 +334,9 @@ int rdma_cma_listen(struct rdma_cma_id *
        struct cma_id_private *cma_id_priv;
        int ret;
 
+       if (addr->sa_family != AF_INET)
+               return -EINVAL;
+
        cma_id_priv = container_of(cma_id, struct cma_id_private, cma_id);
        cma_id->route.src_addr = *addr;
 
@@ -402,7 +434,7 @@ error:
 
 int cma_resolve_ib_route(struct cma_id_private *cma_id_priv,
                         struct sockaddr *src_addr,
-                        struct sockaddr *dest_addr)
+                        struct sockaddr *dst_addr)
 {
        /* TODO: Get remote GID from ARP table, query for path record */
        return -ENOSYS;
@@ -410,7 +442,7 @@ int cma_resolve_ib_route(struct cma_id_p
 
 int rdma_cma_resolve_route(struct rdma_cma_id *cma_id,
                           struct sockaddr *src_addr,
-                          struct sockaddr *dest_addr)
+                          struct sockaddr *dst_addr)
 {
        struct cma_id_private *cma_id_priv;
        int ret;
@@ -419,7 +451,7 @@ int rdma_cma_resolve_route(struct rdma_c
 
        switch (cma_id->device->node_type) {
        case IB_NODE_CA:
-               ret = cma_resolve_ib_route(cma_id_priv, src_addr, dest_addr);
+               ret = cma_resolve_ib_route(cma_id_priv, src_addr, dst_addr);
                break;
        default:
                ret = -ENOSYS;
@@ -430,6 +462,21 @@ int rdma_cma_resolve_route(struct rdma_c
 }
 EXPORT_SYMBOL(rdma_cma_resolve_route);
 
+static void cma_format_addr(struct cma_addr *addr, struct rdma_route *route)
+{
+       struct sockaddr_in *ip_addr;
+
+       memset(addr, 0, sizeof *addr);
+       cma_set_version(addr, 4);
+
+       ip_addr = (struct sockaddr_in *) &route->src_addr;
+       addr->src_addr.ver.ip4.addr = cpu_to_be32(ip_addr->sin_addr.s_addr);
+
+       ip_addr = (struct sockaddr_in *) &route->dst_addr;
+       addr->dst_addr.ver.ip4.addr = cpu_to_be32(ip_addr->sin_addr.s_addr);
+       addr->port = cpu_to_be16(ip_addr->sin_port);
+}
+
 static int cma_connect_ib(struct cma_id_private *cma_id_priv,
                          struct rdma_cma_conn_param *conn_param)
 {
@@ -445,19 +492,20 @@ static int cma_connect_ib(struct cma_id_
        if (!private_data)
                return -ENOMEM;
 
-       /* TODO: set address info in private data */
        addr = private_data;
+       route = &cma_id_priv->cma_id.route;
+       cma_format_addr(addr, route);
+
        if (conn_param->private_data && conn_param->private_data_len)
                memcpy(addr + 1, conn_param->private_data,
                       conn_param->private_data_len);
        req.private_data = private_data;
 
-       route = &cma_id_priv->cma_id.route;
        req.primary_path = &route->path_rec[0];
        if (route->num_paths == 2)
                req.alternate_path = &route->path_rec[1];
-       req.service_id = cma_get_service_id(&route->dest_addr);
 
+       req.service_id = cma_get_service_id(&route->dst_addr);
        req.qp_num = conn_param->qp->qp_num;
        req.qp_type = IB_QPT_RC;
        req.starting_psn = req.qp_num;
Index: include/rdma/rdma_cma.h
===================================================================
--- include/rdma/rdma_cma.h     (revision 3523)
+++ include/rdma/rdma_cma.h     (working copy)
@@ -32,6 +32,7 @@
 
 #include <linux/socket.h>
 #include <linux/in.h>
+#include <linux/in6.h>
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_sa.h>
 
@@ -47,7 +48,7 @@ enum rdma_cma_event_type {
 
 struct rdma_route {
        struct sockaddr src_addr;
-       struct sockaddr dest_addr;
+       struct sockaddr dst_addr;
        struct ib_sa_path_rec *path_rec;
        int num_paths;
 };
@@ -83,7 +84,7 @@ int rdma_cma_listen(struct rdma_cma_id *
 
 int rdma_cma_resolve_route(struct rdma_cma_id *cma_id,
                           struct sockaddr *src_addr,
-                          struct sockaddr *dest_addr);
+                          struct sockaddr *dst_addr);
 
 struct rdma_cma_conn_param {
        struct ib_qp *qp;



_______________________________________________
openib-general mailing list
[email protected]
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to