Skip to content

Commit cbd09ae

Browse files
monis410dledford
authored andcommitted
IB/core: Don't resolve IP address to the loopback device
When resolving an IP address that is on the host of the caller the result from querying the routing table is the loopback device. This is not a valid response, because it doesn't represent the RDMA device and the port. Therefore, callers need to check the resolved device and if it is a loopback device find an alternative way to resolve it. To avoid this we make sure that the response from rdma_resolve_ip() will not be the loopback device. While that, we fix an static checker warning about dereferencing an unintitialized pointer using the same solution as in commit abeffce ("net/mlx5e: Fix a -Wmaybe-uninitialized warning") as a reference. Signed-off-by: Moni Shoua <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent bebb2a4 commit cbd09ae

File tree

3 files changed

+32
-45
lines changed

3 files changed

+32
-45
lines changed

drivers/infiniband/core/addr.c

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ int rdma_translate_ip(const struct sockaddr *addr,
268268
return ret;
269269

270270
ret = rdma_copy_addr(dev_addr, dev, NULL);
271+
dev_addr->bound_dev_if = dev->ifindex;
271272
if (vlan_id)
272273
*vlan_id = rdma_vlan_dev_vlan_id(dev);
273274
dev_put(dev);
@@ -280,6 +281,7 @@ int rdma_translate_ip(const struct sockaddr *addr,
280281
&((const struct sockaddr_in6 *)addr)->sin6_addr,
281282
dev, 1)) {
282283
ret = rdma_copy_addr(dev_addr, dev, NULL);
284+
dev_addr->bound_dev_if = dev->ifindex;
283285
if (vlan_id)
284286
*vlan_id = rdma_vlan_dev_vlan_id(dev);
285287
break;
@@ -405,10 +407,10 @@ static int addr4_resolve(struct sockaddr_in *src_in,
405407
fl4.saddr = src_ip;
406408
fl4.flowi4_oif = addr->bound_dev_if;
407409
rt = ip_route_output_key(addr->net, &fl4);
408-
if (IS_ERR(rt)) {
409-
ret = PTR_ERR(rt);
410-
goto out;
411-
}
410+
ret = PTR_ERR_OR_ZERO(rt);
411+
if (ret)
412+
return ret;
413+
412414
src_in->sin_family = AF_INET;
413415
src_in->sin_addr.s_addr = fl4.saddr;
414416

@@ -423,8 +425,6 @@ static int addr4_resolve(struct sockaddr_in *src_in,
423425

424426
*prt = rt;
425427
return 0;
426-
out:
427-
return ret;
428428
}
429429

430430
#if IS_ENABLED(CONFIG_IPV6)
@@ -527,8 +527,12 @@ static int addr_resolve(struct sockaddr *src_in,
527527
if (resolve_neigh)
528528
ret = addr_resolve_neigh(&rt->dst, dst_in, addr, seq);
529529

530-
ndev = rt->dst.dev;
531-
dev_hold(ndev);
530+
if (addr->bound_dev_if) {
531+
ndev = dev_get_by_index(addr->net, addr->bound_dev_if);
532+
} else {
533+
ndev = rt->dst.dev;
534+
dev_hold(ndev);
535+
}
532536

533537
ip_rt_put(rt);
534538
} else {
@@ -544,13 +548,27 @@ static int addr_resolve(struct sockaddr *src_in,
544548
if (resolve_neigh)
545549
ret = addr_resolve_neigh(dst, dst_in, addr, seq);
546550

547-
ndev = dst->dev;
548-
dev_hold(ndev);
551+
if (addr->bound_dev_if) {
552+
ndev = dev_get_by_index(addr->net, addr->bound_dev_if);
553+
} else {
554+
ndev = dst->dev;
555+
dev_hold(ndev);
556+
}
549557

550558
dst_release(dst);
551559
}
552560

553-
addr->bound_dev_if = ndev->ifindex;
561+
if (ndev->flags & IFF_LOOPBACK) {
562+
ret = rdma_translate_ip(dst_in, addr, NULL);
563+
/*
564+
* Put the loopback device and get the translated
565+
* device instead.
566+
*/
567+
dev_put(ndev);
568+
ndev = dev_get_by_index(addr->net, addr->bound_dev_if);
569+
} else {
570+
addr->bound_dev_if = ndev->ifindex;
571+
}
554572
dev_put(ndev);
555573

556574
return ret;

drivers/infiniband/core/cma.c

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -623,22 +623,11 @@ static inline int cma_validate_port(struct ib_device *device, u8 port,
623623
if ((dev_type != ARPHRD_INFINIBAND) && rdma_protocol_ib(device, port))
624624
return ret;
625625

626-
if (dev_type == ARPHRD_ETHER && rdma_protocol_roce(device, port)) {
626+
if (dev_type == ARPHRD_ETHER && rdma_protocol_roce(device, port))
627627
ndev = dev_get_by_index(&init_net, bound_if_index);
628-
if (ndev && ndev->flags & IFF_LOOPBACK) {
629-
pr_info("detected loopback device\n");
630-
dev_put(ndev);
631-
632-
if (!device->get_netdev)
633-
return -EOPNOTSUPP;
634-
635-
ndev = device->get_netdev(device, port);
636-
if (!ndev)
637-
return -ENODEV;
638-
}
639-
} else {
628+
else
640629
gid_type = IB_GID_TYPE_IB;
641-
}
630+
642631

643632
ret = ib_find_cached_gid_by_port(device, gid, gid_type, port,
644633
ndev, NULL);
@@ -2569,21 +2558,6 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
25692558
goto err2;
25702559
}
25712560

2572-
if (ndev->flags & IFF_LOOPBACK) {
2573-
dev_put(ndev);
2574-
if (!id_priv->id.device->get_netdev) {
2575-
ret = -EOPNOTSUPP;
2576-
goto err2;
2577-
}
2578-
2579-
ndev = id_priv->id.device->get_netdev(id_priv->id.device,
2580-
id_priv->id.port_num);
2581-
if (!ndev) {
2582-
ret = -ENODEV;
2583-
goto err2;
2584-
}
2585-
}
2586-
25872561
supported_gids = roce_gid_type_mask_support(id_priv->id.device,
25882562
id_priv->id.port_num);
25892563
gid_type = cma_route_gid_type(addr->dev_addr.network,

drivers/infiniband/core/verbs.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -520,11 +520,6 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num,
520520
}
521521

522522
resolved_dev = dev_get_by_index(&init_net, if_index);
523-
if (resolved_dev->flags & IFF_LOOPBACK) {
524-
dev_put(resolved_dev);
525-
resolved_dev = idev;
526-
dev_hold(resolved_dev);
527-
}
528523
rcu_read_lock();
529524
if (resolved_dev != idev && !rdma_is_upper_dev_rcu(idev,
530525
resolved_dev))

0 commit comments

Comments
 (0)