@@ -720,13 +720,18 @@ static void ipv6_del_addr(struct inet6_i
hash = ipv6_addr_hash(&ifp->addr);
+ write_lock_bh(&idev->lock);
+ if (ifp->dead) {
+ write_unlock(&idev->lock); /* lost race with DAD */
+ return;
+ }
+
ifp->dead = 1;
- spin_lock_bh(&addrconf_hash_lock);
+ spin_lock(&addrconf_hash_lock);
hlist_del_init_rcu(&ifp->addr_lst);
- spin_unlock_bh(&addrconf_hash_lock);
+ spin_unlock(&addrconf_hash_lock);
- write_lock_bh(&idev->lock);
#ifdef CONFIG_IPV6_PRIVACY
if (ifp->flags&IFA_F_TEMPORARY) {
list_del(&ifp->tmp_list);