[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