diff mbox series

[EXPERIMENTAL,v1,1/4] RDMA/cma: Add support for loopback netdevice

Message ID 1551248837-64041-2-git-send-email-parav@mellanox.com (mailing list archive)
State RFC
Headers show
Series RDMA loopback device | expand

Commit Message

Parav Pandit Feb. 27, 2019, 6:27 a.m. UTC
In order to support loopback rdma device, support resolving loopback
addresses to their respective rdma device.

Signed-off-by: Parav Pandit <parav@mellanox.com>
---
 drivers/infiniband/core/cma.c | 134 ++++--------------------------------------
 1 file changed, 12 insertions(+), 122 deletions(-)
diff mbox series

Patch

diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 68c997b..01913aa 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -621,7 +621,8 @@  static int cma_translate_addr(struct sockaddr *addr, struct rdma_dev_addr *dev_a
 	if ((dev_type != ARPHRD_INFINIBAND) && rdma_protocol_ib(device, port))
 		return ERR_PTR(-ENODEV);
 
-	if (dev_type == ARPHRD_ETHER && rdma_protocol_roce(device, port)) {
+	if ((dev_type == ARPHRD_ETHER || dev_type == ARPHRD_LOOPBACK) &&
+	    rdma_protocol_roce(device, port)) {
 		ndev = dev_get_by_index(dev_addr->net, bound_if_index);
 		if (!ndev)
 			return ERR_PTR(-ENODEV);
@@ -1401,8 +1402,7 @@  static bool validate_ipv4_net_dev(struct net_device *net_dev,
 
 	if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr) ||
 	    ipv4_is_lbcast(daddr) || ipv4_is_zeronet(saddr) ||
-	    ipv4_is_zeronet(daddr) || ipv4_is_loopback(daddr) ||
-	    ipv4_is_loopback(saddr))
+	    ipv4_is_zeronet(daddr))
 		return false;
 
 	memset(&fl4, 0, sizeof(fl4));
@@ -2022,7 +2022,7 @@  static int cma_ib_handler(struct ib_cm_id *cm_id,
 			rt->addr.dev_addr.dev_type = ARPHRD_INFINIBAND;
 			rdma_addr_set_sgid(&rt->addr.dev_addr, &rt->path_rec[0].sgid);
 			ib_addr_set_pkey(&rt->addr.dev_addr, be16_to_cpu(rt->path_rec[0].pkey));
-		} else if (!cma_any_addr(cma_src_addr(id_priv))) {
+		} else if (!cma_zero_addr(cma_src_addr(id_priv))) {
 			ret = cma_translate_addr(cma_src_addr(id_priv), &rt->addr.dev_addr);
 			if (ret)
 				goto err;
@@ -2920,81 +2920,6 @@  int rdma_resolve_route(struct rdma_cm_id *id, unsigned long timeout_ms)
 }
 EXPORT_SYMBOL(rdma_resolve_route);
 
-static void cma_set_loopback(struct sockaddr *addr)
-{
-	switch (addr->sa_family) {
-	case AF_INET:
-		((struct sockaddr_in *) addr)->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-		break;
-	case AF_INET6:
-		ipv6_addr_set(&((struct sockaddr_in6 *) addr)->sin6_addr,
-			      0, 0, 0, htonl(1));
-		break;
-	default:
-		ib_addr_set(&((struct sockaddr_ib *) addr)->sib_addr,
-			    0, 0, 0, htonl(1));
-		break;
-	}
-}
-
-static int cma_bind_loopback(struct rdma_id_private *id_priv)
-{
-	struct cma_device *cma_dev, *cur_dev;
-	union ib_gid gid;
-	enum ib_port_state port_state;
-	u16 pkey;
-	int ret;
-	u8 p;
-
-	cma_dev = NULL;
-	mutex_lock(&lock);
-	list_for_each_entry(cur_dev, &dev_list, list) {
-		if (cma_family(id_priv) == AF_IB &&
-		    !rdma_cap_ib_cm(cur_dev->device, 1))
-			continue;
-
-		if (!cma_dev)
-			cma_dev = cur_dev;
-
-		for (p = 1; p <= cur_dev->device->phys_port_cnt; ++p) {
-			if (!ib_get_cached_port_state(cur_dev->device, p, &port_state) &&
-			    port_state == IB_PORT_ACTIVE) {
-				cma_dev = cur_dev;
-				goto port_found;
-			}
-		}
-	}
-
-	if (!cma_dev) {
-		ret = -ENODEV;
-		goto out;
-	}
-
-	p = 1;
-
-port_found:
-	ret = rdma_query_gid(cma_dev->device, p, 0, &gid);
-	if (ret)
-		goto out;
-
-	ret = ib_get_cached_pkey(cma_dev->device, p, 0, &pkey);
-	if (ret)
-		goto out;
-
-	id_priv->id.route.addr.dev_addr.dev_type =
-		(rdma_protocol_ib(cma_dev->device, p)) ?
-		ARPHRD_INFINIBAND : ARPHRD_ETHER;
-
-	rdma_addr_set_sgid(&id_priv->id.route.addr.dev_addr, &gid);
-	ib_addr_set_pkey(&id_priv->id.route.addr.dev_addr, pkey);
-	id_priv->id.port_num = p;
-	cma_attach_to_dev(id_priv, cma_dev);
-	cma_set_loopback(cma_src_addr(id_priv));
-out:
-	mutex_unlock(&lock);
-	return ret;
-}
-
 static void addr_handler(int status, struct sockaddr *src_addr,
 			 struct rdma_dev_addr *dev_addr, void *context)
 {
@@ -3046,33 +2971,6 @@  static void addr_handler(int status, struct sockaddr *src_addr,
 	mutex_unlock(&id_priv->handler_mutex);
 }
 
-static int cma_resolve_loopback(struct rdma_id_private *id_priv)
-{
-	struct cma_work *work;
-	union ib_gid gid;
-	int ret;
-
-	work = kzalloc(sizeof *work, GFP_KERNEL);
-	if (!work)
-		return -ENOMEM;
-
-	if (!id_priv->cma_dev) {
-		ret = cma_bind_loopback(id_priv);
-		if (ret)
-			goto err;
-	}
-
-	rdma_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid);
-	rdma_addr_set_dgid(&id_priv->id.route.addr.dev_addr, &gid);
-
-	cma_init_resolve_addr_work(work, id_priv);
-	queue_work(cma_wq, &work->work);
-	return 0;
-err:
-	kfree(work);
-	return ret;
-}
-
 static int cma_resolve_ib_addr(struct rdma_id_private *id_priv)
 {
 	struct cma_work *work;
@@ -3140,24 +3038,16 @@  int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
 		return -EINVAL;
 
 	memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr));
