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
