[PATCH] [for-2.6.33] rdma/cm: disallow loopback address for iwarp devices

Sean Hefty
2010-02-08T06:02:11Z

Since iWarp devices are not guaranteed to support loopback connections,
prevent rdma_bind_addr from associating the loopback address with
an iWarp device.

Signed-off-by: Sean Hefty <sean.hefty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
This includes feedback from Steve Wise based on the initial rfc patch.

Although this patch is needed to prevent binding to RDMA devices that
may not support loopback addressing, is also works around a bug in
openmpi using the loopback address to bind to an iwarp device.

This is not a perfect solution either, since it disable all iwarp devices.
The NES driver should be able to support loopback connections, though that
feature has never been tested. We may need a per device attribute.
I will look at creating such a patch, but wanted to post this in case I
can't get that one done in the next couple of days.

drivers/infiniband/core/cma.c | 18 ++++++++++++------
1 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index cc9b594..fe8b0c0 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -1739,6 +1739,9 @@ err:
}
EXPORT_SYMBOL(rdma_resolve_route);

+/*
+ * Only IB devices are guaranteed to support loopback connections.
+ */
static int cma_bind_loopback(struct rdma_id_private *id_priv)
{
struct cma_device *cma_dev;
@@ -1753,14 +1756,19 @@ static int cma_bind_loopback(struct rdma_id_private *id_priv)
ret = -ENODEV;
goto out;
}
- list_for_each_entry(cma_dev, &dev_list, list)
+ list_for_each_entry(cma_dev, &dev_list, list) {
+ if (rdma_node_get_transport(cma_dev->device->node_type) !=
+ RDMA_TRANSPORT_IB)
+ continue;
+
for (p = 1; p <= cma_dev->device->phys_port_cnt; ++p)
if (!ib_query_port(cma_dev->device, p, &port_attr) &&
port_attr.state == IB_PORT_ACTIVE)
goto port_found;
+ }

- p = 1;
- cma_dev = list_entry(dev_list.next, struct cma_device, list);
+ ret = -ENODEV;
+ goto out;

port_found:
ret = ib_get_cached_gid(cma_dev->device, p, 0, &gid);
@@ -1771,9 +1779,7 @@ port_found:
if (ret)
goto out;

- id_priv->id.route.addr.dev_addr.dev_type =
- (rdma_node_get_transport(cma_dev->device->node_type) == RDMA_TRANSPORT_IB) ?
- ARPHRD_INFINIBAND : ARPHRD_ETHER;
+ id_priv->id.route.addr.dev_addr.dev_type = ARPHRD_INFINIBAND;

rdma_addr_set_sgid(&id_priv->id.route.addr.dev_addr, &gid);
ib_addr_set_pkey(&id_priv->id.route.addr.dev_addr, pkey);