From patchwork Wed Dec 14 16:10:06 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathieu Trudel-Lapierre X-Patchwork-Id: 131464 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id D4D7B1007D6 for ; Thu, 15 Dec 2011 06:45:49 +1100 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1Rauli-0005vK-R4; Wed, 14 Dec 2011 19:45:34 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1RarPE-0001Bg-8b for kernel-team@lists.ubuntu.com; Wed, 14 Dec 2011 16:10:08 +0000 Received: from modemcable140.185-179-173.mc.videotron.ca ([173.179.185.140] helo=[10.7.8.120]) by youngberry.canonical.com with esmtpsa (SSL3.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1RarPD-0008HI-SG; Wed, 14 Dec 2011 16:10:08 +0000 Message-ID: <1323879006.3792.16.camel@gaea.(null)> Subject: [PATCH] ipv6: make the net.ipv6.conf.all.use_tempaddr sysctl propagate to interface settings From: Mathieu Trudel-Lapierre To: kernel-team@lists.ubuntu.com Date: Wed, 14 Dec 2011 11:10:06 -0500 Organization: Canonical Ltd. X-Mailer: Evolution 3.2.2- Mime-Version: 1.0 X-Mailman-Approved-At: Wed, 14 Dec 2011 19:45:34 +0000 Cc: mathieu-tl@ubuntu.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.13 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: kernel-team-bounces@lists.ubuntu.com Errors-To: kernel-team-bounces@lists.ubuntu.com Hi, We're trying to enable IPv6 privacy extensions by default in Ubuntu, and I've noticed issues applying the sysctl settings: applying net.ipv6.conf.all.use_tempaddr which I'd expect, readying docs, to be propagated to the underlying interface-specific settings (e.g. net.ipv6.conf.eth0.use_tempaddr) for already-available interfaces; which does not work. Ideally at boot-time, one would only need to set the following settings: net.ipv6.conf.all.use_tempaddr (to modify already-up/added interfaces) net.ipv6.conf.default.use_tempaddr (for future new interfaces) I wrote the attached patch which appears to correctly set the value of net.ipv6.conf.all.use_tempaddr on the interfaces when changed. I would be very grateful if I could get some review on that patch before submitting it upstream. It seems as though the issue is generally reproduced for most of the other ipv6 settings, and my reading of Documentation/networking/ip-sysctls.txt and net/ipv6/Kconfig (the help entry for IPV6_PRIVACY), but I'm concentrating on just use_tempaddr which is something we'd really need to make work. For more information about these issues, I found https://otrs.menandmice.com/otrs/public.pl?Action=PublicFAQ&ItemID=91 which also links two bugzilla.kernel.org bugs (which I unfortunately can't reach). It's also been discussed in the past on netdev (http://markmail.org/thread/pxw4o7p2k3xn5vh3#query:+page:1 +mid:pxw4o7p2k3xn5vh3+state:results ) and on debian-kernel (can't find the thread again). Please keep me in CC; I'm not subscribed to this list. Regards, --- Mathieu Trudel-Lapierre Freenode: cyphermox, Jabber: mathieu.tl@gmail.com 4096R/EE018C93 1967 8F7D 03A1 8F38 732E FF82 C126 33E1 EE01 8C93 From 86c5ce47c44c27f9147e095a448cb56b73453276 Mon Sep 17 00:00:00 2001 From: Mathieu Trudel-Lapierre Date: Wed, 14 Dec 2011 10:09:13 -0500 Subject: [PATCH] ipv6: make the net.ipv6.conf.all.use_tempaddr sysctl propagate to interface settings The description for IPV6_PRIVACY mentions using .../all/use_tempaddr to enable IPv6 Privacy Extensions, and IP sysctl documentation mentions 'all' as setting all interface-specific settings. We make sure at least use_tempaddr actually works as documented. --- net/ipv6/addrconf.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 76 insertions(+), 1 deletions(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index cf88df8..4a84a05 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -4340,6 +4340,81 @@ int addrconf_sysctl_disable(ctl_table *ctl, int write, return ret; } +#ifdef CONFIG_IPV6_PRIVACY +static void dev_tempaddr_change(struct inet6_dev *idev) +{ + if (!idev || !idev->dev) + return; + + if (idev->cnf.disable_ipv6) + addrconf_notify(NULL, NETDEV_DOWN, idev->dev); + else + addrconf_notify(NULL, NETDEV_UP, idev->dev); +} + +static void addrconf_tempaddr_change(struct net *net, __s32 newf) +{ + struct net_device *dev; + struct inet6_dev *idev; + + rcu_read_lock(); + for_each_netdev_rcu(net, dev) { + idev = __in6_dev_get(dev); + if (idev) { + int changed = (!idev->cnf.use_tempaddr) ^ (!newf); + idev->cnf.use_tempaddr = newf; + if (changed) + dev_tempaddr_change(idev); + } + } + rcu_read_unlock(); +} + +static int addrconf_use_tempaddr(struct ctl_table *table, int *p, int old) +{ + struct net *net; + + net = (struct net *)table->extra2; + + if (p == &net->ipv6.devconf_dflt->use_tempaddr) + return 0; + + if (!rtnl_trylock()) { + /* Restore the original values before restarting */ + *p = old; + return restart_syscall(); + } + + if (p == &net->ipv6.devconf_all->use_tempaddr) { + __s32 newf = net->ipv6.devconf_all->use_tempaddr; + net->ipv6.devconf_dflt->use_tempaddr = newf; + addrconf_tempaddr_change(net, newf); + } else if ((!*p) ^ (!old)) + dev_tempaddr_change((struct inet6_dev *)table->extra1); + + rtnl_unlock(); + return 0; +} + +static +int addrconf_sysctl_tempaddr(ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + int *valp = ctl->data; + int val = *valp; + loff_t pos = *ppos; + int ret; + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + + if (write) + ret = addrconf_use_tempaddr(ctl, valp, val); + if (ret) + *ppos = pos; + return ret; +} +#endif + static struct addrconf_sysctl_table { struct ctl_table_header *sysctl_header; @@ -4431,7 +4506,7 @@ static struct addrconf_sysctl_table .data = &ipv6_devconf.use_tempaddr, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec, + .proc_handler = addrconf_sysctl_tempaddr, }, { .procname = "temp_valid_lft", -- 1.7.7.3