[PATCH Precise SRU] UBUNTU: SAUCE: net/ipv6: don't take interface down when enabling/disabling use_tempaddr

Tim Gardner tim.gardner at canonical.com
Fri Jun 20 13:36:54 UTC 2014


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.

rtg
-- 
Tim Gardner tim.gardner at canonical.com




More information about the kernel-team mailing list