From 4a32b9e7c097b1323131a182ddf4ff5e9b3d5e89 Mon Sep 17 00:00:00 2001 From: Krishna Kumar Date: Sat, 8 Nov 2003 06:33:05 -0800 Subject: [PATCH] [IPV6]: Fix hangs during interface down caused by ipv6_del_addr(). While using PRIVACY extensions, I sometimes get a hang when I remove the interface. But I can reproduce this every time using the test script at the end of the mail (hang depends on the order of address deletion). The bug is in ipv6_del_addr() where if a temp address is being deleted, it does an __in6_ifa_put() of the main address from which it was derived (basically the autoconf prefix address). So if the main address was deleted first, it's ifp ref count would be 1 and it would 'wait' to be freed till it's temp address was freed first. When the temp address is deleted, the __put() routine drops the main address's ifp ref count to 0, but not free it. unregister_netdevice() hangs giving message that ref count is 1. Fix tested overnight. Also, the code at the top of the routine is unnecessary, the same is being done when the address is found a little later in that routine. --- net/ipv6/addrconf.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index b73feae5c291b..457b6c044a3ae 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -571,15 +571,6 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) ifp->dead = 1; -#ifdef CONFIG_IPV6_PRIVACY - spin_lock_bh(&ifp->lock); - if (ifp->ifpub) { - __in6_ifa_put(ifp->ifpub); - ifp->ifpub = NULL; - } - spin_unlock_bh(&ifp->lock); -#endif - write_lock_bh(&addrconf_hash_lock); for (ifap = &inet6_addr_lst[hash]; (ifa=*ifap) != NULL; ifap = &ifa->lst_next) { @@ -600,7 +591,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) if (ifa == ifp) { *ifap = ifa->tmp_next; if (ifp->ifpub) { - __in6_ifa_put(ifp->ifpub); + in6_ifa_put(ifp->ifpub); ifp->ifpub = NULL; } __in6_ifa_put(ifp); -- 2.53.0