[PATCH Precise SRU] UBUNTU: SAUCE: net/ipv6: don't take interface down when enabling/disabling use_tempaddr
Andy Whitcroft
apw at canonical.com
Mon Jun 30 12:21:09 UTC 2014
On Fri, Jun 20, 2014 at 07:36:54AM -0600, Tim Gardner wrote:
> On 06/20/2014 07:32 AM, Tim Gardner wrote:
> >From: Malcolm Scott <debianpkg at malc.org.uk>
> >
> >BugLink: http://bugs.launchpad.net/bugs/994931
> >
> >Altering use_tempaddr drops all IPv6 addresses.
> >
> >Signed-off-by: Malcolm Scott <debianpkg at malc.org.uk>
> >Signed-off-by: Tim Gardner <tim.gardner at canonical.com>
> >---
> > net/ipv6/addrconf.c | 57 ++++++++++++++++++++++++++++++++++++++++-------------
> > 1 file changed, 43 insertions(+), 14 deletions(-)
> >
> >diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> >index 246a170..6e576c6 100644
> >--- a/net/ipv6/addrconf.c
> >+++ b/net/ipv6/addrconf.c
> >@@ -125,7 +125,8 @@ static inline void addrconf_sysctl_unregister(struct inet6_dev *idev)
> > #ifdef CONFIG_IPV6_PRIVACY
> > static int __ipv6_regen_rndid(struct inet6_dev *idev);
> > static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr);
> >-static void ipv6_regen_rndid(unsigned long data);
> >+static void ipv6_regen_rndid(struct inet6_dev *idev);
> >+static void ipv6_regen_rndid_tick(unsigned long data);
> > #endif
> >
> > static int ipv6_generate_eui64(u8 *eui, struct net_device *dev);
> >@@ -409,7 +410,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
> >
> > #ifdef CONFIG_IPV6_PRIVACY
> > INIT_LIST_HEAD(&ndev->tempaddr_list);
> >- setup_timer(&ndev->regen_timer, ipv6_regen_rndid, (unsigned long)ndev);
> >+ setup_timer(&ndev->regen_timer, ipv6_regen_rndid_tick, (unsigned long)ndev);
> > if ((dev->flags&IFF_LOOPBACK) ||
> > dev->type == ARPHRD_TUNNEL ||
> > dev->type == ARPHRD_TUNNEL6 ||
> >@@ -417,8 +418,9 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
> > dev->type == ARPHRD_NONE) {
> > ndev->cnf.use_tempaddr = -1;
> > } else {
> >- in6_dev_hold(ndev);
> >- ipv6_regen_rndid((unsigned long) ndev);
> >+ rcu_read_lock_bh();
> >+ ipv6_regen_rndid(ndev);
> >+ rcu_read_unlock_bh();
> > }
> > #endif
> >
> >@@ -1649,12 +1651,21 @@ regen:
> > return 0;
> > }
> >
> >-static void ipv6_regen_rndid(unsigned long data)
> >+static void ipv6_regen_rndid_tick(unsigned long data)
> > {
> > struct inet6_dev *idev = (struct inet6_dev *) data;
> >- unsigned long expires;
> >
> > rcu_read_lock_bh();
> >+ ipv6_regen_rndid(idev);
> >+ rcu_read_unlock_bh();
> >+ in6_dev_put(idev);
> >+}
> >+
> >+/* called with rcu_read_lock_bh() */
> >+static void ipv6_regen_rndid(struct inet6_dev *idev)
> >+{
> >+ unsigned long expires;
> >+
> > write_lock_bh(&idev->lock);
> >
> > if (idev->dead)
> >@@ -1679,8 +1690,6 @@ static void ipv6_regen_rndid(unsigned long data)
> >
> > out:
> > write_unlock_bh(&idev->lock);
> >- rcu_read_unlock_bh();
> >- in6_dev_put(idev);
> > }
> >
>
> Malcolm - what is the benefit of ipv6_regen_rndid_tick() ? AFAICT it is
> merely reorganizing the locking, but there is no functional difference.
I believe this has been rearranged, to expose the unlocked form now
confusingly called ipv6_regen_rndid() to be called directly.
-apw
More information about the kernel-team
mailing list