On 7/21/16 7:44 AM, Mike Manning wrote:

Default kernel behavior is to delete IPv6 addresses on link
down, which entails deletion of the address-derived
subnet-router anycast address. The latter does not happen
with sysctl setting to keep global IPv6 addrs on link down,
so every link down/up causes an increment of the anycast
refcount, cf aca_users in __ipv6_dev_ac_inc(). This bogus
refcount stops the anycast being removed on subsequent
calls to delete the address. The solution is to leave the
group for this subnet anycast on link down also for the
callflow when global IPv6 addresses are kept.

Fixes: f1705ec197e7 ("net: ipv6: Make address flushing on ifdown optional")
Signed-off-by: Mike Manning <[email protected]>
---
 net/ipv6/addrconf.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 47f837a..3c69e56 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3562,6 +3562,8 @@ restart:
                if (state != INET6_IFADDR_STATE_DEAD) {
                        __ipv6_ifa_notify(RTM_DELADDR, ifa);
                        inet6addr_notifier_call_chain(NETDEV_DOWN, ifa);
+               } else if (idev->cnf.forwarding) {
+                       addrconf_leave_anycast(ifa);
                }

                write_lock_bh(&idev->lock);



mcast has the same problem, so this should be:

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 24f1b0898e40..6287a8b9f428 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3636,6 +3636,10 @@ static int addrconf_ifdown(struct net_device *dev, int how)
                if (state != INET6_IFADDR_STATE_DEAD) {
                        __ipv6_ifa_notify(RTM_DELADDR, ifa);
                        inet6addr_notifier_call_chain(NETDEV_DOWN, ifa);
+               } else {
+                       if (idev->cnf.forwarding)
+                               addrconf_leave_anycast(ifa);
+                       addrconf_leave_solict(ifa->idev, &ifa->addr);
                }

                write_lock_bh(&idev->lock);

Reply via email to