-	if (cma_any_addr(dst_addr)) {
-		ret = cma_resolve_loopback(id_priv);
+	if (dst_addr->sa_family == AF_IB) {
+		ret = cma_resolve_ib_addr(id_priv);
 	} else {
-		if (dst_addr->sa_family == AF_IB) {
-			ret = cma_resolve_ib_addr(id_priv);
-		} else {
-			ret = rdma_resolve_ip(cma_src_addr(id_priv), dst_addr,
-					      &id->route.addr.dev_addr,
-					      timeout_ms, addr_handler,
-					      false, id_priv);
-		}
+		ret = rdma_resolve_ip(cma_src_addr(id_priv), dst_addr,
+				      &id->route.addr.dev_addr,
+				      timeout_ms, addr_handler,
+				      false, id_priv);
 	}
 	if (ret)
-		goto err;
-
-	return 0;
-err:
-	cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND);
+		cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND);
 	return ret;
 }
 EXPORT_SYMBOL(rdma_resolve_addr);
@@ -3563,7 +3453,7 @@  int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
 		goto err1;
 
 	memcpy(cma_src_addr(id_priv), addr, rdma_addr_size(addr));
-	if (!cma_any_addr(addr)) {
+	if (!cma_zero_addr(addr)) {
 		ret = cma_translate_addr(addr, &id->route.addr.dev_addr);
 		if (ret)
 			goto err1;