From: Eric Dumazet <eric.duma...@gmail.com>
Date: Fri, 04 Mar 2016 16:08:30 -0800

> __inet_del_ifa() should probably take into account in_dev->dead (no
> promotion, no list scan...)

Indeed, that is the real problem:

diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 8c3df2c..7412feb 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -334,6 +334,12 @@ static void __inet_del_ifa(struct in_device *in_dev, 
struct in_ifaddr **ifap,
 
        ASSERT_RTNL();
 
+       /* None of these potentially quadratic scans matter if the
+        * device is being destroyed.
+        */
+       if (in_dev->dead)
+               goto no_promotions;
+
        /* 1. Deleting primary ifaddr forces deletion all secondaries
         * unless alias promotion is set
         **/
@@ -380,6 +386,7 @@ static void __inet_del_ifa(struct in_device *in_dev, struct 
in_ifaddr **ifap,
                        fib_del_ifaddr(ifa, ifa1);
        }
 
+no_promotions:
        /* 2. Unlink it */
 
        *ifap = ifa1->ifa_next;

Reply via email to