Skip to content

Commit

Permalink
ipv6: Never schedule DAD timer on dead address
Browse files Browse the repository at this point in the history
This patch ensures that all places that schedule the DAD timer
look at the address state in a safe manner before scheduling the
timer.  This ensures that we don't end up with pending timers
after deleting an address.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Herbert Xu authored and David S. Miller committed May 18, 2010
1 parent f2344a1 commit 622ccdf
Showing 1 changed file with 8 additions and 2 deletions.
10 changes: 8 additions & 2 deletions net/ipv6/addrconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2853,10 +2853,10 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
net_srandom(ifp->addr.s6_addr32[3]);

read_lock_bh(&idev->lock);
spin_lock(&ifp->lock);
if (ifp->state == INET6_IFADDR_STATE_DEAD)
goto out;

spin_lock(&ifp->lock);
if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
idev->cnf.accept_dad < 1 ||
!(ifp->flags&IFA_F_TENTATIVE) ||
Expand Down Expand Up @@ -2890,8 +2890,8 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
ip6_ins_rt(ifp->rt);

addrconf_dad_kick(ifp);
spin_unlock(&ifp->lock);
out:
spin_unlock(&ifp->lock);
read_unlock_bh(&idev->lock);
}

Expand All @@ -2911,6 +2911,12 @@ static void addrconf_dad_timer(unsigned long data)
}

spin_lock(&ifp->lock);
if (ifp->state == INET6_IFADDR_STATE_DEAD) {
spin_unlock(&ifp->lock);
read_unlock(&idev->lock);
goto out;
}

if (ifp->probes == 0) {
/*
* DAD was successful
Expand Down

0 comments on commit 622ccdf

Please sign in to comment.