ipv6: recreate ipv6 link-local addresses when increasing MTU over IPV6_MIN_MTU
authorAlexander Duyck <aduyck@mirantis.com>
Mon, 26 Oct 2015 18:06:33 +0000 (11:06 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 30 Oct 2015 09:11:07 +0000 (18:11 +0900)
This change makes it so that we reinitialize the interface if the MTU is
increased back above IPV6_MIN_MTU and the interface is up.

Cc: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv6/addrconf.c

index d0c685cdc3456aa21359365e873b30e650209d23..d72fa90d6feb0122d15d68d6d862e5299d331008 100644 (file)
@@ -3147,6 +3147,32 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
                }
                break;
 
+       case NETDEV_CHANGEMTU:
+               /* if MTU under IPV6_MIN_MTU stop IPv6 on this interface. */
+               if (dev->mtu < IPV6_MIN_MTU) {
+                       addrconf_ifdown(dev, 1);
+                       break;
+               }
+
+               if (idev) {
+                       rt6_mtu_change(dev, dev->mtu);
+                       idev->cnf.mtu6 = dev->mtu;
+                       break;
+               }
+
+               /* allocate new idev */
+               idev = ipv6_add_dev(dev);
+               if (IS_ERR(idev))
+                       break;
+
+               /* device is still not ready */
+               if (!(idev->if_flags & IF_READY))
+                       break;
+
+               run_pending = 1;
+
+               /* fall through */
+
        case NETDEV_UP:
        case NETDEV_CHANGE:
                if (dev->flags & IFF_SLAVE)
@@ -3170,7 +3196,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
                                idev->if_flags |= IF_READY;
                                run_pending = 1;
                        }
-               } else {
+               } else if (event == NETDEV_CHANGE) {
                        if (!addrconf_qdisc_ok(dev)) {
                                /* device is still not ready. */
                                break;
@@ -3235,24 +3261,6 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
                }
                break;
 
-       case NETDEV_CHANGEMTU:
-               if (idev && dev->mtu >= IPV6_MIN_MTU) {
-                       rt6_mtu_change(dev, dev->mtu);
-                       idev->cnf.mtu6 = dev->mtu;
-                       break;
-               }
-
-               if (!idev && dev->mtu >= IPV6_MIN_MTU) {
-                       idev = ipv6_add_dev(dev);
-                       if (!IS_ERR(idev))
-                               break;
-               }
-
-               /*
-                * if MTU under IPV6_MIN_MTU.
-                * Stop IPv6 on this interface.
-                */
-
        case NETDEV_DOWN:
        case NETDEV_UNREGISTER:
                /*