aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/cma.c
diff options
context:
space:
mode:
authorMatan Barak <matanb@mellanox.com>2015-10-15 18:38:49 +0300
committerDoug Ledford <dledford@redhat.com>2015-10-21 23:48:17 -0400
commitabae1b71dd37bab506b14a6cf6ba7148f4d57232 (patch)
treebb1e327e209e8009fea2ef9fda94e5844bfd6376 /drivers/infiniband/core/cma.c
parentIB/cm: cm_init_av_by_path should find a GID by its netdevice (diff)
downloadlinux-dev-abae1b71dd37bab506b14a6cf6ba7148f4d57232.tar.xz
linux-dev-abae1b71dd37bab506b14a6cf6ba7148f4d57232.zip
IB/cma: cma_validate_port should verify the port and netdevice
Previously, cma_validate_port searched for GIDs in IB cache and then tried to verify the found port. This could fail when there are identical GIDs on both ports. In addition, netdevice should be taken into account when searching the GID table. Fixing cma_validate_port to search only the relevant port's cache and netdevice. Signed-off-by: Matan Barak <matanb@mellanox.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/infiniband/core/cma.c')
-rw-r--r--drivers/infiniband/core/cma.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index e4d9d75ffc08..2cbf9c9b4fe4 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -427,10 +427,11 @@ static int cma_translate_addr(struct sockaddr *addr, struct rdma_dev_addr *dev_a
}
static inline int cma_validate_port(struct ib_device *device, u8 port,
- union ib_gid *gid, int dev_type)
+ union ib_gid *gid, int dev_type,
+ int bound_if_index)
{
- u8 found_port;
int ret = -ENODEV;
+ struct net_device *ndev = NULL;
if ((dev_type == ARPHRD_INFINIBAND) && !rdma_protocol_ib(device, port))
return ret;
@@ -438,9 +439,13 @@ static inline int cma_validate_port(struct ib_device *device, u8 port,
if ((dev_type != ARPHRD_INFINIBAND) && rdma_protocol_ib(device, port))
return ret;
- ret = ib_find_cached_gid(device, gid, NULL, &found_port, NULL);
- if (port != found_port)
- return -ENODEV;
+ if (dev_type == ARPHRD_ETHER)
+ ndev = dev_get_by_index(&init_net, bound_if_index);
+
+ ret = ib_find_cached_gid_by_port(device, gid, port, ndev, NULL);
+
+ if (ndev)
+ dev_put(ndev);
return ret;
}
@@ -472,7 +477,8 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv,
&iboe_gid : &gid;
ret = cma_validate_port(cma_dev->device, port, gidp,
- dev_addr->dev_type);
+ dev_addr->dev_type,
+ dev_addr->bound_dev_if);
if (!ret) {
id_priv->id.port_num = port;
goto out;
@@ -490,7 +496,8 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv,
&iboe_gid : &gid;
ret = cma_validate_port(cma_dev->device, port, gidp,
- dev_addr->dev_type);
+ dev_addr->dev_type,
+ dev_addr->bound_dev_if);
if (!ret) {
id_priv->id.port_num = port;
goto out;
@@ -2296,8 +2303,11 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
route->num_paths = 1;
- if (addr->dev_addr.bound_dev_if)
+ if (addr->dev_addr.bound_dev_if) {
ndev = dev_get_by_index(&init_net, addr->dev_addr.bound_dev_if);
+ route->path_rec->net = &init_net;
+ route->path_rec->ifindex = addr->dev_addr.bound_dev_if;
+ }
if (!ndev) {
ret = -ENODEV;
goto err2;