Skip to content

Commit 42f993d

Browse files
vladumrleon
authored andcommitted
IB/ipoib: Ignore L3 master device
Currently, all master upper netdevices (e.g., bond, VRF) are treated equally. When a VRF netdevice is used over an IPoIB netdevice, the expected netdev resolution is on the lower IPoIB device which has the IP address assigned to it and not the VRF device. The rdma_cm module (CMA) tries to match incoming requests to a particular netdevice. When successful, it also validates that the return path points to the same device by performing a routing table lookup. Currently, the former would resolve to the VRF netdevice, while the latter to the correct lower IPoIB netdevice, leading to failure in rdma_cm. Improve this by ignoring the VRF master netdevice, if it exists, and instead return the lower IPoIB device. Signed-off-by: Vlad Dumitrescu <vdumitrescu@nvidia.com> Reviewed-by: Parav Pandit <parav@nvidia.com> Signed-off-by: Edward Srouji <edwards@nvidia.com> Link: https://patch.msgid.link/20250916111103.84069-5-edwards@nvidia.com Signed-off-by: Leon Romanovsky <leon@kernel.org>
1 parent c31e403 commit 42f993d

1 file changed

Lines changed: 11 additions & 10 deletions

File tree

drivers/infiniband/ulp/ipoib/ipoib_main.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -351,26 +351,27 @@ static bool ipoib_is_dev_match_addr_rcu(const struct sockaddr *addr,
351351
}
352352

353353
/*
354-
* Find the master net_device on top of the given net_device.
354+
* Find the L2 master net_device on top of the given net_device.
355355
* @dev: base IPoIB net_device
356356
*
357-
* Returns the master net_device with a reference held, or the same net_device
358-
* if no master exists.
357+
* Returns the L2 master net_device with reference held if the L2 master
358+
* exists (such as bond netdevice), or returns same netdev with reference
359+
* held when master does not exist or when L3 master (such as VRF netdev).
359360
*/
360361
static struct net_device *ipoib_get_master_net_dev(struct net_device *dev)
361362
{
362363
struct net_device *master;
363364

364365
rcu_read_lock();
366+
365367
master = netdev_master_upper_dev_get_rcu(dev);
368+
if (!master || netif_is_l3_master(master))
369+
master = dev;
370+
366371
dev_hold(master);
367372
rcu_read_unlock();
368373

369-
if (master)
370-
return master;
371-
372-
dev_hold(dev);
373-
return dev;
374+
return master;
374375
}
375376

376377
struct ipoib_walk_data {
@@ -522,7 +523,7 @@ static struct net_device *ipoib_get_net_dev_by_params(
522523
if (ret)
523524
return NULL;
524525

525-
/* See if we can find a unique device matching the L2 parameters */
526+
/* See if we can find a unique device matching the pkey and GID */
526527
matches = __ipoib_get_net_dev_by_params(dev_list, port, pkey_index,
527528
gid, NULL, &net_dev);
528529

@@ -535,7 +536,7 @@ static struct net_device *ipoib_get_net_dev_by_params(
535536

536537
dev_put(net_dev);
537538

538-
/* Couldn't find a unique device with L2 parameters only. Use L3
539+
/* Couldn't find a unique device with pkey and GID only. Use L3
539540
* address to uniquely match the net device */
540541
matches = __ipoib_get_net_dev_by_params(dev_list, port, pkey_index,
541542
gid, addr, &net_dev);

0 commit comments

Comments
 (0)