From c4b39bf56bbcacd49d7f888a0745cd4b5580b36b Mon Sep 17 00:00:00 2001 From: James Simmons Date: Sat, 18 May 2019 18:35:54 -0400 Subject: [PATCH] LU-11893 o2iblnd: add secondary IP address handling Using dev_get_by_name() in kiblnd_create_dev() means we can only discover primary IP addresses. This breaks using network aliasing which some people use. Move away from dev_get_by_name() to using for_ifa() so we can detect any secondary IP addresses. Change-Id: I03f2f8d18118b716a5eb5fb87694000ac06fe242 Signed-off-by: James Simmons Reviewed-on: https://review.whamcloud.com/34476 Reviewed-by: Petros Koutoupis Reviewed-by: Neil Brown Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- lnet/klnds/o2iblnd/o2iblnd.c | 90 ++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 40 deletions(-) diff --git a/lnet/klnds/o2iblnd/o2iblnd.c b/lnet/klnds/o2iblnd/o2iblnd.c index 09ed638..6da280e 100644 --- a/lnet/klnds/o2iblnd/o2iblnd.c +++ b/lnet/klnds/o2iblnd/o2iblnd.c @@ -2875,68 +2875,73 @@ static struct kib_dev * kiblnd_create_dev(char *ifname) { struct net_device *netdev; - struct in_device *in_dev; - struct kib_dev *dev; + struct kib_dev *dev = NULL; int flags; int rc; rtnl_lock(); - netdev = dev_get_by_name(&init_net, ifname); - if (!netdev) { - CERROR("Can't find IPoIB interface %s\n", - ifname); - goto unlock; - } + for_each_netdev(&init_net, netdev) { + struct in_device *in_dev; - flags = dev_get_flags(netdev); - if (!(flags & IFF_UP)) { - CERROR("Can't query IPoIB interface %s: it's down\n", ifname); - goto unlock; - } + if (strcmp(netdev->name, "lo") == 0) /* skip the loopback IF */ + continue; - LIBCFS_ALLOC(dev, sizeof(*dev)); - if (!dev) - goto unlock; + flags = dev_get_flags(netdev); + if (!(flags & IFF_UP)) { + CERROR("Can't query IPoIB interface %s: it's down\n", + netdev->name); + goto unlock; + } - dev->ibd_can_failover = !!(flags & IFF_MASTER); + in_dev = __in_dev_get_rtnl(netdev); + if (!in_dev) { + CWARN("Interface %s has no IPv4 status.\n", + netdev->name); + goto unlock; + } - INIT_LIST_HEAD(&dev->ibd_nets); - INIT_LIST_HEAD(&dev->ibd_list); /* not yet in kib_devs */ - INIT_LIST_HEAD(&dev->ibd_fail_list); + for_ifa(in_dev) + if (strcmp(ifname, ifa->ifa_label) == 0) { + LIBCFS_ALLOC(dev, sizeof(*dev)); + if (!dev) + goto unlock; - in_dev = __in_dev_get_rtnl(netdev); - if (!in_dev) { - kfree(dev); - goto unlock; - } + dev->ibd_can_failover = !!(flags & IFF_MASTER); + dev->ibd_ifip = ntohl(ifa->ifa_local); - for_primary_ifa(in_dev) - if (strcmp(ifa->ifa_label, ifname) == 0) { - dev->ibd_ifip = ntohl(ifa->ifa_local); - break; - } - endfor_ifa(in_dev); + INIT_LIST_HEAD(&dev->ibd_nets); + INIT_LIST_HEAD(&dev->ibd_list); /* not yet in kib_devs */ + INIT_LIST_HEAD(&dev->ibd_fail_list); + break; + } + endfor_ifa(in_dev); + } rtnl_unlock(); + if (!dev) { + CERROR("Can't find any usable interfaces\n"); + return NULL; + } + if (dev->ibd_ifip == 0) { CERROR("Can't initialize device: no IP address\n"); - LIBCFS_FREE(dev, sizeof(*dev)); - return NULL; + goto free_dev; } strcpy(&dev->ibd_ifname[0], ifname); - /* initialize the device */ - rc = kiblnd_dev_failover(dev); - if (rc != 0) { - CERROR("Can't initialize device: %d\n", rc); - LIBCFS_FREE(dev, sizeof(*dev)); - return NULL; - } + /* initialize the device */ + rc = kiblnd_dev_failover(dev); + if (rc != 0) { + CERROR("Can't initialize device: %d\n", rc); + goto free_dev; + } list_add_tail(&dev->ibd_list, &kiblnd_data.kib_devs); return dev; unlock: rtnl_unlock(); +free_dev: + LIBCFS_FREE(dev, sizeof(*dev)); return NULL; } @@ -3307,6 +3312,11 @@ kiblnd_startup(struct lnet_ni *ni) kiblnd_tunables_setup(ni); + /* + * ni_interfaces is only to support legacy pre Multi-Rail + * tcp bonding for ksocklnd. Multi-Rail wants each secondary + * IP to be treated as an unique 'struct ni' interfaces instead. + */ if (ni->ni_interfaces[0] != NULL) { /* Use the IPoIB interface specified in 'networks=' */ -- 1.8.3.1