Whamcloud - gitweb
LU-18644 socklnd: make link state detection namespace-aware 08/57808/2
authorSerguei Smirnov <ssmirnov@whamcloud.com>
Fri, 17 Jan 2025 02:10:28 +0000 (18:10 -0800)
committerOleg Drokin <green@whamcloud.com>
Sun, 2 Feb 2025 06:30:49 +0000 (06:30 +0000)
Check the network namespace of the device in the event against
the namespace associated with the ni and ignore events from
non-matching namespaces

Test-Parameters: trivial testlist=sanity-lnet
Signed-off-by: Serguei Smirnov <ssmirnov@whamcloud.com>
Change-Id: I589399c0f2f85e5abd50d55079b79c44e30b4401
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/57808
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Chris Horn <chris.horn@hpe.com>
Reviewed-by: Frank Sehr <fsehr@whamcloud.com>
Reviewed-by: Adam Peace <adam.peace@microsoft.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lnet/klnds/socklnd/socklnd.c

index 447ebb4..afec9d3 100644 (file)
@@ -1989,6 +1989,7 @@ ksocknal_handle_link_state_change(struct net_device *dev,
        u32 ni_state_before;
        bool update_ping_buf = false;
        int state;
+       struct net *dev_netns = dev_net(dev);
 
        link_down = !((operstate == IF_OPER_UP) || (operstate == IF_OPER_UNKNOWN));
        ifindex = dev->ifindex;
@@ -2000,6 +2001,14 @@ ksocknal_handle_link_state_change(struct net_device *dev,
                                 ksnn_list) {
                ksi = &net->ksnn_interface;
                found_ip = false;
+               ni = net->ksnn_ni;
+
+               /* Skip devices from a different namespace */
+               if (!net_eq(dev_netns, ni->ni_net_ns)) {
+                       CDEBUG(D_NET, "Skipping device %s from namespace %p (expected %p)\n",
+                              dev->name, dev_netns, ni->ni_net_ns);
+                       continue;
+               }
 
                if (strcmp(ksi->ksni_name, dev->name))
                        continue;
@@ -2025,8 +2034,6 @@ ksocknal_handle_link_state_change(struct net_device *dev,
                        goto out;
                }
 
-               ni = net->ksnn_ni;
-
                sa = (void *)&ksi->ksni_addr;
                switch (sa->sa_family) {
                case AF_INET: {
@@ -2123,6 +2130,7 @@ ksocknal_handle_inetaddr_change(struct net_device *event_netdev, unsigned long e
        u32 ni_state_before;
        bool update_ping_buf = false;
        bool link_down;
+       struct net *dev_netns = dev_net(event_netdev);
 
        if (!ksocknal_data.ksnd_nnets)
                goto out;
@@ -2133,12 +2141,19 @@ ksocknal_handle_inetaddr_change(struct net_device *event_netdev, unsigned long e
                                 ksnn_list) {
                ksi = &net->ksnn_interface;
                sa = (void *)&ksi->ksni_addr;
+               ni = net->ksnn_ni;
+
+               /* Skip devices from a different namespace */
+               if (!net_eq(dev_netns, ni->ni_net_ns)) {
+                       CDEBUG(D_NET, "Skipping device %s from namespace %p (expected %p)\n",
+                              event_netdev->name, dev_netns, ni->ni_net_ns);
+                       continue;
+               }
 
                if (ksi->ksni_index != ifindex ||
                    strcmp(ksi->ksni_name, event_netdev->name))
                        continue;
 
-               ni = net->ksnn_ni;
                if (nid_is_nid4(&ni->ni_nid) ^ (sa->sa_family == AF_INET))
                        continue;
 
@@ -2166,11 +2181,13 @@ static int ksocknal_device_event(struct notifier_block *unused,
 {
        struct net_device *dev = netdev_notifier_info_to_dev(ptr);
        unsigned char operstate;
+       struct net *dev_netns = dev_net(dev);
 
        operstate = dev->operstate;
 
-       CDEBUG(D_NET, "devevent: status=%s, iface=%s ifindex %d state %u\n",
-              netdev_cmd_to_name(event), dev->name, dev->ifindex, operstate);
+       CDEBUG(D_NET, "devevent: status=%s, iface=%s ifindex %d state %u ns %p \n",
+              netdev_cmd_to_name(event), dev->name, dev->ifindex, operstate,
+              dev_netns);
 
        switch (event) {
        case NETDEV_UP:
@@ -2192,10 +2209,11 @@ static int ksocknal_inetaddr_event(struct notifier_block *unused,
                                   unsigned long event, void *ptr)
 {
        struct in_ifaddr *ifa = ptr;
+       struct net *dev_netns = dev_net(ifa->ifa_dev->dev);
 
-       CDEBUG(D_NET, "addrevent: status %s device %s, ip addr %pI4, netmask %pI4.\n",
+       CDEBUG(D_NET, "addrevent: status %s device %s, ip addr %pI4, netmask %pI4 ns %p.\n",
                netdev_cmd_to_name(event), ifa->ifa_dev->dev->name,
-               &ifa->ifa_address, &ifa->ifa_mask);
+               &ifa->ifa_address, &ifa->ifa_mask, dev_netns);
 
        switch (event) {
        case NETDEV_UP:
@@ -2221,9 +2239,11 @@ static int ksocknal_inet6addr_event(struct notifier_block *this,
                                    unsigned long event, void *ptr)
 {
        struct inet6_ifaddr *ifa6 = ptr;
+       struct net *dev_netns = dev_net(ifa6->idev->dev);
 
-       CDEBUG(D_NET, "addr6event: status %s, device %s, ip addr %pISc\n",
-               netdev_cmd_to_name(event), ifa6->idev->dev->name, &ifa6->addr);
+       CDEBUG(D_NET, "addr6event: status %s, device %s, ip addr %pISc, ns %p\n",
+               netdev_cmd_to_name(event), ifa6->idev->dev->name, &ifa6->addr,
+               dev_netns);
 
        switch (event) {
        case NETDEV_UP: