Whamcloud - gitweb
LU-11893 o2iblnd: add secondary IP address handling 76/34476/7
authorJames Simmons <uja.ornl@yahoo.com>
Sat, 18 May 2019 22:35:54 +0000 (18:35 -0400)
committerOleg Drokin <green@whamcloud.com>
Sat, 1 Jun 2019 03:55:04 +0000 (03:55 +0000)
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 <uja.ornl@yahoo.com>
Reviewed-on: https://review.whamcloud.com/34476
Reviewed-by: Petros Koutoupis <pkoutoupis@cray.com>
Reviewed-by: Neil Brown <neilb@suse.com>
Tested-by: Jenkins
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lnet/klnds/o2iblnd/o2iblnd.c

index 09ed638..6da280e 100644 (file)
@@ -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=' */