Skip to content

Commit 70af921

Browse files
David Aherndavem330
authored andcommitted
net: ipv6: Do not keep linklocal and loopback addresses
f1705ec 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 of f1705ec. Add check to drop those addresses. Fixes: f1705ec ("net: ipv6: Make address flushing on ifdown optional") Signed-off-by: David Ahern <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent a6d3713 commit 70af921

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

net/ipv6/addrconf.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3448,6 +3448,12 @@ static void addrconf_type_change(struct net_device *dev, unsigned long event)
34483448
ipv6_mc_unmap(idev);
34493449
}
34503450

3451+
static bool addr_is_local(const struct in6_addr *addr)
3452+
{
3453+
return ipv6_addr_type(addr) &
3454+
(IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK);
3455+
}
3456+
34513457
static int addrconf_ifdown(struct net_device *dev, int how)
34523458
{
34533459
struct net *net = dev_net(dev);
@@ -3505,7 +3511,8 @@ static int addrconf_ifdown(struct net_device *dev, int how)
35053511
* address is retained on a down event
35063512
*/
35073513
if (!keep_addr ||
3508-
!(ifa->flags & IFA_F_PERMANENT)) {
3514+
!(ifa->flags & IFA_F_PERMANENT) ||
3515+
addr_is_local(&ifa->addr)) {
35093516
hlist_del_init_rcu(&ifa->addr_lst);
35103517
goto restart;
35113518
}
@@ -3554,7 +3561,8 @@ static int addrconf_ifdown(struct net_device *dev, int how)
35543561
write_unlock_bh(&idev->lock);
35553562
spin_lock_bh(&ifa->lock);
35563563

3557-
if (keep_addr && (ifa->flags & IFA_F_PERMANENT)) {
3564+
if (keep_addr && (ifa->flags & IFA_F_PERMANENT) &&
3565+
!addr_is_local(&ifa->addr)) {
35583566
/* set state to skip the notifier below */
35593567
state = INET6_IFADDR_STATE_DEAD;
35603568
ifa->state = 0;

0 commit comments

Comments
 (0)