From b4748cb4684f5b2594d127b29f3876f07bd077ee Mon Sep 17 00:00:00 2001 From: Serguei Smirnov Date: Thu, 16 Jan 2025 18:10:28 -0800 Subject: [PATCH] LU-18644 socklnd: make link state detection namespace-aware 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 Change-Id: I589399c0f2f85e5abd50d55079b79c44e30b4401 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/57808 Tested-by: jenkins Tested-by: Maloo Reviewed-by: James Simmons Reviewed-by: Chris Horn Reviewed-by: Frank Sehr Reviewed-by: Adam Peace Reviewed-by: Oleg Drokin --- lnet/klnds/socklnd/socklnd.c | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/lnet/klnds/socklnd/socklnd.c b/lnet/klnds/socklnd/socklnd.c index 447ebb4..afec9d3 100644 --- a/lnet/klnds/socklnd/socklnd.c +++ b/lnet/klnds/socklnd/socklnd.c @@ -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: -- 1.8.3.1