Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 187926
b: refs/heads/master
c: 84e8b80
h: refs/heads/master
v: v3
  • Loading branch information
stephen hemminger authored and David S. Miller committed Mar 4, 2010
1 parent 384ff04 commit d8ddaba
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 18 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5b2a19539c5f59c5a038d213ede723f0245d97cf
refs/heads/master: 84e8b803f1e16f3a2b8b80f80a63fa2f2f8a9be6
46 changes: 29 additions & 17 deletions trunk/net/ipv6/addrconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2649,11 +2649,11 @@ static int addrconf_ifdown(struct net_device *dev, int how)
write_lock_bh(&addrconf_hash_lock);
while ((ifa = *bifa) != NULL) {
if (ifa->idev == idev &&
(how || !(ifa->flags&IFA_F_PERMANENT))) {
(how || !(ifa->flags&IFA_F_PERMANENT) ||
ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) {
*bifa = ifa->lst_next;
ifa->lst_next = NULL;
addrconf_del_timer(ifa);
in6_ifa_put(ifa);
__in6_ifa_put(ifa);
continue;
}
bifa = &ifa->lst_next;
Expand Down Expand Up @@ -2691,28 +2691,40 @@ static int addrconf_ifdown(struct net_device *dev, int how)
#endif
bifa = &idev->addr_list;
while ((ifa = *bifa) != NULL) {
if (how == 0 && (ifa->flags&IFA_F_PERMANENT)) {
/* Retain permanent address on admin down */
addrconf_del_timer(ifa);

/* If just doing link down, and address is permanent
and not link-local, then retain it. */
if (how == 0 &&
(ifa->flags&IFA_F_PERMANENT) &&
!(ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) {
bifa = &ifa->if_next;

/* Restart DAD if needed when link comes back up */
if ( !((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) ||
idev->cnf.accept_dad <= 0 ||
(ifa->flags & IFA_F_NODAD)))
ifa->flags |= IFA_F_TENTATIVE;
/* If not doing DAD on this address, just keep it. */
if ((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) ||
idev->cnf.accept_dad <= 0 ||
(ifa->flags & IFA_F_NODAD))
continue;

/* If it was tentative already, no need to notify */
if (ifa->flags & IFA_F_TENTATIVE)
continue;

/* Flag it for later restoration when link comes up */
ifa->flags |= IFA_F_TENTATIVE;
in6_ifa_hold(ifa);
} else {
*bifa = ifa->if_next;
ifa->if_next = NULL;

ifa->dead = 1;
write_unlock_bh(&idev->lock);
}
write_unlock_bh(&idev->lock);

__ipv6_ifa_notify(RTM_DELADDR, ifa);
atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa);
in6_ifa_put(ifa);
__ipv6_ifa_notify(RTM_DELADDR, ifa);
atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa);
in6_ifa_put(ifa);

write_lock_bh(&idev->lock);
}
write_lock_bh(&idev->lock);
}
write_unlock_bh(&idev->lock);

Expand Down

0 comments on commit d8ddaba

Please sign in to comment.