From: Chuck Lever <chuck.lever@xxxxxxxxxx> In the past, LOOPBACK and NONE (tunnel) devices had all-zero MAC addresses. siw_device_create() would fall back to copying the device's name in those cases, because an all-zero MAC address breaks the RDMA core IP-to-device lookup mechanism. However, in some cases, the net_device::name field is also empty. So we're back at square one. Rather than checking the device type, look at the net_device::addr_len field. If it's got the right number of octets and it is not all zeroes, use that. Then, to enable siw support for that device/address type, change the device driver to ensure such devices have a valid 6-octet MAC address. For virtual devices, using eth_hw_addr_random() is sufficient. Fixes: a2d36b02c15d ("RDMA/siw: Enable siw on tunnel devices") Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx> --- drivers/infiniband/sw/siw/siw_main.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/infiniband/sw/siw/siw_main.c b/drivers/infiniband/sw/siw/siw_main.c index 65b5cda5457b..2c31bf397993 100644 --- a/drivers/infiniband/sw/siw/siw_main.c +++ b/drivers/infiniband/sw/siw/siw_main.c @@ -304,10 +304,15 @@ static const struct ib_device_ops siw_device_ops = { static struct siw_device *siw_device_create(struct net_device *netdev) { + static const u8 zeromac[ETH_ALEN] = { 0 }; struct siw_device *sdev = NULL; struct ib_device *base_dev; int rv; + if ((netdev->addr_len != ETH_ALEN) || + (memcmp(netdev->dev_addr, zeromac, ETH_ALEN) == 0)) + return NULL; + sdev = ib_alloc_device(siw_device, base_dev); if (!sdev) return NULL; @@ -316,21 +321,8 @@ static struct siw_device *siw_device_create(struct net_device *netdev) sdev->netdev = netdev; - if (netdev->type != ARPHRD_LOOPBACK && netdev->type != ARPHRD_NONE) { - addrconf_addr_eui48((unsigned char *)&base_dev->node_guid, - netdev->dev_addr); - } else { - /* - * This device does not have a HW address, - * but connection mangagement lib expects gid != 0 - */ - size_t len = min_t(size_t, strlen(base_dev->name), 6); - char addr[6] = { }; - - memcpy(addr, base_dev->name, len); - addrconf_addr_eui48((unsigned char *)&base_dev->node_guid, - addr); - } + addrconf_addr_eui48((unsigned char *)&base_dev->node_guid, + netdev->dev_addr); base_dev->uverbs_cmd_mask |= BIT_ULL(IB_USER_VERBS_CMD_POST_SEND);