[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