]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
RDMA/irdma: Fix netdev notifications for vlan's
authorMustafa Ismail <mustafa.ismail@intel.com>
Fri, 25 Feb 2022 16:32:09 +0000 (10:32 -0600)
committerStefan Bader <stefan.bader@canonical.com>
Fri, 20 May 2022 12:39:04 +0000 (14:39 +0200)
BugLink: https://bugs.launchpad.net/bugs/1969110
[ Upstream commit 6702bc14744847842a87fed21a795b6e8bab6965 ]

Currently, events on vlan netdevs are being ignored. Fix this by finding
the real netdev and processing the notifications for vlan netdevs.

Fixes: 915cc7ac0f8e ("RDMA/irdma: Add miscellaneous utility definitions")
Link: https://lore.kernel.org/r/20220225163211.127-2-shiraz.saleem@intel.com
Signed-off-by: Mustafa Ismail <mustafa.ismail@intel.com>
Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
(cherry picked from commit 5e96bb45c9363c5329399e7c369aba21494e7591)
Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
drivers/infiniband/hw/irdma/utils.c

index feebfe6bf31ad92145b2a54c21f8e803d0ad543d..fee179fd8c67b6f87826e6fc2f92aa4a3f6fdd86 100644 (file)
@@ -150,31 +150,35 @@ int irdma_inetaddr_event(struct notifier_block *notifier, unsigned long event,
                         void *ptr)
 {
        struct in_ifaddr *ifa = ptr;
-       struct net_device *netdev = ifa->ifa_dev->dev;
+       struct net_device *real_dev, *netdev = ifa->ifa_dev->dev;
        struct irdma_device *iwdev;
        struct ib_device *ibdev;
        u32 local_ipaddr;
 
-       ibdev = ib_device_get_by_netdev(netdev, RDMA_DRIVER_IRDMA);
+       real_dev = rdma_vlan_dev_real_dev(netdev);
+       if (!real_dev)
+               real_dev = netdev;
+
+       ibdev = ib_device_get_by_netdev(real_dev, RDMA_DRIVER_IRDMA);
        if (!ibdev)
                return NOTIFY_DONE;
 
        iwdev = to_iwdev(ibdev);
        local_ipaddr = ntohl(ifa->ifa_address);
        ibdev_dbg(&iwdev->ibdev,
-                 "DEV: netdev %p event %lu local_ip=%pI4 MAC=%pM\n", netdev,
-                 event, &local_ipaddr, netdev->dev_addr);
+                 "DEV: netdev %p event %lu local_ip=%pI4 MAC=%pM\n", real_dev,
+                 event, &local_ipaddr, real_dev->dev_addr);
        switch (event) {
        case NETDEV_DOWN:
-               irdma_manage_arp_cache(iwdev->rf, netdev->dev_addr,
+               irdma_manage_arp_cache(iwdev->rf, real_dev->dev_addr,
                                       &local_ipaddr, true, IRDMA_ARP_DELETE);
-               irdma_if_notify(iwdev, netdev, &local_ipaddr, true, false);
+               irdma_if_notify(iwdev, real_dev, &local_ipaddr, true, false);
                irdma_gid_change_event(&iwdev->ibdev);
                break;
        case NETDEV_UP:
        case NETDEV_CHANGEADDR:
-               irdma_add_arp(iwdev->rf, &local_ipaddr, true, netdev->dev_addr);
-               irdma_if_notify(iwdev, netdev, &local_ipaddr, true, true);
+               irdma_add_arp(iwdev->rf, &local_ipaddr, true, real_dev->dev_addr);
+               irdma_if_notify(iwdev, real_dev, &local_ipaddr, true, true);
                irdma_gid_change_event(&iwdev->ibdev);
                break;
        default:
@@ -196,32 +200,36 @@ int irdma_inet6addr_event(struct notifier_block *notifier, unsigned long event,
                          void *ptr)
 {
        struct inet6_ifaddr *ifa = ptr;
-       struct net_device *netdev = ifa->idev->dev;
+       struct net_device *real_dev, *netdev = ifa->idev->dev;
        struct irdma_device *iwdev;
        struct ib_device *ibdev;
        u32 local_ipaddr6[4];
 
-       ibdev = ib_device_get_by_netdev(netdev, RDMA_DRIVER_IRDMA);
+       real_dev = rdma_vlan_dev_real_dev(netdev);
+       if (!real_dev)
+               real_dev = netdev;
+
+       ibdev = ib_device_get_by_netdev(real_dev, RDMA_DRIVER_IRDMA);
        if (!ibdev)
                return NOTIFY_DONE;
 
        iwdev = to_iwdev(ibdev);
        irdma_copy_ip_ntohl(local_ipaddr6, ifa->addr.in6_u.u6_addr32);
        ibdev_dbg(&iwdev->ibdev,
-                 "DEV: netdev %p event %lu local_ip=%pI6 MAC=%pM\n", netdev,
-                 event, local_ipaddr6, netdev->dev_addr);
+                 "DEV: netdev %p event %lu local_ip=%pI6 MAC=%pM\n", real_dev,
+                 event, local_ipaddr6, real_dev->dev_addr);
        switch (event) {
        case NETDEV_DOWN:
-               irdma_manage_arp_cache(iwdev->rf, netdev->dev_addr,
+               irdma_manage_arp_cache(iwdev->rf, real_dev->dev_addr,
                                       local_ipaddr6, false, IRDMA_ARP_DELETE);
-               irdma_if_notify(iwdev, netdev, local_ipaddr6, false, false);
+               irdma_if_notify(iwdev, real_dev, local_ipaddr6, false, false);
                irdma_gid_change_event(&iwdev->ibdev);
                break;
        case NETDEV_UP:
        case NETDEV_CHANGEADDR:
                irdma_add_arp(iwdev->rf, local_ipaddr6, false,
-                             netdev->dev_addr);
-               irdma_if_notify(iwdev, netdev, local_ipaddr6, false, true);
+                             real_dev->dev_addr);
+               irdma_if_notify(iwdev, real_dev, local_ipaddr6, false, true);
                irdma_gid_change_event(&iwdev->ibdev);
                break;
        default:
@@ -243,14 +251,18 @@ int irdma_net_event(struct notifier_block *notifier, unsigned long event,
                    void *ptr)
 {
        struct neighbour *neigh = ptr;
+       struct net_device *real_dev, *netdev = (struct net_device *)neigh->dev;
        struct irdma_device *iwdev;
        struct ib_device *ibdev;
        __be32 *p;
        u32 local_ipaddr[4] = {};
        bool ipv4 = true;
 
-       ibdev = ib_device_get_by_netdev((struct net_device *)neigh->dev,
-                                       RDMA_DRIVER_IRDMA);
+       real_dev = rdma_vlan_dev_real_dev(netdev);
+       if (!real_dev)
+               real_dev = netdev;
+
+       ibdev = ib_device_get_by_netdev(real_dev, RDMA_DRIVER_IRDMA);
        if (!ibdev)
                return NOTIFY_DONE;