aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv6/addrconf.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 75d3b8c1e856..4e5ad9de1679 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -553,7 +553,7 @@ void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp)
553 if (del_timer(&ifp->timer)) 553 if (del_timer(&ifp->timer))
554 pr_notice("Timer is still running, when freeing ifa=%p\n", ifp); 554 pr_notice("Timer is still running, when freeing ifa=%p\n", ifp);
555 555
556 if (!ifp->dead) { 556 if (ifp->state != INET6_IFADDR_STATE_DEAD) {
557 pr_warning("Freeing alive inet6 address %p\n", ifp); 557 pr_warning("Freeing alive inet6 address %p\n", ifp);
558 return; 558 return;
559 } 559 }
@@ -648,6 +648,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
648 ipv6_addr_copy(&ifa->addr, addr); 648 ipv6_addr_copy(&ifa->addr, addr);
649 649
650 spin_lock_init(&ifa->lock); 650 spin_lock_init(&ifa->lock);
651 spin_lock_init(&ifa->state_lock);
651 init_timer(&ifa->timer); 652 init_timer(&ifa->timer);
652 INIT_HLIST_NODE(&ifa->addr_lst); 653 INIT_HLIST_NODE(&ifa->addr_lst);
653 ifa->timer.data = (unsigned long) ifa; 654 ifa->timer.data = (unsigned long) ifa;
@@ -720,7 +721,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
720 721
721 hash = ipv6_addr_hash(&ifp->addr); 722 hash = ipv6_addr_hash(&ifp->addr);
722 723
723 ifp->dead = 1; 724 ifp->state = INET6_IFADDR_STATE_DEAD;
724 725
725 spin_lock_bh(&addrconf_hash_lock); 726 spin_lock_bh(&addrconf_hash_lock);
726 hlist_del_init_rcu(&ifp->addr_lst); 727 hlist_del_init_rcu(&ifp->addr_lst);
@@ -2665,7 +2666,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2665 ifa = list_first_entry(&idev->tempaddr_list, 2666 ifa = list_first_entry(&idev->tempaddr_list,
2666 struct inet6_ifaddr, tmp_list); 2667 struct inet6_ifaddr, tmp_list);
2667 list_del(&ifa->tmp_list); 2668 list_del(&ifa->tmp_list);
2668 ifa->dead = 1; 2669 ifa->state = INET6_IFADDR_STATE_DEAD;
2669 write_unlock_bh(&idev->lock); 2670 write_unlock_bh(&idev->lock);
2670 spin_lock_bh(&ifa->lock); 2671 spin_lock_bh(&ifa->lock);
2671 2672
@@ -2707,7 +2708,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2707 write_unlock_bh(&idev->lock); 2708 write_unlock_bh(&idev->lock);
2708 } else { 2709 } else {
2709 list_del(&ifa->if_list); 2710 list_del(&ifa->if_list);
2710 ifa->dead = 1; 2711 ifa->state = INET6_IFADDR_STATE_DEAD;
2711 write_unlock_bh(&idev->lock); 2712 write_unlock_bh(&idev->lock);
2712 2713
2713 /* clear hash table */ 2714 /* clear hash table */
@@ -2717,7 +2718,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2717 } 2718 }
2718 2719
2719 __ipv6_ifa_notify(RTM_DELADDR, ifa); 2720 __ipv6_ifa_notify(RTM_DELADDR, ifa);
2720 if (ifa->dead) 2721 if (ifa->state == INET6_IFADDR_STATE_DEAD)
2721 atomic_notifier_call_chain(&inet6addr_chain, 2722 atomic_notifier_call_chain(&inet6addr_chain,
2722 NETDEV_DOWN, ifa); 2723 NETDEV_DOWN, ifa);
2723 in6_ifa_put(ifa); 2724 in6_ifa_put(ifa);
@@ -2815,7 +2816,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
2815 net_srandom(ifp->addr.s6_addr32[3]); 2816 net_srandom(ifp->addr.s6_addr32[3]);
2816 2817
2817 read_lock_bh(&idev->lock); 2818 read_lock_bh(&idev->lock);
2818 if (ifp->dead) 2819 if (ifp->state == INET6_IFADDR_STATE_DEAD)
2819 goto out; 2820 goto out;
2820 2821
2821 spin_lock(&ifp->lock); 2822 spin_lock(&ifp->lock);
@@ -4050,7 +4051,8 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
4050 addrconf_leave_solict(ifp->idev, &ifp->addr); 4051 addrconf_leave_solict(ifp->idev, &ifp->addr);
4051 dst_hold(&ifp->rt->u.dst); 4052 dst_hold(&ifp->rt->u.dst);
4052 4053
4053 if (ifp->dead && ip6_del_rt(ifp->rt)) 4054 if (ifp->state == INET6_IFADDR_STATE_DEAD &&
4055 ip6_del_rt(ifp->rt))
4054 dst_free(&ifp->rt->u.dst); 4056 dst_free(&ifp->rt->u.dst);
4055 break; 4057 break;
4056 } 4058 }