net: ipv6: Do not keep linklocal and loopback addresses
f1705ec197
added the option to retain user configured addresses on an admin down. A comment to one of the later revisions suggested using the IFA_F_PERMANENT flag rather than adding a user_managed boolean to the ifaddr struct. A side effect of this change is that link local and loopback addresses are also retained which is not part of the objective off1705ec197
. Add check to drop those addresses. Fixes:f1705ec197
("net: ipv6: Make address flushing on ifdown optional") Signed-off-by: David Ahern <dsa@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
a6d37131c0
commit
70af921db6
|
@ -3448,6 +3448,12 @@ static void addrconf_type_change(struct net_device *dev, unsigned long event)
|
||||||
ipv6_mc_unmap(idev);
|
ipv6_mc_unmap(idev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool addr_is_local(const struct in6_addr *addr)
|
||||||
|
{
|
||||||
|
return ipv6_addr_type(addr) &
|
||||||
|
(IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK);
|
||||||
|
}
|
||||||
|
|
||||||
static int addrconf_ifdown(struct net_device *dev, int how)
|
static int addrconf_ifdown(struct net_device *dev, int how)
|
||||||
{
|
{
|
||||||
struct net *net = dev_net(dev);
|
struct net *net = dev_net(dev);
|
||||||
|
@ -3505,7 +3511,8 @@ restart:
|
||||||
* address is retained on a down event
|
* address is retained on a down event
|
||||||
*/
|
*/
|
||||||
if (!keep_addr ||
|
if (!keep_addr ||
|
||||||
!(ifa->flags & IFA_F_PERMANENT)) {
|
!(ifa->flags & IFA_F_PERMANENT) ||
|
||||||
|
addr_is_local(&ifa->addr)) {
|
||||||
hlist_del_init_rcu(&ifa->addr_lst);
|
hlist_del_init_rcu(&ifa->addr_lst);
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
|
@ -3554,7 +3561,8 @@ restart:
|
||||||
write_unlock_bh(&idev->lock);
|
write_unlock_bh(&idev->lock);
|
||||||
spin_lock_bh(&ifa->lock);
|
spin_lock_bh(&ifa->lock);
|
||||||
|
|
||||||
if (keep_addr && (ifa->flags & IFA_F_PERMANENT)) {
|
if (keep_addr && (ifa->flags & IFA_F_PERMANENT) &&
|
||||||
|
!addr_is_local(&ifa->addr)) {
|
||||||
/* set state to skip the notifier below */
|
/* set state to skip the notifier below */
|
||||||
state = INET6_IFADDR_STATE_DEAD;
|
state = INET6_IFADDR_STATE_DEAD;
|
||||||
ifa->state = 0;
|
ifa->state = 0;
|
||||||
|
|
Loading…
Reference in a new issue