From: Eric Dumazet <[email protected]>
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;