All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch net-next 0/5] ipv6: change sysctl to behave more like in ipv4
@ 2014-06-10 16:19 Milos Vyletel
  2014-06-10 16:19 ` [patch net-next 1/5] ipv6: align sysctl table creation code with ipv4 Milos Vyletel
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Milos Vyletel @ 2014-06-10 16:19 UTC (permalink / raw)
  To: davem, amwang, netdev

This patch series changes how we treat net.sysctl.conf.all settings in a same
way it is done in ipv4. It is followup to my original patch submission at
http://patchwork.ozlabs.org/patch/350346/ where Cong and David suggested that
it should mimic IPv4 behaviour.

Furthermore code was aligned to look more like ipv4 does to make the
maintanance easier. List of patches and diffstat is below. Hopefully they are
not too long. If that's the case I can split them some more.

ipv6: align sysctl table creation code with ipv4
ipv6: rename DEVCONF* to IPV6_DEVCONF* to align
ipv6: consider net.ipv6.conf.all sysctls when
Documentation: update ipv6 part of
ipv6: copy default config values to interfaces

 Documentation/networking/ip-sysctl.txt |  48 ++-
 drivers/net/usb/cdc_mbim.c             |   2 +-
 drivers/net/vxlan.c                    |   2 +-
 include/linux/ipv6.h                   |  44 +--
 include/net/addrconf.h                 |   4 +-
 include/net/ipv6.h                     |  98 ++++-
 include/uapi/linux/ipv6.h              |  68 ++--
 net/ipv6/addrconf.c                    | 666 ++++++++++++---------------------
 net/ipv6/anycast.c                     |   4 +-
 net/ipv6/exthdrs.c                     |   8 +-
 net/ipv6/ip6_input.c                   |   4 +-
 net/ipv6/ip6_output.c                  |   9 +-
 net/ipv6/ip6mr.c                       |   8 +-
 net/ipv6/ipv6_sockglue.c               |   2 +-
 net/ipv6/mcast.c                       |  31 +-
 net/ipv6/ndisc.c                       |  41 +-
 net/ipv6/output_core.c                 |   4 +-
 net/ipv6/route.c                       |  13 +-
 18 files changed, 472 insertions(+), 584 deletions(-)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [patch net-next 1/5] ipv6: align sysctl table creation code with ipv4
  2014-06-10 16:19 [patch net-next 0/5] ipv6: change sysctl to behave more like in ipv4 Milos Vyletel
@ 2014-06-10 16:19 ` Milos Vyletel
  2014-06-10 16:19 ` [patch net-next 2/5] ipv6: rename DEVCONF* to IPV6_DEVCONF* to align " Milos Vyletel
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 12+ messages in thread
From: Milos Vyletel @ 2014-06-10 16:19 UTC (permalink / raw)
  To: davem, amwang, netdev
  Cc: Milos Vyletel, Alexey Kuznetsov, James Morris, Hideaki YOSHIFUJI,
	Patrick McHardy, open list

Use ADDRCONF_SYSCTL* macros to define sysctl table. This is first step
to align ipv6 and ipv4 sysctl code.

Signed-off-by: Milos Vyletel <milos.vyletel@gmail.com>
---
 net/ipv6/addrconf.c | 300 ++++++++++++----------------------------------------
 1 file changed, 66 insertions(+), 234 deletions(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 5667b30..dbacca4 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -4917,6 +4917,27 @@ int addrconf_sysctl_proxy_ndp(struct ctl_table *ctl, int write,
 	return ret;
 }
 
+#define ADDRCONF_SYSCTL_ENTRY(name, var, mval, proc) \
+	{ \
+		.procname	= #name, \
+		.data		= (void *)&ipv6_devconf + \
+				offsetof(struct ipv6_devconf, var), \
+		.maxlen		= sizeof(int), \
+		.mode		= mval, \
+		.proc_handler	= proc, \
+	}
+
+#define ADDRCONF_SYSCTL_RW_ENTRY(name) \
+	ADDRCONF_SYSCTL_ENTRY(name, name, 0644, proc_dointvec)
+
+#define ADDRCONF_SYSCTL_RO_ENTRY(name) \
+	ADDRCONF_SYSCTL_ENTRY(name, name, 0444, proc_dointvec)
+
+#define ADDRCONF_SYSCTL_COMPLEX_ENTRY(name, proc) \
+	ADDRCONF_SYSCTL_ENTRY(name, name, 0644, proc)
+
+#define ADDRCONF_SYSCTL_CUSTOM_ENTRY(name, var, proc) \
+	ADDRCONF_SYSCTL_ENTRY(name, var, 0644, proc)
 
 static struct addrconf_sysctl_table
 {
@@ -4925,248 +4946,59 @@ static struct addrconf_sysctl_table
 } addrconf_sysctl __read_mostly = {
 	.sysctl_header = NULL,
 	.addrconf_vars = {
-		{
-			.procname	= "forwarding",
-			.data		= &ipv6_devconf.forwarding,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= addrconf_sysctl_forward,
-		},
-		{
-			.procname	= "hop_limit",
-			.data		= &ipv6_devconf.hop_limit,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec,
-		},
-		{
-			.procname	= "mtu",
-			.data		= &ipv6_devconf.mtu6,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec,
-		},
-		{
-			.procname	= "accept_ra",
-			.data		= &ipv6_devconf.accept_ra,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec,
-		},
-		{
-			.procname	= "accept_redirects",
-			.data		= &ipv6_devconf.accept_redirects,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec,
-		},
-		{
-			.procname	= "autoconf",
-			.data		= &ipv6_devconf.autoconf,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec,
-		},
-		{
-			.procname	= "dad_transmits",
-			.data		= &ipv6_devconf.dad_transmits,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec,
-		},
-		{
-			.procname	= "router_solicitations",
-			.data		= &ipv6_devconf.rtr_solicits,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec,
-		},
-		{
-			.procname	= "router_solicitation_interval",
-			.data		= &ipv6_devconf.rtr_solicit_interval,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec_jiffies,
-		},
-		{
-			.procname	= "router_solicitation_delay",
-			.data		= &ipv6_devconf.rtr_solicit_delay,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec_jiffies,
-		},
-		{
-			.procname	= "force_mld_version",
-			.data		= &ipv6_devconf.force_mld_version,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec,
-		},
-		{
-			.procname	= "mldv1_unsolicited_report_interval",
-			.data		=
-				&ipv6_devconf.mldv1_unsolicited_report_interval,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec_ms_jiffies,
-		},
-		{
-			.procname	= "mldv2_unsolicited_report_interval",
-			.data		=
-				&ipv6_devconf.mldv2_unsolicited_report_interval,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec_ms_jiffies,
-		},
-		{
-			.procname	= "use_tempaddr",
-			.data		= &ipv6_devconf.use_tempaddr,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec,
-		},
-		{
-			.procname	= "temp_valid_lft",
-			.data		= &ipv6_devconf.temp_valid_lft,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec,
-		},
-		{
-			.procname	= "temp_prefered_lft",
-			.data		= &ipv6_devconf.temp_prefered_lft,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec,
-		},
-		{
-			.procname	= "regen_max_retry",
-			.data		= &ipv6_devconf.regen_max_retry,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec,
-		},
-		{
-			.procname	= "max_desync_factor",
-			.data		= &ipv6_devconf.max_desync_factor,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec,
-		},
-		{
-			.procname	= "max_addresses",
-			.data		= &ipv6_devconf.max_addresses,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec,
-		},
-		{
-			.procname	= "accept_ra_defrtr",
-			.data		= &ipv6_devconf.accept_ra_defrtr,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec,
-		},
-		{
-			.procname	= "accept_ra_pinfo",
-			.data		= &ipv6_devconf.accept_ra_pinfo,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec,
-		},
+		ADDRCONF_SYSCTL_COMPLEX_ENTRY(forwarding,
+					      addrconf_sysctl_forward),
+		ADDRCONF_SYSCTL_RW_ENTRY(hop_limit),
+		ADDRCONF_SYSCTL_CUSTOM_ENTRY(mtu, mtu6, proc_dointvec),
+		ADDRCONF_SYSCTL_RW_ENTRY(accept_ra),
+		ADDRCONF_SYSCTL_RW_ENTRY(accept_redirects),
+		ADDRCONF_SYSCTL_RW_ENTRY(autoconf),
+		ADDRCONF_SYSCTL_RW_ENTRY(dad_transmits),
+		ADDRCONF_SYSCTL_CUSTOM_ENTRY(router_solicitations, rtr_solicits,
+					     proc_dointvec),
+		ADDRCONF_SYSCTL_CUSTOM_ENTRY(router_solicitation_interval,
+					     rtr_solicit_interval,
+					     proc_dointvec_jiffies),
+		ADDRCONF_SYSCTL_CUSTOM_ENTRY(router_solicitation_delay,
+					     rtr_solicit_delay,
+					     proc_dointvec_jiffies),
+		ADDRCONF_SYSCTL_RW_ENTRY(force_mld_version),
+		ADDRCONF_SYSCTL_COMPLEX_ENTRY(mldv1_unsolicited_report_interval,
+					      proc_dointvec_ms_jiffies),
+		ADDRCONF_SYSCTL_COMPLEX_ENTRY(mldv2_unsolicited_report_interval,
+					      proc_dointvec_ms_jiffies),
+		ADDRCONF_SYSCTL_RW_ENTRY(use_tempaddr),
+		ADDRCONF_SYSCTL_RW_ENTRY(temp_valid_lft),
+		ADDRCONF_SYSCTL_RW_ENTRY(temp_prefered_lft),
+		ADDRCONF_SYSCTL_RW_ENTRY(regen_max_retry),
+		ADDRCONF_SYSCTL_RW_ENTRY(max_desync_factor),
+		ADDRCONF_SYSCTL_RW_ENTRY(max_addresses),
+		ADDRCONF_SYSCTL_RW_ENTRY(accept_ra_defrtr),
+		ADDRCONF_SYSCTL_RW_ENTRY(accept_ra_pinfo),
 #ifdef CONFIG_IPV6_ROUTER_PREF
-		{
-			.procname	= "accept_ra_rtr_pref",
-			.data		= &ipv6_devconf.accept_ra_rtr_pref,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec,
-		},
-		{
-			.procname	= "router_probe_interval",
-			.data		= &ipv6_devconf.rtr_probe_interval,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec_jiffies,
-		},
+		ADDRCONF_SYSCTL_RW_ENTRY(accept_ra_rtr_pref),
+		ADDRCONF_SYSCTL_CUSTOM_ENTRY(router_probe_interval,
+					     rtr_probe_interval,
+					     proc_dointvec_jiffies),
 #ifdef CONFIG_IPV6_ROUTE_INFO
-		{
-			.procname	= "accept_ra_rt_info_max_plen",
-			.data		= &ipv6_devconf.accept_ra_rt_info_max_plen,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec,
-		},
+		ADDRCONF_SYSCTL_RW_ENTRY(accept_ra_rt_info_max_plen),
 #endif
 #endif
-		{
-			.procname	= "proxy_ndp",
-			.data		= &ipv6_devconf.proxy_ndp,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= addrconf_sysctl_proxy_ndp,
-		},
-		{
-			.procname	= "accept_source_route",
-			.data		= &ipv6_devconf.accept_source_route,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec,
-		},
+		ADDRCONF_SYSCTL_COMPLEX_ENTRY(proxy_ndp,
+					      addrconf_sysctl_proxy_ndp),
+		ADDRCONF_SYSCTL_RW_ENTRY(accept_source_route),
 #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
-		{
-			.procname       = "optimistic_dad",
-			.data           = &ipv6_devconf.optimistic_dad,
-			.maxlen         = sizeof(int),
-			.mode           = 0644,
-			.proc_handler   = proc_dointvec,
-
-		},
+		ADDRCONF_SYSCTL_RW_ENTRY(optimistic_dad),
 #endif
 #ifdef CONFIG_IPV6_MROUTE
-		{
-			.procname	= "mc_forwarding",
-			.data		= &ipv6_devconf.mc_forwarding,
-			.maxlen		= sizeof(int),
-			.mode		= 0444,
-			.proc_handler	= proc_dointvec,
-		},
+		ADDRCONF_SYSCTL_RO_ENTRY(mc_forwarding),
 #endif
-		{
-			.procname	= "disable_ipv6",
-			.data		= &ipv6_devconf.disable_ipv6,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= addrconf_sysctl_disable,
-		},
-		{
-			.procname	= "accept_dad",
-			.data		= &ipv6_devconf.accept_dad,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec,
-		},
-		{
-			.procname       = "force_tllao",
-			.data           = &ipv6_devconf.force_tllao,
-			.maxlen         = sizeof(int),
-			.mode           = 0644,
-			.proc_handler   = proc_dointvec
-		},
-		{
-			.procname       = "ndisc_notify",
-			.data           = &ipv6_devconf.ndisc_notify,
-			.maxlen         = sizeof(int),
-			.mode           = 0644,
-			.proc_handler   = proc_dointvec
-		},
-		{
-			.procname	= "suppress_frag_ndisc",
-			.data		= &ipv6_devconf.suppress_frag_ndisc,
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= proc_dointvec
-		},
+		ADDRCONF_SYSCTL_COMPLEX_ENTRY(disable_ipv6,
+					      addrconf_sysctl_disable),
+		ADDRCONF_SYSCTL_RW_ENTRY(accept_dad),
+		ADDRCONF_SYSCTL_RW_ENTRY(force_tllao),
+		ADDRCONF_SYSCTL_RW_ENTRY(ndisc_notify),
+		ADDRCONF_SYSCTL_RW_ENTRY(suppress_frag_ndisc),
 		{
 			/* sentinel */
 		}
-- 
1.9.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [patch net-next 2/5] ipv6: rename DEVCONF* to IPV6_DEVCONF* to align with ipv4
  2014-06-10 16:19 [patch net-next 0/5] ipv6: change sysctl to behave more like in ipv4 Milos Vyletel
  2014-06-10 16:19 ` [patch net-next 1/5] ipv6: align sysctl table creation code with ipv4 Milos Vyletel
@ 2014-06-10 16:19 ` Milos Vyletel
  2014-06-10 16:19 ` [patch net-next 3/5] ipv6: consider net.ipv6.conf.all sysctls when making decisions Milos Vyletel
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 12+ messages in thread
From: Milos Vyletel @ 2014-06-10 16:19 UTC (permalink / raw)
  To: davem, amwang, netdev
  Cc: Milos Vyletel, Alexey Kuznetsov, James Morris, Hideaki YOSHIFUJI,
	Patrick McHardy, Hannes Frederic Sowa, open list

Use IPV6_DEVCONF* name similar to the IPV4_DEVCONF* used in ipv4.
Another step in aligning code.

Signed-off-by: Milos Vyletel <milos.vyletel@gmail.com>
---
 include/uapi/linux/ipv6.h | 68 +++++++++++++++++++++----------------------
 net/ipv6/addrconf.c       | 74 +++++++++++++++++++++++------------------------
 2 files changed, 71 insertions(+), 71 deletions(-)

diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h
index 593b0e3..715559a 100644
--- a/include/uapi/linux/ipv6.h
+++ b/include/uapi/linux/ipv6.h
@@ -130,40 +130,40 @@ struct ipv6hdr {
 
 /* index values for the variables in ipv6_devconf */
 enum {
-	DEVCONF_FORWARDING = 0,
-	DEVCONF_HOPLIMIT,
-	DEVCONF_MTU6,
-	DEVCONF_ACCEPT_RA,
-	DEVCONF_ACCEPT_REDIRECTS,
-	DEVCONF_AUTOCONF,
-	DEVCONF_DAD_TRANSMITS,
-	DEVCONF_RTR_SOLICITS,
-	DEVCONF_RTR_SOLICIT_INTERVAL,
-	DEVCONF_RTR_SOLICIT_DELAY,
-	DEVCONF_USE_TEMPADDR,
-	DEVCONF_TEMP_VALID_LFT,
-	DEVCONF_TEMP_PREFERED_LFT,
-	DEVCONF_REGEN_MAX_RETRY,
-	DEVCONF_MAX_DESYNC_FACTOR,
-	DEVCONF_MAX_ADDRESSES,
-	DEVCONF_FORCE_MLD_VERSION,
-	DEVCONF_ACCEPT_RA_DEFRTR,
-	DEVCONF_ACCEPT_RA_PINFO,
-	DEVCONF_ACCEPT_RA_RTR_PREF,
-	DEVCONF_RTR_PROBE_INTERVAL,
-	DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN,
-	DEVCONF_PROXY_NDP,
-	DEVCONF_OPTIMISTIC_DAD,
-	DEVCONF_ACCEPT_SOURCE_ROUTE,
-	DEVCONF_MC_FORWARDING,
-	DEVCONF_DISABLE_IPV6,
-	DEVCONF_ACCEPT_DAD,
-	DEVCONF_FORCE_TLLAO,
-	DEVCONF_NDISC_NOTIFY,
-	DEVCONF_MLDV1_UNSOLICITED_REPORT_INTERVAL,
-	DEVCONF_MLDV2_UNSOLICITED_REPORT_INTERVAL,
-	DEVCONF_SUPPRESS_FRAG_NDISC,
-	DEVCONF_MAX
+	IPV6_DEVCONF_FORWARDING = 0,
+	IPV6_DEVCONF_HOPLIMIT,
+	IPV6_DEVCONF_MTU6,
+	IPV6_DEVCONF_ACCEPT_RA,
+	IPV6_DEVCONF_ACCEPT_REDIRECTS,
+	IPV6_DEVCONF_AUTOCONF,
+	IPV6_DEVCONF_DAD_TRANSMITS,
+	IPV6_DEVCONF_RTR_SOLICITS,
+	IPV6_DEVCONF_RTR_SOLICIT_INTERVAL,
+	IPV6_DEVCONF_RTR_SOLICIT_DELAY,
+	IPV6_DEVCONF_USE_TEMPADDR,
+	IPV6_DEVCONF_TEMP_VALID_LFT,
+	IPV6_DEVCONF_TEMP_PREFERED_LFT,
+	IPV6_DEVCONF_REGEN_MAX_RETRY,
+	IPV6_DEVCONF_MAX_DESYNC_FACTOR,
+	IPV6_DEVCONF_MAX_ADDRESSES,
+	IPV6_DEVCONF_FORCE_MLD_VERSION,
+	IPV6_DEVCONF_ACCEPT_RA_DEFRTR,
+	IPV6_DEVCONF_ACCEPT_RA_PINFO,
+	IPV6_DEVCONF_ACCEPT_RA_RTR_PREF,
+	IPV6_DEVCONF_RTR_PROBE_INTERVAL,
+	IPV6_DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN,
+	IPV6_DEVCONF_PROXY_NDP,
+	IPV6_DEVCONF_OPTIMISTIC_DAD,
+	IPV6_DEVCONF_ACCEPT_SOURCE_ROUTE,
+	IPV6_DEVCONF_MC_FORWARDING,
+	IPV6_DEVCONF_DISABLE_IPV6,
+	IPV6_DEVCONF_ACCEPT_DAD,
+	IPV6_DEVCONF_FORCE_TLLAO,
+	IPV6_DEVCONF_NDISC_NOTIFY,
+	IPV6_DEVCONF_MLDV1_UNSOLICITED_REPORT_INTERVAL,
+	IPV6_DEVCONF_MLDV2_UNSOLICITED_REPORT_INTERVAL,
+	IPV6_DEVCONF_SUPPRESS_FRAG_NDISC,
+	IPV6_DEVCONF_MAX
 };
 
 
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index dbacca4..24fbb38 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -4272,62 +4272,62 @@ errout:
 static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
 				__s32 *array, int bytes)
 {
-	BUG_ON(bytes < (DEVCONF_MAX * 4));
+	BUG_ON(bytes < (IPV6_DEVCONF_MAX * 4));
 
 	memset(array, 0, bytes);
-	array[DEVCONF_FORWARDING] = cnf->forwarding;
-	array[DEVCONF_HOPLIMIT] = cnf->hop_limit;
-	array[DEVCONF_MTU6] = cnf->mtu6;
-	array[DEVCONF_ACCEPT_RA] = cnf->accept_ra;
-	array[DEVCONF_ACCEPT_REDIRECTS] = cnf->accept_redirects;
-	array[DEVCONF_AUTOCONF] = cnf->autoconf;
-	array[DEVCONF_DAD_TRANSMITS] = cnf->dad_transmits;
-	array[DEVCONF_RTR_SOLICITS] = cnf->rtr_solicits;
-	array[DEVCONF_RTR_SOLICIT_INTERVAL] =
+	array[IPV6_DEVCONF_FORWARDING] = cnf->forwarding;
+	array[IPV6_DEVCONF_HOPLIMIT] = cnf->hop_limit;
+	array[IPV6_DEVCONF_MTU6] = cnf->mtu6;
+	array[IPV6_DEVCONF_ACCEPT_RA] = cnf->accept_ra;
+	array[IPV6_DEVCONF_ACCEPT_REDIRECTS] = cnf->accept_redirects;
+	array[IPV6_DEVCONF_AUTOCONF] = cnf->autoconf;
+	array[IPV6_DEVCONF_DAD_TRANSMITS] = cnf->dad_transmits;
+	array[IPV6_DEVCONF_RTR_SOLICITS] = cnf->rtr_solicits;
+	array[IPV6_DEVCONF_RTR_SOLICIT_INTERVAL] =
 		jiffies_to_msecs(cnf->rtr_solicit_interval);
-	array[DEVCONF_RTR_SOLICIT_DELAY] =
+	array[IPV6_DEVCONF_RTR_SOLICIT_DELAY] =
 		jiffies_to_msecs(cnf->rtr_solicit_delay);
-	array[DEVCONF_FORCE_MLD_VERSION] = cnf->force_mld_version;
-	array[DEVCONF_MLDV1_UNSOLICITED_REPORT_INTERVAL] =
+	array[IPV6_DEVCONF_FORCE_MLD_VERSION] = cnf->force_mld_version;
+	array[IPV6_DEVCONF_MLDV1_UNSOLICITED_REPORT_INTERVAL] =
 		jiffies_to_msecs(cnf->mldv1_unsolicited_report_interval);
-	array[DEVCONF_MLDV2_UNSOLICITED_REPORT_INTERVAL] =
+	array[IPV6_DEVCONF_MLDV2_UNSOLICITED_REPORT_INTERVAL] =
 		jiffies_to_msecs(cnf->mldv2_unsolicited_report_interval);
-	array[DEVCONF_USE_TEMPADDR] = cnf->use_tempaddr;
-	array[DEVCONF_TEMP_VALID_LFT] = cnf->temp_valid_lft;
-	array[DEVCONF_TEMP_PREFERED_LFT] = cnf->temp_prefered_lft;
-	array[DEVCONF_REGEN_MAX_RETRY] = cnf->regen_max_retry;
-	array[DEVCONF_MAX_DESYNC_FACTOR] = cnf->max_desync_factor;
-	array[DEVCONF_MAX_ADDRESSES] = cnf->max_addresses;
-	array[DEVCONF_ACCEPT_RA_DEFRTR] = cnf->accept_ra_defrtr;
-	array[DEVCONF_ACCEPT_RA_PINFO] = cnf->accept_ra_pinfo;
+	array[IPV6_DEVCONF_USE_TEMPADDR] = cnf->use_tempaddr;
+	array[IPV6_DEVCONF_TEMP_VALID_LFT] = cnf->temp_valid_lft;
+	array[IPV6_DEVCONF_TEMP_PREFERED_LFT] = cnf->temp_prefered_lft;
+	array[IPV6_DEVCONF_REGEN_MAX_RETRY] = cnf->regen_max_retry;
+	array[IPV6_DEVCONF_MAX_DESYNC_FACTOR] = cnf->max_desync_factor;
+	array[IPV6_DEVCONF_MAX_ADDRESSES] = cnf->max_addresses;
+	array[IPV6_DEVCONF_ACCEPT_RA_DEFRTR] = cnf->accept_ra_defrtr;
+	array[IPV6_DEVCONF_ACCEPT_RA_PINFO] = cnf->accept_ra_pinfo;
 #ifdef CONFIG_IPV6_ROUTER_PREF
-	array[DEVCONF_ACCEPT_RA_RTR_PREF] = cnf->accept_ra_rtr_pref;
-	array[DEVCONF_RTR_PROBE_INTERVAL] =
+	array[IPV6_DEVCONF_ACCEPT_RA_RTR_PREF] = cnf->accept_ra_rtr_pref;
+	array[IPV6_DEVCONF_RTR_PROBE_INTERVAL] =
 		jiffies_to_msecs(cnf->rtr_probe_interval);
 #ifdef CONFIG_IPV6_ROUTE_INFO
-	array[DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen;
+	array[IPV6_DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen;
 #endif
 #endif
-	array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp;
-	array[DEVCONF_ACCEPT_SOURCE_ROUTE] = cnf->accept_source_route;
+	array[IPV6_DEVCONF_PROXY_NDP] = cnf->proxy_ndp;
+	array[IPV6_DEVCONF_ACCEPT_SOURCE_ROUTE] = cnf->accept_source_route;
 #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
-	array[DEVCONF_OPTIMISTIC_DAD] = cnf->optimistic_dad;
+	array[IPV6_DEVCONF_OPTIMISTIC_DAD] = cnf->optimistic_dad;
 #endif
 #ifdef CONFIG_IPV6_MROUTE
-	array[DEVCONF_MC_FORWARDING] = cnf->mc_forwarding;
+	array[IPV6_DEVCONF_MC_FORWARDING] = cnf->mc_forwarding;
 #endif
-	array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6;
-	array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad;
-	array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao;
-	array[DEVCONF_NDISC_NOTIFY] = cnf->ndisc_notify;
-	array[DEVCONF_SUPPRESS_FRAG_NDISC] = cnf->suppress_frag_ndisc;
+	array[IPV6_DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6;
+	array[IPV6_DEVCONF_ACCEPT_DAD] = cnf->accept_dad;
+	array[IPV6_DEVCONF_FORCE_TLLAO] = cnf->force_tllao;
+	array[IPV6_DEVCONF_NDISC_NOTIFY] = cnf->ndisc_notify;
+	array[IPV6_DEVCONF_SUPPRESS_FRAG_NDISC] = cnf->suppress_frag_ndisc;
 }
 
 static inline size_t inet6_ifla6_size(void)
 {
 	return nla_total_size(4) /* IFLA_INET6_FLAGS */
 	     + nla_total_size(sizeof(struct ifla_cacheinfo))
-	     + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */
+	     + nla_total_size(IPV6_DEVCONF_MAX * 4) /* IFLA_INET6_CONF */
 	     + nla_total_size(IPSTATS_MIB_MAX * 8) /* IFLA_INET6_STATS */
 	     + nla_total_size(ICMP6_MIB_MAX * 8) /* IFLA_INET6_ICMP6STATS */
 	     + nla_total_size(sizeof(struct in6_addr)); /* IFLA_INET6_TOKEN */
@@ -4400,7 +4400,7 @@ static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev)
 	ci.retrans_time = jiffies_to_msecs(NEIGH_VAR(idev->nd_parms, RETRANS_TIME));
 	if (nla_put(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci))
 		goto nla_put_failure;
-	nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32));
+	nla = nla_reserve(skb, IFLA_INET6_CONF, IPV6_DEVCONF_MAX * sizeof(s32));
 	if (nla == NULL)
 		goto nla_put_failure;
 	ipv6_store_devconf(&idev->cnf, nla_data(nla), nla_len(nla));
@@ -4942,7 +4942,7 @@ int addrconf_sysctl_proxy_ndp(struct ctl_table *ctl, int write,
 static struct addrconf_sysctl_table
 {
 	struct ctl_table_header *sysctl_header;
-	struct ctl_table addrconf_vars[DEVCONF_MAX+1];
+	struct ctl_table addrconf_vars[IPV6_DEVCONF_MAX+1];
 } addrconf_sysctl __read_mostly = {
 	.sysctl_header = NULL,
 	.addrconf_vars = {
-- 
1.9.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [patch net-next 3/5] ipv6: consider net.ipv6.conf.all sysctls when making decisions
  2014-06-10 16:19 [patch net-next 0/5] ipv6: change sysctl to behave more like in ipv4 Milos Vyletel
  2014-06-10 16:19 ` [patch net-next 1/5] ipv6: align sysctl table creation code with ipv4 Milos Vyletel
  2014-06-10 16:19 ` [patch net-next 2/5] ipv6: rename DEVCONF* to IPV6_DEVCONF* to align " Milos Vyletel
@ 2014-06-10 16:19 ` Milos Vyletel
  2014-06-10 17:13   ` Stephen Hemminger
  2014-06-10 17:15   ` Florent Fourcot
  2014-06-10 16:19 ` [patch net-next 4/5] Documentation: update ipv6 part of networking/ip-sysctl.txt Milos Vyletel
  2014-06-10 16:19 ` [patch net-next 5/5] ipv6: copy default config values to interfaces Milos Vyletel
  4 siblings, 2 replies; 12+ messages in thread
From: Milos Vyletel @ 2014-06-10 16:19 UTC (permalink / raw)
  To: davem, amwang, netdev
  Cc: Milos Vyletel, Oliver Neukum, Alexey Kuznetsov, James Morris,
	Hideaki YOSHIFUJI, Patrick McHardy, stephen hemminger,
	Pravin B Shelar, Nicolas Dichtel, Mike Rapoport, Daniel Borkmann,
	Or Gerlitz, Tom Herbert, Hannes Frederic Sowa, Florent Fourcot,
	Eric Dumazet, Paul Durrant, open list:USB CDC ETHERNET...,
	open list

As it is right now net.ipv6.conf.all.* are mostly ignored and instead
we're only making decisions based on interface specific settings. These
settings are coppied from net.ipv6.conf.default and changing either all
or default settings have no effect.

This patch changes ipv6 code to look more like the one in ipv4 world. It
will introduce new macros (IN6_DEV_{AND,OR,MAX}CONF) that will take
settings in net.ipv6.conf.all into account when making decisions.

Furthermore code is now almost identical to the ipv4 one. ipv6_devconf
no longer defines each entry but instead uses array of IPV6_DEVCONF_MAX
size to store all data to simplify access to these data from macros.

Each sysctl tunable has it's own macro defined and they use one of the
IN6_DEV_{AND,OR,MAX}CONF with the exception of IN6_DEV_FORWARD which
returns device specific setting. They are defined as:

IN6_DEV_ANDCONF
	IN6_DEV_AUTOCONF
	IN6_DEV_MFORWARD
	IN6_DEV_ACCEPT_REDIRECTS
	IN6_DEV_ACCEPT_RA_DEFRTR
	IN6_DEV_ACCEPT_RA_PINFO
	IN6_DEV_ACCEPT_RA_RTR_PREF
	IN6_DEV_NDISC_NOTIFY
	IN6_DEV_SUPPRESS_FRAG_NDISC
	IN6_DEV_FORCE_TLLAO

IN6_DEV_ORCONF
	IN6_DEV_DISABLE_IPV6
	IN6_DEV_PROXY_NDP

IN6_DEV_MAXCONF
	IN6_DEV_HOPLIMIT
	IN6_DEV_MTU
	IN6_DEV_RTR_SOLICITS
	IN6_DEV_RTR_SOLICIT_INTERVAL
	IN6_DEV_RTR_SOLICIT_DELAY
	IN6_DEV_USE_TEMPADDR
	IN6_DEV_ACCEPT_RA
	IN6_DEV_ACCEPT_RA_RT_INFO_MAX_PLEN
	IN6_DEV_ACCEPT_SOURCE_ROUTE
	IN6_DEV_RTR_PROBE_INTERVAL
	IN6_DEV_REGEN_MAX_RETRY
	IN6_DEV_TEMP_VALID_LFT
	IN6_DEV_TEMP_PREFERED_LFT
	IN6_DEV_MAX_DESYNC_FACTOR
	IN6_DEV_MAX_ADDRESSES
	IN6_DEV_ACCEPT_DAD
	IN6_DEV_OPTIMISTIC_DAD
	IN6_DEV_DAD_TRANSMITS

All places which were using accesing these settings directly from
ipv6_devconf stuct were updated to use these new macros.

Signed-off-by: Milos Vyletel <milos.vyletel@gmail.com>
---
 drivers/net/usb/cdc_mbim.c |   2 +-
 drivers/net/vxlan.c        |   2 +-
 include/linux/ipv6.h       |  44 +----
 include/net/addrconf.h     |   4 +-
 include/net/ipv6.h         |  98 +++++++++-
 net/ipv6/addrconf.c        | 466 ++++++++++++++++++++++-----------------------
 net/ipv6/anycast.c         |   4 +-
 net/ipv6/exthdrs.c         |   8 +-
 net/ipv6/ip6_input.c       |   4 +-
 net/ipv6/ip6_output.c      |   9 +-
 net/ipv6/ip6mr.c           |   8 +-
 net/ipv6/ipv6_sockglue.c   |   2 +-
 net/ipv6/mcast.c           |  31 +--
 net/ipv6/ndisc.c           |  41 ++--
 net/ipv6/output_core.c     |   4 +-
 net/ipv6/route.c           |  13 +-
 16 files changed, 379 insertions(+), 361 deletions(-)

diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c
index 5ee7a1d..deb21de 100644
--- a/drivers/net/usb/cdc_mbim.c
+++ b/drivers/net/usb/cdc_mbim.c
@@ -338,7 +338,7 @@ static void do_neigh_solicit(struct usbnet *dev, u8 *buf, u16 tci)
 	in6_dev = in6_dev_get(netdev);
 	if (!in6_dev)
 		goto out;
-	is_router = !!in6_dev->cnf.forwarding;
+	is_router = !!IN6_DEV_FORWARD(in6_dev);
 	in6_dev_put(in6_dev);
 
 	/* ipv6_stub != NULL if in6_dev_get returned an inet6_dev */
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 4e2caaf..38d4029 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -2633,7 +2633,7 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
 #if IS_ENABLED(CONFIG_IPV6)
 		if (use_ipv6) {
 			struct inet6_dev *idev = __in6_dev_get(lowerdev);
-			if (idev && idev->cnf.disable_ipv6) {
+			if (idev && IN6_DEV_DISABLE_IPV6(idev)) {
 				pr_info("IPv6 is disabled via sysctl\n");
 				return -EPERM;
 			}
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 2faef33..fe8d38d 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -9,48 +9,8 @@
  * This structure contains configuration options per IPv6 link.
  */
 struct ipv6_devconf {
-	__s32		forwarding;
-	__s32		hop_limit;
-	__s32		mtu6;
-	__s32		accept_ra;
-	__s32		accept_redirects;
-	__s32		autoconf;
-	__s32		dad_transmits;
-	__s32		rtr_solicits;
-	__s32		rtr_solicit_interval;
-	__s32		rtr_solicit_delay;
-	__s32		force_mld_version;
-	__s32		mldv1_unsolicited_report_interval;
-	__s32		mldv2_unsolicited_report_interval;
-	__s32		use_tempaddr;
-	__s32		temp_valid_lft;
-	__s32		temp_prefered_lft;
-	__s32		regen_max_retry;
-	__s32		max_desync_factor;
-	__s32		max_addresses;
-	__s32		accept_ra_defrtr;
-	__s32		accept_ra_pinfo;
-#ifdef CONFIG_IPV6_ROUTER_PREF
-	__s32		accept_ra_rtr_pref;
-	__s32		rtr_probe_interval;
-#ifdef CONFIG_IPV6_ROUTE_INFO
-	__s32		accept_ra_rt_info_max_plen;
-#endif
-#endif
-	__s32		proxy_ndp;
-	__s32		accept_source_route;
-#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
-	__s32		optimistic_dad;
-#endif
-#ifdef CONFIG_IPV6_MROUTE
-	__s32		mc_forwarding;
-#endif
-	__s32		disable_ipv6;
-	__s32		accept_dad;
-	__s32		force_tllao;
-	__s32           ndisc_notify;
-	__s32		suppress_frag_ndisc;
-	void		*sysctl;
+	void	*sysctl;
+	__s32	data[IPV6_DEVCONF_MAX];
 };
 
 struct ipv6_params {
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index f679877..7eb463e 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -8,8 +8,8 @@
 
 #define TEMP_VALID_LIFETIME		(7*86400)
 #define TEMP_PREFERRED_LIFETIME		(86400)
-#define REGEN_MAX_RETRY			(3)
-#define MAX_DESYNC_FACTOR		(600)
+#define _REGEN_MAX_RETRY		(3)
+#define _MAX_DESYNC_FACTOR		(600)
 
 #define ADDR_CHECK_FREQUENCY		(120*HZ)
 
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 574337f..1ee39a5 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -288,13 +288,107 @@ struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
 
 bool ipv6_opt_accepted(const struct sock *sk, const struct sk_buff *skb);
 
+#define IPV6_DEVCONF(cnf, attr) ((cnf).data[IPV6_DEVCONF_ ## attr])
+#define IPV6_DEVCONF_ALL(net, attr) \
+	IPV6_DEVCONF((*(net)->ipv6.devconf_all), attr)
+#define IPV6_DEVCONF_DFLT(net, attr) \
+	IPV6_DEVCONF((*(net)->ipv6.devconf_dflt), attr)
+
+static inline int ipv6_devconf_get(struct inet6_dev *idev, int index)
+{
+	return idev->cnf.data[index];
+}
+
+static inline void ipv6_devconf_set(struct inet6_dev *idev, int index,
+				    int val)
+{
+	idev->cnf.data[index] = val;
+}
+
+#define IN6_DEV_CONF_GET(idev, attr) \
+	ipv6_devconf_get((idev), IPV6_DEVCONF_ ## attr)
+#define IN6_DEV_CONF_SET(idev, attr, val) \
+	ipv6_devconf_set((idev), IPV6_DEVCONF_ ## attr, (val))
+
+#define IN6_DEV_ANDCONF(idev, attr) \
+	(IPV6_DEVCONF_ALL(dev_net(idev->dev), attr) && \
+	 IN6_DEV_CONF_GET((idev), attr))
+#define IN6_DEV_ORCONF(idev, attr) \
+	(IPV6_DEVCONF_ALL(dev_net(idev->dev), attr) || \
+	 IN6_DEV_CONF_GET((idev), attr))
+#define IN6_DEV_MAXCONF(idev, attr) \
+	(max(IPV6_DEVCONF_ALL(dev_net(idev->dev), attr), \
+	     IN6_DEV_CONF_GET((idev), attr)))
+
+#define IN6_DEV_DISABLE_IPV6(idev)\
+			unlikely(IN6_DEV_ORCONF((idev), DISABLE_IPV6))
+#define IN6_DEV_AUTOCONF(idev)	IN6_DEV_ANDCONF((idev), AUTOCONF)
+
+#define IN6_DEV_FORWARD(idev)		IN6_DEV_CONF_GET((idev), FORWARDING)
+#define IN6_DEV_MFORWARD(idev)	IN6_DEV_ANDCONF((idev), MC_FORWARDING)
+#define IN6_DEV_MFORWARD_INC(idev) \
+	IN6_DEV_CONF_SET((idev), MC_FORWARDING, \
+		IN6_DEV_CONF_GET((idev), MC_FORWARDING) + 1)
+#define IN6_DEV_MFORWARD_DEC(idev) \
+	IN6_DEV_CONF_SET((idev), MC_FORWARDING, \
+		IN6_DEV_CONF_GET((idev), MC_FORWARDING) - 1)
+
+#define IN6_DEV_HOPLIMIT(idev)	IN6_DEV_MAXCONF((idev), HOPLIMIT)
+#define IN6_DEV_MTU(idev)		IN6_DEV_MAXCONF((idev), MTU6)
+
+#define IN6_DEV_RTR_SOLICITS(idev)	IN6_DEV_MAXCONF((idev), RTR_SOLICITS)
+#define IN6_DEV_RTR_SOLICIT_INTERVAL(idev) \
+			IN6_DEV_MAXCONF((idev), RTR_SOLICIT_INTERVAL)
+#define IN6_DEV_RTR_SOLICIT_DELAY(idev) \
+			IN6_DEV_MAXCONF((idev), RTR_SOLICIT_DELAY)
+#define IN6_DEV_USE_TEMPADDR(idev)	IN6_DEV_MAXCONF((idev), USE_TEMPADDR)
+
+#define IN6_DEV_ACCEPT_RA(idev)	IN6_DEV_MAXCONF((idev), ACCEPT_RA)
+#define IN6_DEV_ACCEPT_REDIRECTS(idev) \
+			IN6_DEV_ANDCONF((idev), ACCEPT_REDIRECTS)
+#define IN6_DEV_ACCEPT_RA_DEFRTR(idev) \
+			IN6_DEV_ANDCONF((idev), ACCEPT_RA_DEFRTR)
+#define IN6_DEV_ACCEPT_RA_PINFO(idev) \
+			IN6_DEV_ANDCONF((idev), ACCEPT_RA_PINFO)
+#define IN6_DEV_ACCEPT_RA_RTR_PREF(idev) \
+			IN6_DEV_ANDCONF((idev), ACCEPT_RA_RTR_PREF)
+#define IN6_DEV_ACCEPT_RA_RT_INFO_MAX_PLEN(idev) \
+			IN6_DEV_MAXCONF((idev), ACCEPT_RA_RT_INFO_MAX_PLEN)
+
+#define IN6_DEV_ACCEPT_SOURCE_ROUTE(idev) \
+			IN6_DEV_MAXCONF((idev), ACCEPT_SOURCE_ROUTE)
+#define IN6_DEV_PROXY_NDP(idev)	IN6_DEV_ORCONF((idev), PROXY_NDP)
+#define IN6_DEV_FORCE_MLD_VERSION(idev) \
+			IN6_DEV_MAXCONF((idev), FORCE_MLD_VERSION)
+
+#define IN6_DEV_NDISC_NOTIFY(idev)	IN6_DEV_ANDCONF((idev), NDISC_NOTIFY)
+#define IN6_DEV_SUPPRESS_FRAG_NDISC(idev) \
+			IN6_DEV_ANDCONF((idev), SUPPRESS_FRAG_NDISC)
+#define IN6_DEV_FORCE_TLLAO(idev)	 IN6_DEV_ANDCONF((idev), FORCE_TLLAO)
+#define IN6_DEV_RTR_PROBE_INTERVAL(idev) \
+			IN6_DEV_MAXCONF((idev), RTR_PROBE_INTERVAL)
+#define IN6_DEV_REGEN_MAX_RETRY(idev) \
+			IN6_DEV_MAXCONF((idev), REGEN_MAX_RETRY)
+#define IN6_DEV_TEMP_VALID_LFT(idev) \
+			IN6_DEV_MAXCONF((idev), TEMP_VALID_LFT)
+#define IN6_DEV_TEMP_PREFERED_LFT(idev) \
+			IN6_DEV_MAXCONF((idev), TEMP_PREFERED_LFT)
+#define IN6_DEV_MAX_DESYNC_FACTOR(idev) \
+			IN6_DEV_MAXCONF((idev), MAX_DESYNC_FACTOR)
+#define IN6_DEV_MAX_ADDRESSES(idev)	IN6_DEV_MAXCONF((idev), MAX_ADDRESSES)
+
+#define IN6_DEV_ACCEPT_DAD(idev)	IN6_DEV_MAXCONF((idev), ACCEPT_DAD)
+#define IN6_DEV_OPTIMISTIC_DAD(idev)	IN6_DEV_ANDCONF((idev), OPTIMISTIC_DAD)
+#define IN6_DEV_DAD_TRANSMITS(idev)	IN6_DEV_MAXCONF((idev), DAD_TRANSMITS)
+
 static inline bool ipv6_accept_ra(struct inet6_dev *idev)
 {
 	/* If forwarding is enabled, RA are not accepted unless the special
 	 * hybrid mode (accept_ra=2) is enabled.
 	 */
-	return idev->cnf.forwarding ? idev->cnf.accept_ra == 2 :
-	    idev->cnf.accept_ra;
+	return IN6_DEV_FORWARD(idev) ?
+		IN6_DEV_ACCEPT_RA(idev) == 2 :
+		IN6_DEV_ACCEPT_RA(idev);
 }
 
 #if IS_ENABLED(CONFIG_IPV6)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 24fbb38..5b1b578 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -166,75 +166,81 @@ static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
 			       struct net_device *dev);
 
 static struct ipv6_devconf ipv6_devconf __read_mostly = {
-	.forwarding		= 0,
-	.hop_limit		= IPV6_DEFAULT_HOPLIMIT,
-	.mtu6			= IPV6_MIN_MTU,
-	.accept_ra		= 1,
-	.accept_redirects	= 1,
-	.autoconf		= 1,
-	.force_mld_version	= 0,
-	.mldv1_unsolicited_report_interval = 10 * HZ,
-	.mldv2_unsolicited_report_interval = HZ,
-	.dad_transmits		= 1,
-	.rtr_solicits		= MAX_RTR_SOLICITATIONS,
-	.rtr_solicit_interval	= RTR_SOLICITATION_INTERVAL,
-	.rtr_solicit_delay	= MAX_RTR_SOLICITATION_DELAY,
-	.use_tempaddr 		= 0,
-	.temp_valid_lft		= TEMP_VALID_LIFETIME,
-	.temp_prefered_lft	= TEMP_PREFERRED_LIFETIME,
-	.regen_max_retry	= REGEN_MAX_RETRY,
-	.max_desync_factor	= MAX_DESYNC_FACTOR,
-	.max_addresses		= IPV6_MAX_ADDRESSES,
-	.accept_ra_defrtr	= 1,
-	.accept_ra_pinfo	= 1,
+	.data = {
+		[IPV6_DEVCONF_FORWARDING] = 0,
+		[IPV6_DEVCONF_HOPLIMIT] = IPV6_DEFAULT_HOPLIMIT,
+		[IPV6_DEVCONF_MTU6] = IPV6_MIN_MTU,
+		[IPV6_DEVCONF_ACCEPT_RA] = 1,
+		[IPV6_DEVCONF_ACCEPT_REDIRECTS] = 1,
+		[IPV6_DEVCONF_AUTOCONF] = 1,
+		[IPV6_DEVCONF_FORCE_MLD_VERSION] = 0,
+		[IPV6_DEVCONF_MLDV1_UNSOLICITED_REPORT_INTERVAL] = 10 * HZ,
+		[IPV6_DEVCONF_MLDV2_UNSOLICITED_REPORT_INTERVAL] = HZ,
+		[IPV6_DEVCONF_DAD_TRANSMITS] = 1,
+		[IPV6_DEVCONF_RTR_SOLICITS] = MAX_RTR_SOLICITATIONS,
+		[IPV6_DEVCONF_RTR_SOLICIT_INTERVAL] = RTR_SOLICITATION_INTERVAL,
+		[IPV6_DEVCONF_RTR_SOLICIT_DELAY] = MAX_RTR_SOLICITATION_DELAY,
+		[IPV6_DEVCONF_USE_TEMPADDR] = 0,
+		[IPV6_DEVCONF_TEMP_VALID_LFT] = TEMP_VALID_LIFETIME,
+		[IPV6_DEVCONF_TEMP_PREFERED_LFT] = TEMP_PREFERRED_LIFETIME,
+		[IPV6_DEVCONF_REGEN_MAX_RETRY] = _REGEN_MAX_RETRY,
+		[IPV6_DEVCONF_MAX_DESYNC_FACTOR] = _MAX_DESYNC_FACTOR,
+		[IPV6_DEVCONF_MAX_ADDRESSES] = IPV6_MAX_ADDRESSES,
+		[IPV6_DEVCONF_ACCEPT_RA_DEFRTR] = 1,
+		[IPV6_DEVCONF_ACCEPT_RA_PINFO] = 1,
 #ifdef CONFIG_IPV6_ROUTER_PREF
-	.accept_ra_rtr_pref	= 1,
-	.rtr_probe_interval	= 60 * HZ,
+		[IPV6_DEVCONF_ACCEPT_RA_RTR_PREF] = 1,
+		[IPV6_DEVCONF_RTR_PROBE_INTERVAL] = 60 * HZ,
 #ifdef CONFIG_IPV6_ROUTE_INFO
-	.accept_ra_rt_info_max_plen = 0,
+		[IPV6_DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = 0,
 #endif
 #endif
-	.proxy_ndp		= 0,
-	.accept_source_route	= 0,	/* we do not accept RH0 by default. */
-	.disable_ipv6		= 0,
-	.accept_dad		= 1,
-	.suppress_frag_ndisc	= 1,
+		[IPV6_DEVCONF_PROXY_NDP] = 0,
+		/* we do not accept RH0 by default. */
+		[IPV6_DEVCONF_ACCEPT_SOURCE_ROUTE] = 0,
+		[IPV6_DEVCONF_DISABLE_IPV6] = 0,
+		[IPV6_DEVCONF_ACCEPT_DAD] = 1,
+		[IPV6_DEVCONF_SUPPRESS_FRAG_NDISC] = 1,
+	},
 };
 
 static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
-	.forwarding		= 0,
-	.hop_limit		= IPV6_DEFAULT_HOPLIMIT,
-	.mtu6			= IPV6_MIN_MTU,
-	.accept_ra		= 1,
-	.accept_redirects	= 1,
-	.autoconf		= 1,
-	.force_mld_version	= 0,
-	.mldv1_unsolicited_report_interval = 10 * HZ,
-	.mldv2_unsolicited_report_interval = HZ,
-	.dad_transmits		= 1,
-	.rtr_solicits		= MAX_RTR_SOLICITATIONS,
-	.rtr_solicit_interval	= RTR_SOLICITATION_INTERVAL,
-	.rtr_solicit_delay	= MAX_RTR_SOLICITATION_DELAY,
-	.use_tempaddr		= 0,
-	.temp_valid_lft		= TEMP_VALID_LIFETIME,
-	.temp_prefered_lft	= TEMP_PREFERRED_LIFETIME,
-	.regen_max_retry	= REGEN_MAX_RETRY,
-	.max_desync_factor	= MAX_DESYNC_FACTOR,
-	.max_addresses		= IPV6_MAX_ADDRESSES,
-	.accept_ra_defrtr	= 1,
-	.accept_ra_pinfo	= 1,
+	.data = {
+		[IPV6_DEVCONF_FORWARDING] = 0,
+		[IPV6_DEVCONF_HOPLIMIT] = IPV6_DEFAULT_HOPLIMIT,
+		[IPV6_DEVCONF_MTU6] = IPV6_MIN_MTU,
+		[IPV6_DEVCONF_ACCEPT_RA] = 1,
+		[IPV6_DEVCONF_ACCEPT_REDIRECTS] = 1,
+		[IPV6_DEVCONF_AUTOCONF] = 1,
+		[IPV6_DEVCONF_FORCE_MLD_VERSION] = 0,
+		[IPV6_DEVCONF_MLDV1_UNSOLICITED_REPORT_INTERVAL] = 10 * HZ,
+		[IPV6_DEVCONF_MLDV2_UNSOLICITED_REPORT_INTERVAL] = HZ,
+		[IPV6_DEVCONF_DAD_TRANSMITS] = 1,
+		[IPV6_DEVCONF_RTR_SOLICITS] = MAX_RTR_SOLICITATIONS,
+		[IPV6_DEVCONF_RTR_SOLICIT_INTERVAL] = RTR_SOLICITATION_INTERVAL,
+		[IPV6_DEVCONF_RTR_SOLICIT_DELAY] = MAX_RTR_SOLICITATION_DELAY,
+		[IPV6_DEVCONF_USE_TEMPADDR] = 0,
+		[IPV6_DEVCONF_TEMP_VALID_LFT] = TEMP_VALID_LIFETIME,
+		[IPV6_DEVCONF_TEMP_PREFERED_LFT] = TEMP_PREFERRED_LIFETIME,
+		[IPV6_DEVCONF_REGEN_MAX_RETRY] = _REGEN_MAX_RETRY,
+		[IPV6_DEVCONF_MAX_DESYNC_FACTOR] = _MAX_DESYNC_FACTOR,
+		[IPV6_DEVCONF_MAX_ADDRESSES] = IPV6_MAX_ADDRESSES,
+		[IPV6_DEVCONF_ACCEPT_RA_DEFRTR] = 1,
+		[IPV6_DEVCONF_ACCEPT_RA_PINFO] = 1,
 #ifdef CONFIG_IPV6_ROUTER_PREF
-	.accept_ra_rtr_pref	= 1,
-	.rtr_probe_interval	= 60 * HZ,
+		[IPV6_DEVCONF_ACCEPT_RA_RTR_PREF] = 1,
+		[IPV6_DEVCONF_RTR_PROBE_INTERVAL] = 60 * HZ,
 #ifdef CONFIG_IPV6_ROUTE_INFO
-	.accept_ra_rt_info_max_plen = 0,
+		[IPV6_DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = 0,
 #endif
 #endif
-	.proxy_ndp		= 0,
-	.accept_source_route	= 0,	/* we do not accept RH0 by default. */
-	.disable_ipv6		= 0,
-	.accept_dad		= 1,
-	.suppress_frag_ndisc	= 1,
+		[IPV6_DEVCONF_PROXY_NDP] = 0,
+		/* we do not accept RH0 by default. */
+		[IPV6_DEVCONF_ACCEPT_SOURCE_ROUTE] = 0,
+		[IPV6_DEVCONF_DISABLE_IPV6] = 0,
+		[IPV6_DEVCONF_ACCEPT_DAD] = 1,
+		[IPV6_DEVCONF_SUPPRESS_FRAG_NDISC] = 1,
+	},
 };
 
 /* Check if a valid qdisc is available */
@@ -325,14 +331,14 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
 	setup_timer(&ndev->rs_timer, addrconf_rs_timer,
 		    (unsigned long)ndev);
 	memcpy(&ndev->cnf, dev_net(dev)->ipv6.devconf_dflt, sizeof(ndev->cnf));
-	ndev->cnf.mtu6 = dev->mtu;
+	IN6_DEV_CONF_SET(ndev, MTU6, dev->mtu);
 	ndev->cnf.sysctl = NULL;
 	ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl);
 	if (ndev->nd_parms == NULL) {
 		kfree(ndev);
 		return NULL;
 	}
-	if (ndev->cnf.forwarding)
+	if (IN6_DEV_FORWARD(ndev))
 		dev_disable_lro(dev);
 	/* We refer to the device */
 	dev_hold(dev);
@@ -363,12 +369,12 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
 	in6_dev_hold(ndev);
 
 	if (dev->flags & (IFF_NOARP | IFF_LOOPBACK))
-		ndev->cnf.accept_dad = -1;
+		IN6_DEV_CONF_SET(ndev, ACCEPT_DAD, -1);
 
 #if IS_ENABLED(CONFIG_IPV6_SIT)
 	if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) {
 		pr_info("%s: Disabled Multicast RS\n", dev->name);
-		ndev->cnf.rtr_solicits = 0;
+		IN6_DEV_CONF_SET(ndev, RTR_SOLICITS, 0);
 	}
 #endif
 
@@ -379,7 +385,7 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
 	    dev->type == ARPHRD_TUNNEL6 ||
 	    dev->type == ARPHRD_SIT ||
 	    dev->type == ARPHRD_NONE) {
-		ndev->cnf.use_tempaddr = -1;
+		IN6_DEV_CONF_SET(ndev, USE_TEMPADDR, -1);
 	} else {
 		in6_dev_hold(ndev);
 		ipv6_regen_rndid((unsigned long) ndev);
@@ -403,7 +409,7 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
 	ipv6_dev_mc_inc(dev, &in6addr_linklocal_allnodes);
 
 	/* Join all-router multicast group if forwarding is set */
-	if (ndev->cnf.forwarding && (dev->flags & IFF_MULTICAST))
+	if (IN6_DEV_FORWARD(ndev) && (dev->flags & IFF_MULTICAST))
 		ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters);
 
 	return ndev;
@@ -466,16 +472,18 @@ static int inet6_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
 
 	/* type -1 is used for ALL */
 	if ((type == -1 || type == NETCONFA_FORWARDING) &&
-	    nla_put_s32(skb, NETCONFA_FORWARDING, devconf->forwarding) < 0)
+	    nla_put_s32(skb, NETCONFA_FORWARDING,
+			IPV6_DEVCONF(*devconf, FORWARDING)) < 0)
 		goto nla_put_failure;
 #ifdef CONFIG_IPV6_MROUTE
 	if ((type == -1 || type == NETCONFA_MC_FORWARDING) &&
 	    nla_put_s32(skb, NETCONFA_MC_FORWARDING,
-			devconf->mc_forwarding) < 0)
+			IPV6_DEVCONF(*devconf, MC_FORWARDING)) < 0)
 		goto nla_put_failure;
 #endif
 	if ((type == -1 || type == NETCONFA_PROXY_NEIGH) &&
-	    nla_put_s32(skb, NETCONFA_PROXY_NEIGH, devconf->proxy_ndp) < 0)
+	    nla_put_s32(skb, NETCONFA_PROXY_NEIGH,
+			IPV6_DEVCONF(*devconf, PROXY_NDP)) < 0)
 		goto nla_put_failure;
 
 	return nlmsg_end(skb, nlh);
@@ -656,10 +664,10 @@ static void dev_forward_change(struct inet6_dev *idev)
 	if (!idev)
 		return;
 	dev = idev->dev;
-	if (idev->cnf.forwarding)
+	if (IN6_DEV_FORWARD(idev))
 		dev_disable_lro(dev);
 	if (dev->flags & IFF_MULTICAST) {
-		if (idev->cnf.forwarding) {
+		if (IN6_DEV_FORWARD(idev)) {
 			ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters);
 			ipv6_dev_mc_inc(dev, &in6addr_interfacelocal_allrouters);
 			ipv6_dev_mc_inc(dev, &in6addr_sitelocal_allrouters);
@@ -673,7 +681,7 @@ static void dev_forward_change(struct inet6_dev *idev)
 	list_for_each_entry(ifa, &idev->addr_list, if_list) {
 		if (ifa->flags&IFA_F_TENTATIVE)
 			continue;
-		if (idev->cnf.forwarding)
+		if (IN6_DEV_FORWARD(idev))
 			addrconf_join_anycast(ifa);
 		else
 			addrconf_leave_anycast(ifa);
@@ -691,8 +699,9 @@ static void addrconf_forward_change(struct net *net, __s32 newf)
 	for_each_netdev(net, dev) {
 		idev = __in6_dev_get(dev);
 		if (idev) {
-			int changed = (!idev->cnf.forwarding) ^ (!newf);
-			idev->cnf.forwarding = newf;
+			int changed = (!IN6_DEV_FORWARD(idev)) ^ (!newf);
+
+			IN6_DEV_CONF_SET(idev, FORWARDING, newf);
 			if (changed)
 				dev_forward_change(idev);
 		}
@@ -711,7 +720,7 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf)
 	old = *p;
 	*p = newf;
 
-	if (p == &net->ipv6.devconf_dflt->forwarding) {
+	if (p == &IPV6_DEVCONF_DFLT(net, FORWARDING)) {
 		if ((!newf) ^ (!old))
 			inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING,
 						     NETCONFA_IFINDEX_DEFAULT,
@@ -720,15 +729,19 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf)
 		return 0;
 	}
 
-	if (p == &net->ipv6.devconf_all->forwarding) {
-		net->ipv6.devconf_dflt->forwarding = newf;
+	if (p == &IPV6_DEVCONF_ALL(net, FORWARDING)) {
+		IPV6_DEVCONF_DFLT(net, FORWARDING) = newf;
 		addrconf_forward_change(net, newf);
 		if ((!newf) ^ (!old))
 			inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING,
 						     NETCONFA_IFINDEX_ALL,
 						     net->ipv6.devconf_all);
-	} else if ((!newf) ^ (!old))
-		dev_forward_change((struct inet6_dev *)table->extra1);
+	} else if ((!newf) ^ (!old)) {
+		struct ipv6_devconf *cnf = table->extra1;
+		struct inet6_dev *idev =
+			container_of(cnf, struct inet6_dev, cnf);
+		dev_forward_change(idev);
+	}
 	rtnl_unlock();
 
 	if (newf)
@@ -811,7 +824,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr,
 		goto out2;
 	}
 
-	if (idev->cnf.disable_ipv6) {
+	if (IN6_DEV_DISABLE_IPV6(idev)) {
 		err = -EACCES;
 		goto out2;
 	}
@@ -1059,7 +1072,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i
 	}
 retry:
 	in6_dev_hold(idev);
-	if (idev->cnf.use_tempaddr <= 0) {
+	if (IN6_DEV_USE_TEMPADDR(idev) <= 0) {
 		write_unlock_bh(&idev->lock);
 		pr_info("%s: use_tempaddr is disabled\n", __func__);
 		in6_dev_put(idev);
@@ -1067,8 +1080,8 @@ retry:
 		goto out;
 	}
 	spin_lock_bh(&ifp->lock);
-	if (ifp->regen_count++ >= idev->cnf.regen_max_retry) {
-		idev->cnf.use_tempaddr = -1;	/*XXX*/
+	if (ifp->regen_count++ >= IN6_DEV_REGEN_MAX_RETRY(idev)) {
+		IN6_DEV_CONF_SET(idev, USE_TEMPADDR, -1);	/*XXX*/
 		spin_unlock_bh(&ifp->lock);
 		write_unlock_bh(&idev->lock);
 		pr_warn("%s: regeneration time exceeded - disabled temporary address support\n",
@@ -1084,18 +1097,18 @@ retry:
 	age = (now - ifp->tstamp) / HZ;
 	tmp_valid_lft = min_t(__u32,
 			      ifp->valid_lft,
-			      idev->cnf.temp_valid_lft + age);
+			      IN6_DEV_TEMP_VALID_LFT(idev) + age);
 	tmp_prefered_lft = min_t(__u32,
 				 ifp->prefered_lft,
-				 idev->cnf.temp_prefered_lft + age -
-				 idev->cnf.max_desync_factor);
+				 IN6_DEV_TEMP_PREFERED_LFT(idev) + age -
+				 IN6_DEV_MAX_DESYNC_FACTOR(idev));
 	tmp_plen = ifp->prefix_len;
 	tmp_tstamp = ifp->tstamp;
 	spin_unlock_bh(&ifp->lock);
 
-	regen_advance = idev->cnf.regen_max_retry *
-	                idev->cnf.dad_transmits *
-	                NEIGH_VAR(idev->nd_parms, RETRANS_TIME) / HZ;
+	regen_advance = IN6_DEV_REGEN_MAX_RETRY(idev) *
+			IN6_DEV_DAD_TRANSMITS(idev) *
+			NEIGH_VAR(idev->nd_parms, RETRANS_TIME) / HZ;
 	write_unlock_bh(&idev->lock);
 
 	/* A temporary address is created only if this calculated Preferred
@@ -1277,7 +1290,7 @@ static int ipv6_get_saddr_eval(struct net *net,
 		 */
 		int preftmp = dst->prefs & (IPV6_PREFER_SRC_PUBLIC|IPV6_PREFER_SRC_TMP) ?
 				!!(dst->prefs & IPV6_PREFER_SRC_TMP) :
-				score->ifa->idev->cnf.use_tempaddr >= 2;
+				IN6_DEV_USE_TEMPADDR(score->ifa->idev) >= 2;
 		ret = (!(score->ifa->flags & IFA_F_TEMPORARY)) ^ preftmp;
 		break;
 	    }
@@ -1655,7 +1668,8 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
 	net_info_ratelimited("%s: IPv6 duplicate address %pI6c detected!\n",
 			     ifp->idev->dev->name, &ifp->addr);
 
-	if (idev->cnf.accept_dad > 1 && !idev->cnf.disable_ipv6) {
+	if (IN6_DEV_ACCEPT_DAD(idev) > 1 &&
+	    !IN6_DEV_DISABLE_IPV6(idev)) {
 		struct in6_addr addr;
 
 		addr.s6_addr32[0] = htonl(0xfe800000);
@@ -1664,7 +1678,7 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
 		if (!ipv6_generate_eui64(addr.s6_addr + 8, idev->dev) &&
 		    ipv6_addr_equal(&ifp->addr, &addr)) {
 			/* DAD failed for link-local based on MAC address */
-			idev->cnf.disable_ipv6 = 1;
+			IN6_DEV_CONF_SET(idev, DISABLE_IPV6, 1);
 
 			pr_info("%s: IPv6 being disabled!\n",
 				ifp->idev->dev->name);
@@ -1935,10 +1949,11 @@ static void ipv6_regen_rndid(unsigned long data)
 	__ipv6_regen_rndid(idev);
 
 	expires = jiffies +
-		idev->cnf.temp_prefered_lft * HZ -
-		idev->cnf.regen_max_retry * idev->cnf.dad_transmits *
+		IN6_DEV_TEMP_PREFERED_LFT(idev) * HZ -
+		IN6_DEV_REGEN_MAX_RETRY(idev) *
+		IN6_DEV_DAD_TRANSMITS(idev) *
 		NEIGH_VAR(idev->nd_parms, RETRANS_TIME) -
-		idev->cnf.max_desync_factor * HZ;
+		IN6_DEV_MAX_DESYNC_FACTOR(idev) * HZ;
 	if (time_before(expires, jiffies)) {
 		pr_warn("%s: too short regeneration interval; timer disabled for %s\n",
 			__func__, idev->dev->name);
@@ -2055,7 +2070,7 @@ static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
 	if (!idev)
 		return ERR_PTR(-ENOBUFS);
 
-	if (idev->cnf.disable_ipv6)
+	if (IN6_DEV_DISABLE_IPV6(idev))
 		return ERR_PTR(-EACCES);
 
 	/* Add default multicast route */
@@ -2090,12 +2105,13 @@ static void manage_tempaddrs(struct inet6_dev *idev,
 		 * (TEMP_PREFERRED_LIFETIME - DESYNC_FACTOR), respectively.
 		 */
 		age = (now - ift->cstamp) / HZ;
-		max_valid = idev->cnf.temp_valid_lft - age;
+		max_valid = IN6_DEV_TEMP_VALID_LFT(idev) - age;
 		if (max_valid < 0)
 			max_valid = 0;
 
-		max_prefered = idev->cnf.temp_prefered_lft -
-			       idev->cnf.max_desync_factor - age;
+		max_prefered = IN6_DEV_TEMP_PREFERED_LFT(idev) -
+			       IN6_DEV_MAX_DESYNC_FACTOR(idev) -
+			       age;
 		if (max_prefered < 0)
 			max_prefered = 0;
 
@@ -2119,7 +2135,7 @@ static void manage_tempaddrs(struct inet6_dev *idev,
 	}
 
 	if ((create || list_empty(&idev->tempaddr_list)) &&
-	    idev->cnf.use_tempaddr > 0) {
+	    IN6_DEV_USE_TEMPADDR(idev) > 0) {
 		/* When a new public address is created as described
 		 * in [ADDRCONF], also create a new temporary address.
 		 * Also create a temporary address if it's enabled but
@@ -2229,7 +2245,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao)
 
 	/* Try to figure out our local address for this prefix */
 
-	if (pinfo->autoconf && in6_dev->cnf.autoconf) {
+	if (pinfo->autoconf && IN6_DEV_AUTOCONF(in6_dev)) {
 		struct inet6_ifaddr *ifp;
 		struct in6_addr addr;
 		int create = 0, update_lft = 0;
@@ -2261,12 +2277,12 @@ ok:
 		ifp = ipv6_get_ifaddr(net, &addr, dev, 1);
 
 		if (ifp == NULL && valid_lft) {
-			int max_addresses = in6_dev->cnf.max_addresses;
+			int max_addresses = IN6_DEV_MAX_ADDRESSES(in6_dev);
 			u32 addr_flags = 0;
 
 #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
-			if (in6_dev->cnf.optimistic_dad &&
-			    !net->ipv6.devconf_all->forwarding && sllao)
+			if (IN6_DEV_OPTIMISTIC_DAD(in6_dev) &&
+			    !IPV6_DEVCONF_ALL(net, FORWARDING) && sllao)
 				addr_flags = IFA_F_OPTIMISTIC;
 #endif
 
@@ -2713,8 +2729,8 @@ static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr
 	u32 addr_flags = IFA_F_PERMANENT;
 
 #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
-	if (idev->cnf.optimistic_dad &&
-	    !dev_net(idev->dev)->ipv6.devconf_all->forwarding)
+	if (IN6_DEV_OPTIMISTIC_DAD(idev) &&
+	    !IPV6_DEVCONF_ALL(dev_net(idev->dev), FORWARDING))
 		addr_flags |= IFA_F_OPTIMISTIC;
 #endif
 
@@ -2898,10 +2914,10 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
 			 * when the interface up, the changed MTU must be
 			 * reflected in the idev as well as routers.
 			 */
-			if (idev->cnf.mtu6 != dev->mtu &&
+			if (IN6_DEV_MTU(idev) != dev->mtu &&
 			    dev->mtu >= IPV6_MIN_MTU) {
 				rt6_mtu_change(dev, dev->mtu);
-				idev->cnf.mtu6 = dev->mtu;
+				IN6_DEV_CONF_SET(idev, MTU6, dev->mtu);
 			}
 			idev->tstamp = jiffies;
 			inet6_ifinfo_notify(RTM_NEWLINK, idev);
@@ -2918,7 +2934,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
 	case NETDEV_CHANGEMTU:
 		if (idev && dev->mtu >= IPV6_MIN_MTU) {
 			rt6_mtu_change(dev, dev->mtu);
-			idev->cnf.mtu6 = dev->mtu;
+			IN6_DEV_CONF_SET(idev, MTU6, dev->mtu);
 			break;
 		}
 
@@ -3116,7 +3132,7 @@ static void addrconf_rs_timer(unsigned long data)
 	if (idev->if_flags & IF_RA_RCVD)
 		goto out;
 
-	if (idev->rs_probes++ < idev->cnf.rtr_solicits) {
+	if (idev->rs_probes++ < IN6_DEV_RTR_SOLICITS(idev)) {
 		write_unlock(&idev->lock);
 		if (!ipv6_get_lladdr(dev, &lladdr, IFA_F_TENTATIVE))
 			ndisc_send_rs(dev, &lladdr,
@@ -3127,9 +3143,9 @@ static void addrconf_rs_timer(unsigned long data)
 		write_lock(&idev->lock);
 		/* The wait after the last probe can be shorter */
 		addrconf_mod_rs_timer(idev, (idev->rs_probes ==
-					     idev->cnf.rtr_solicits) ?
-				      idev->cnf.rtr_solicit_delay :
-				      idev->cnf.rtr_solicit_interval);
+					     IN6_DEV_RTR_SOLICITS(idev)) ?
+				      IN6_DEV_RTR_SOLICIT_DELAY(idev) :
+				      IN6_DEV_RTR_SOLICIT_INTERVAL(idev));
 	} else {
 		/*
 		 * Note: we do not support deprecated "all on-link"
@@ -3155,9 +3171,10 @@ static void addrconf_dad_kick(struct inet6_ifaddr *ifp)
 	if (ifp->flags & IFA_F_OPTIMISTIC)
 		rand_num = 0;
 	else
-		rand_num = prandom_u32() % (idev->cnf.rtr_solicit_delay ? : 1);
+		rand_num = prandom_u32() %
+			   (IN6_DEV_RTR_SOLICIT_DELAY(idev) ? : 1);
 
-	ifp->dad_probes = idev->cnf.dad_transmits;
+	ifp->dad_probes = IN6_DEV_DAD_TRANSMITS(idev);
 	addrconf_mod_dad_work(ifp, rand_num);
 }
 
@@ -3176,7 +3193,7 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp)
 		goto out;
 
 	if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
-	    idev->cnf.accept_dad < 1 ||
+	    IN6_DEV_ACCEPT_DAD(idev) < 1 ||
 	    !(ifp->flags&IFA_F_TENTATIVE) ||
 	    ifp->flags & IFA_F_NODAD) {
 		ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED);
@@ -3346,7 +3363,7 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
 	send_mld = ifp->scope == IFA_LINK && ipv6_lonely_lladdr(ifp);
 	send_rs = send_mld &&
 		  ipv6_accept_ra(ifp->idev) &&
-		  ifp->idev->cnf.rtr_solicits > 0 &&
+		  IN6_DEV_RTR_SOLICITS(ifp->idev) > 0 &&
 		  (dev->flags&IFF_LOOPBACK) == 0;
 	read_unlock_bh(&ifp->idev->lock);
 
@@ -3371,7 +3388,7 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
 		ifp->idev->rs_probes = 1;
 		ifp->idev->if_flags |= IF_RS_SENT;
 		addrconf_mod_rs_timer(ifp->idev,
-				      ifp->idev->cnf.rtr_solicit_interval);
+				      IN6_DEV_RTR_SOLICIT_INTERVAL(ifp->idev));
 		spin_unlock(&ifp->lock);
 		write_unlock_bh(&ifp->idev->lock);
 	}
@@ -3635,8 +3652,9 @@ restart:
 				}
 			} else if ((ifp->flags&IFA_F_TEMPORARY) &&
 				   !(ifp->flags&IFA_F_TENTATIVE)) {
-				unsigned long regen_advance = ifp->idev->cnf.regen_max_retry *
-					ifp->idev->cnf.dad_transmits *
+				unsigned long regen_advance =
+					IN6_DEV_REGEN_MAX_RETRY(ifp->idev) *
+					IN6_DEV_DAD_TRANSMITS(ifp->idev) *
 					NEIGH_VAR(ifp->idev->nd_parms, RETRANS_TIME) / HZ;
 
 				if (age >= ifp->prefered_lft - regen_advance) {
@@ -4275,52 +4293,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
 	BUG_ON(bytes < (IPV6_DEVCONF_MAX * 4));
 
 	memset(array, 0, bytes);
-	array[IPV6_DEVCONF_FORWARDING] = cnf->forwarding;
-	array[IPV6_DEVCONF_HOPLIMIT] = cnf->hop_limit;
-	array[IPV6_DEVCONF_MTU6] = cnf->mtu6;
-	array[IPV6_DEVCONF_ACCEPT_RA] = cnf->accept_ra;
-	array[IPV6_DEVCONF_ACCEPT_REDIRECTS] = cnf->accept_redirects;
-	array[IPV6_DEVCONF_AUTOCONF] = cnf->autoconf;
-	array[IPV6_DEVCONF_DAD_TRANSMITS] = cnf->dad_transmits;
-	array[IPV6_DEVCONF_RTR_SOLICITS] = cnf->rtr_solicits;
-	array[IPV6_DEVCONF_RTR_SOLICIT_INTERVAL] =
-		jiffies_to_msecs(cnf->rtr_solicit_interval);
-	array[IPV6_DEVCONF_RTR_SOLICIT_DELAY] =
-		jiffies_to_msecs(cnf->rtr_solicit_delay);
-	array[IPV6_DEVCONF_FORCE_MLD_VERSION] = cnf->force_mld_version;
-	array[IPV6_DEVCONF_MLDV1_UNSOLICITED_REPORT_INTERVAL] =
-		jiffies_to_msecs(cnf->mldv1_unsolicited_report_interval);
-	array[IPV6_DEVCONF_MLDV2_UNSOLICITED_REPORT_INTERVAL] =
-		jiffies_to_msecs(cnf->mldv2_unsolicited_report_interval);
-	array[IPV6_DEVCONF_USE_TEMPADDR] = cnf->use_tempaddr;
-	array[IPV6_DEVCONF_TEMP_VALID_LFT] = cnf->temp_valid_lft;
-	array[IPV6_DEVCONF_TEMP_PREFERED_LFT] = cnf->temp_prefered_lft;
-	array[IPV6_DEVCONF_REGEN_MAX_RETRY] = cnf->regen_max_retry;
-	array[IPV6_DEVCONF_MAX_DESYNC_FACTOR] = cnf->max_desync_factor;
-	array[IPV6_DEVCONF_MAX_ADDRESSES] = cnf->max_addresses;
-	array[IPV6_DEVCONF_ACCEPT_RA_DEFRTR] = cnf->accept_ra_defrtr;
-	array[IPV6_DEVCONF_ACCEPT_RA_PINFO] = cnf->accept_ra_pinfo;
-#ifdef CONFIG_IPV6_ROUTER_PREF
-	array[IPV6_DEVCONF_ACCEPT_RA_RTR_PREF] = cnf->accept_ra_rtr_pref;
-	array[IPV6_DEVCONF_RTR_PROBE_INTERVAL] =
-		jiffies_to_msecs(cnf->rtr_probe_interval);
-#ifdef CONFIG_IPV6_ROUTE_INFO
-	array[IPV6_DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen;
-#endif
-#endif
-	array[IPV6_DEVCONF_PROXY_NDP] = cnf->proxy_ndp;
-	array[IPV6_DEVCONF_ACCEPT_SOURCE_ROUTE] = cnf->accept_source_route;
-#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
-	array[IPV6_DEVCONF_OPTIMISTIC_DAD] = cnf->optimistic_dad;
-#endif
-#ifdef CONFIG_IPV6_MROUTE
-	array[IPV6_DEVCONF_MC_FORWARDING] = cnf->mc_forwarding;
-#endif
-	array[IPV6_DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6;
-	array[IPV6_DEVCONF_ACCEPT_DAD] = cnf->accept_dad;
-	array[IPV6_DEVCONF_FORCE_TLLAO] = cnf->force_tllao;
-	array[IPV6_DEVCONF_NDISC_NOTIFY] = cnf->ndisc_notify;
-	array[IPV6_DEVCONF_SUPPRESS_FRAG_NDISC] = cnf->suppress_frag_ndisc;
+	memcpy(array, cnf->data, bytes);
 }
 
 static inline size_t inet6_ifla6_size(void)
@@ -4468,7 +4441,7 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token)
 		return -EINVAL;
 	if (!ipv6_accept_ra(idev))
 		return -EINVAL;
-	if (idev->cnf.rtr_solicits <= 0)
+	if (IN6_DEV_RTR_SOLICITS(idev) <= 0)
 		return -EINVAL;
 
 	write_lock_bh(&idev->lock);
@@ -4494,7 +4467,7 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token)
 	if (update_rs) {
 		idev->if_flags |= IF_RS_SENT;
 		idev->rs_probes = 1;
-		addrconf_mod_rs_timer(idev, idev->cnf.rtr_solicit_interval);
+		addrconf_mod_rs_timer(idev, IN6_DEV_RTR_SOLICIT_INTERVAL(idev));
 	}
 
 	/* Well, that's kinda nasty ... */
@@ -4725,14 +4698,14 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
 		 */
 		if (!(ifp->rt->rt6i_node))
 			ip6_ins_rt(ifp->rt);
-		if (ifp->idev->cnf.forwarding)
+		if (IN6_DEV_FORWARD(ifp->idev))
 			addrconf_join_anycast(ifp);
 		if (!ipv6_addr_any(&ifp->peer_addr))
 			addrconf_prefix_route(&ifp->peer_addr, 128,
 					      ifp->idev->dev, 0, 0);
 		break;
 	case RTM_DELADDR:
-		if (ifp->idev->cnf.forwarding)
+		if (IN6_DEV_FORWARD(ifp->idev))
 			addrconf_leave_anycast(ifp);
 		addrconf_leave_solict(ifp->idev, &ifp->addr);
 		if (!ipv6_addr_any(&ifp->peer_addr)) {
@@ -4778,8 +4751,8 @@ int addrconf_sysctl_forward(struct ctl_table *ctl, int write,
 	int ret;
 
 	/*
-	 * ctl->data points to idev->cnf.forwarding, we should
-	 * not modify it until we get the rtnl lock.
+	 * ctl->data points to idev->cnf.data[IPV6_DEVCONF_FORWARDING],
+	 * we should not modify it until we get the rtnl lock.
 	 */
 	lctl = *ctl;
 	lctl.data = &val;
@@ -4801,7 +4774,7 @@ static void dev_disable_change(struct inet6_dev *idev)
 		return;
 
 	netdev_notifier_info_init(&info, idev->dev);
-	if (idev->cnf.disable_ipv6)
+	if (IN6_DEV_DISABLE_IPV6(idev))
 		addrconf_notify(NULL, NETDEV_DOWN, &info);
 	else
 		addrconf_notify(NULL, NETDEV_UP, &info);
@@ -4816,8 +4789,9 @@ static void addrconf_disable_change(struct net *net, __s32 newf)
 	for_each_netdev_rcu(net, dev) {
 		idev = __in6_dev_get(dev);
 		if (idev) {
-			int changed = (!idev->cnf.disable_ipv6) ^ (!newf);
-			idev->cnf.disable_ipv6 = newf;
+			int changed = (!IN6_DEV_DISABLE_IPV6(idev)) ^ (!newf);
+
+			IN6_DEV_CONF_SET(idev, DISABLE_IPV6, newf);
 			if (changed)
 				dev_disable_change(idev);
 		}
@@ -4837,16 +4811,20 @@ static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int newf)
 	old = *p;
 	*p = newf;
 
-	if (p == &net->ipv6.devconf_dflt->disable_ipv6) {
+	if (p == &IPV6_DEVCONF_DFLT(net, DISABLE_IPV6)) {
 		rtnl_unlock();
 		return 0;
 	}
 
-	if (p == &net->ipv6.devconf_all->disable_ipv6) {
-		net->ipv6.devconf_dflt->disable_ipv6 = newf;
+	if (p == &IPV6_DEVCONF_ALL(net, DISABLE_IPV6)) {
+		IPV6_DEVCONF_DFLT(net, DISABLE_IPV6) = newf;
 		addrconf_disable_change(net, newf);
-	} else if ((!newf) ^ (!old))
-		dev_disable_change((struct inet6_dev *)table->extra1);
+	} else if ((!newf) ^ (!old)) {
+		struct ipv6_devconf *cnf = table->extra1;
+		struct inet6_dev *idev =
+			container_of(cnf, struct inet6_dev, cnf);
+		dev_disable_change(idev);
+	}
 
 	rtnl_unlock();
 	return 0;
@@ -4863,8 +4841,8 @@ int addrconf_sysctl_disable(struct ctl_table *ctl, int write,
 	int ret;
 
 	/*
-	 * ctl->data points to idev->cnf.disable_ipv6, we should
-	 * not modify it until we get the rtnl lock.
+	 * ctl->data points to idev->cnf.data[IPV6_DEVCONF_DISABLE_IPV6],
+	 * we should not modify it until we get the rtnl lock.
 	 */
 	lctl = *ctl;
 	lctl.data = &val;
@@ -4896,16 +4874,18 @@ int addrconf_sysctl_proxy_ndp(struct ctl_table *ctl, int write,
 		if (!rtnl_trylock())
 			return restart_syscall();
 
-		if (valp == &net->ipv6.devconf_dflt->proxy_ndp)
+		if (valp == &IPV6_DEVCONF_DFLT(net, PROXY_NDP))
 			inet6_netconf_notify_devconf(net, NETCONFA_PROXY_NEIGH,
 						     NETCONFA_IFINDEX_DEFAULT,
 						     net->ipv6.devconf_dflt);
-		else if (valp == &net->ipv6.devconf_all->proxy_ndp)
+		else if (valp == &IPV6_DEVCONF_ALL(net, PROXY_NDP))
 			inet6_netconf_notify_devconf(net, NETCONFA_PROXY_NEIGH,
 						     NETCONFA_IFINDEX_ALL,
 						     net->ipv6.devconf_all);
 		else {
-			struct inet6_dev *idev = ctl->extra1;
+			struct ipv6_devconf *cnf = ctl->extra1;
+			struct inet6_dev *idev =
+				container_of(cnf, struct inet6_dev, cnf);
 
 			inet6_netconf_notify_devconf(net, NETCONFA_PROXY_NEIGH,
 						     idev->dev->ifindex,
@@ -4917,27 +4897,25 @@ int addrconf_sysctl_proxy_ndp(struct ctl_table *ctl, int write,
 	return ret;
 }
 
-#define ADDRCONF_SYSCTL_ENTRY(name, var, mval, proc) \
+#define ADDRCONF_SYSCTL_ENTRY(attr, name, mval, proc) \
 	{ \
 		.procname	= #name, \
-		.data		= (void *)&ipv6_devconf + \
-				offsetof(struct ipv6_devconf, var), \
+		.data		= ipv6_devconf.data + \
+				  IPV6_DEVCONF_ ## attr, \
 		.maxlen		= sizeof(int), \
 		.mode		= mval, \
 		.proc_handler	= proc, \
+		.extra1		= &ipv6_devconf, \
 	}
 
-#define ADDRCONF_SYSCTL_RW_ENTRY(name) \
-	ADDRCONF_SYSCTL_ENTRY(name, name, 0644, proc_dointvec)
+#define ADDRCONF_SYSCTL_RW_ENTRY(attr, name) \
+	ADDRCONF_SYSCTL_ENTRY(attr, name, 0644, proc_dointvec)
 
-#define ADDRCONF_SYSCTL_RO_ENTRY(name) \
-	ADDRCONF_SYSCTL_ENTRY(name, name, 0444, proc_dointvec)
+#define ADDRCONF_SYSCTL_RO_ENTRY(attr, name) \
+	ADDRCONF_SYSCTL_ENTRY(attr, name, 0444, proc_dointvec)
 
-#define ADDRCONF_SYSCTL_COMPLEX_ENTRY(name, proc) \
-	ADDRCONF_SYSCTL_ENTRY(name, name, 0644, proc)
-
-#define ADDRCONF_SYSCTL_CUSTOM_ENTRY(name, var, proc) \
-	ADDRCONF_SYSCTL_ENTRY(name, var, 0644, proc)
+#define ADDRCONF_SYSCTL_COMPLEX_ENTRY(attr, name, proc) \
+	ADDRCONF_SYSCTL_ENTRY(attr, name, 0644, proc)
 
 static struct addrconf_sysctl_table
 {
@@ -4946,62 +4924,64 @@ static struct addrconf_sysctl_table
 } addrconf_sysctl __read_mostly = {
 	.sysctl_header = NULL,
 	.addrconf_vars = {
-		ADDRCONF_SYSCTL_COMPLEX_ENTRY(forwarding,
+		ADDRCONF_SYSCTL_COMPLEX_ENTRY(FORWARDING, forwarding,
 					      addrconf_sysctl_forward),
-		ADDRCONF_SYSCTL_RW_ENTRY(hop_limit),
-		ADDRCONF_SYSCTL_CUSTOM_ENTRY(mtu, mtu6, proc_dointvec),
-		ADDRCONF_SYSCTL_RW_ENTRY(accept_ra),
-		ADDRCONF_SYSCTL_RW_ENTRY(accept_redirects),
-		ADDRCONF_SYSCTL_RW_ENTRY(autoconf),
-		ADDRCONF_SYSCTL_RW_ENTRY(dad_transmits),
-		ADDRCONF_SYSCTL_CUSTOM_ENTRY(router_solicitations, rtr_solicits,
-					     proc_dointvec),
-		ADDRCONF_SYSCTL_CUSTOM_ENTRY(router_solicitation_interval,
-					     rtr_solicit_interval,
-					     proc_dointvec_jiffies),
-		ADDRCONF_SYSCTL_CUSTOM_ENTRY(router_solicitation_delay,
-					     rtr_solicit_delay,
-					     proc_dointvec_jiffies),
-		ADDRCONF_SYSCTL_RW_ENTRY(force_mld_version),
-		ADDRCONF_SYSCTL_COMPLEX_ENTRY(mldv1_unsolicited_report_interval,
-					      proc_dointvec_ms_jiffies),
-		ADDRCONF_SYSCTL_COMPLEX_ENTRY(mldv2_unsolicited_report_interval,
-					      proc_dointvec_ms_jiffies),
-		ADDRCONF_SYSCTL_RW_ENTRY(use_tempaddr),
-		ADDRCONF_SYSCTL_RW_ENTRY(temp_valid_lft),
-		ADDRCONF_SYSCTL_RW_ENTRY(temp_prefered_lft),
-		ADDRCONF_SYSCTL_RW_ENTRY(regen_max_retry),
-		ADDRCONF_SYSCTL_RW_ENTRY(max_desync_factor),
-		ADDRCONF_SYSCTL_RW_ENTRY(max_addresses),
-		ADDRCONF_SYSCTL_RW_ENTRY(accept_ra_defrtr),
-		ADDRCONF_SYSCTL_RW_ENTRY(accept_ra_pinfo),
+		ADDRCONF_SYSCTL_RW_ENTRY(HOPLIMIT, hop_limit),
+		ADDRCONF_SYSCTL_RW_ENTRY(MTU6, mtu),
+		ADDRCONF_SYSCTL_RW_ENTRY(ACCEPT_RA, accept_ra),
+		ADDRCONF_SYSCTL_RW_ENTRY(ACCEPT_REDIRECTS, accept_redirects),
+		ADDRCONF_SYSCTL_RW_ENTRY(AUTOCONF, autoconf),
+		ADDRCONF_SYSCTL_RW_ENTRY(DAD_TRANSMITS, dad_transmits),
+		ADDRCONF_SYSCTL_RW_ENTRY(RTR_SOLICITS, router_solicitations),
+		ADDRCONF_SYSCTL_RW_ENTRY(RTR_SOLICIT_INTERVAL,
+					 router_solicitation_interval),
+		ADDRCONF_SYSCTL_RW_ENTRY(RTR_SOLICIT_DELAY,
+					 router_solicitation_delay),
+		ADDRCONF_SYSCTL_RW_ENTRY(FORCE_MLD_VERSION, force_mld_version),
+		ADDRCONF_SYSCTL_COMPLEX_ENTRY(
+				MLDV1_UNSOLICITED_REPORT_INTERVAL,
+				mldv1_unsolicited_report_interval,
+				proc_dointvec_ms_jiffies),
+		ADDRCONF_SYSCTL_COMPLEX_ENTRY(
+				MLDV2_UNSOLICITED_REPORT_INTERVAL,
+				mldv2_unsolicited_report_interval,
+				proc_dointvec_ms_jiffies),
+		ADDRCONF_SYSCTL_RW_ENTRY(USE_TEMPADDR, use_tempaddr),
+		ADDRCONF_SYSCTL_RW_ENTRY(TEMP_VALID_LFT, temp_valid_lft),
+		ADDRCONF_SYSCTL_RW_ENTRY(TEMP_PREFERED_LFT, temp_prefered_lft),
+		ADDRCONF_SYSCTL_RW_ENTRY(REGEN_MAX_RETRY, regen_max_retry),
+		ADDRCONF_SYSCTL_RW_ENTRY(MAX_DESYNC_FACTOR, max_desync_factor),
+		ADDRCONF_SYSCTL_RW_ENTRY(MAX_ADDRESSES, max_addresses),
+		ADDRCONF_SYSCTL_RW_ENTRY(ACCEPT_RA_DEFRTR, accept_ra_defrtr),
+		ADDRCONF_SYSCTL_RW_ENTRY(ACCEPT_RA_PINFO, accept_ra_pinfo),
 #ifdef CONFIG_IPV6_ROUTER_PREF
-		ADDRCONF_SYSCTL_RW_ENTRY(accept_ra_rtr_pref),
-		ADDRCONF_SYSCTL_CUSTOM_ENTRY(router_probe_interval,
-					     rtr_probe_interval,
-					     proc_dointvec_jiffies),
+		ADDRCONF_SYSCTL_RW_ENTRY(ACCEPT_RA_RTR_PREF,
+					 accept_ra_rtr_pref),
+		ADDRCONF_SYSCTL_COMPLEX_ENTRY(RTR_PROBE_INTERVAL,
+					      router_probe_interval,
+					      proc_dointvec_jiffies),
 #ifdef CONFIG_IPV6_ROUTE_INFO
-		ADDRCONF_SYSCTL_RW_ENTRY(accept_ra_rt_info_max_plen),
+		ADDRCONF_SYSCTL_RW_ENTRY(ACCEPT_RA_RT_INFO_MAX_PLEN,
+					 accept_ra_rt_info_max_plen),
 #endif
 #endif
-		ADDRCONF_SYSCTL_COMPLEX_ENTRY(proxy_ndp,
+		ADDRCONF_SYSCTL_COMPLEX_ENTRY(PROXY_NDP, proxy_ndp,
 					      addrconf_sysctl_proxy_ndp),
-		ADDRCONF_SYSCTL_RW_ENTRY(accept_source_route),
+		ADDRCONF_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE,
+					 accept_source_route),
 #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
-		ADDRCONF_SYSCTL_RW_ENTRY(optimistic_dad),
+		ADDRCONF_SYSCTL_RW_ENTRY(OPTIMISTIC_DAD, optimistic_dad),
 #endif
 #ifdef CONFIG_IPV6_MROUTE
-		ADDRCONF_SYSCTL_RO_ENTRY(mc_forwarding),
+		ADDRCONF_SYSCTL_RO_ENTRY(MC_FORWARDING, mc_forwarding),
 #endif
-		ADDRCONF_SYSCTL_COMPLEX_ENTRY(disable_ipv6,
+		ADDRCONF_SYSCTL_COMPLEX_ENTRY(DISABLE_IPV6, disable_ipv6,
 					      addrconf_sysctl_disable),
-		ADDRCONF_SYSCTL_RW_ENTRY(accept_dad),
-		ADDRCONF_SYSCTL_RW_ENTRY(force_tllao),
-		ADDRCONF_SYSCTL_RW_ENTRY(ndisc_notify),
-		ADDRCONF_SYSCTL_RW_ENTRY(suppress_frag_ndisc),
-		{
-			/* sentinel */
-		}
+		ADDRCONF_SYSCTL_RW_ENTRY(ACCEPT_DAD, accept_dad),
+		ADDRCONF_SYSCTL_RW_ENTRY(FORCE_TLLAO, force_tllao),
+		ADDRCONF_SYSCTL_RW_ENTRY(NDISC_NOTIFY, ndisc_notify),
+		ADDRCONF_SYSCTL_RW_ENTRY(SUPPRESS_FRAG_NDISC,
+					 suppress_frag_ndisc),
 	},
 };
 
@@ -5018,7 +4998,7 @@ static int __addrconf_sysctl_register(struct net *net, char *dev_name,
 
 	for (i = 0; t->addrconf_vars[i].data; i++) {
 		t->addrconf_vars[i].data += (char *)p - (char *)&ipv6_devconf;
-		t->addrconf_vars[i].extra1 = idev; /* embedded; no ref */
+		t->addrconf_vars[i].extra1 = p;
 		t->addrconf_vars[i].extra2 = net;
 	}
 
@@ -5081,8 +5061,8 @@ static int __net_init addrconf_init_net(struct net *net)
 		goto err_alloc_dflt;
 
 	/* these will be inherited by all namespaces */
-	dflt->autoconf = ipv6_defaults.autoconf;
-	dflt->disable_ipv6 = ipv6_defaults.disable_ipv6;
+	IPV6_DEVCONF(*dflt, AUTOCONF) = ipv6_defaults.autoconf;
+	IPV6_DEVCONF(*dflt, DISABLE_IPV6) = ipv6_defaults.disable_ipv6;
 
 	net->ipv6.devconf_all = all;
 	net->ipv6.devconf_dflt = dflt;
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 2101832..4a9beac 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -61,7 +61,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
 	struct inet6_dev *idev;
 	struct ipv6_ac_socklist *pac;
 	struct net *net = sock_net(sk);
-	int	ishost = !net->ipv6.devconf_all->forwarding;
+	int	ishost = !IPV6_DEVCONF_ALL(net, FORWARDING);
 	int	err = 0;
 
 	if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
@@ -110,7 +110,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
 		goto error;
 	}
 	/* reset ishost, now that we have a specific device */
-	ishost = !idev->cnf.forwarding;
+	ishost = !IN6_DEV_FORWARD(idev);
 
 	pac->acl_ifindex = dev->ifindex;
 
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 8d67900..9fcf463 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -295,16 +295,12 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb)
 	struct inet6_skb_parm *opt = IP6CB(skb);
 	struct in6_addr *addr = NULL;
 	struct in6_addr daddr;
-	struct inet6_dev *idev;
 	int n, i;
 	struct ipv6_rt_hdr *hdr;
 	struct rt0_hdr *rthdr;
 	struct net *net = dev_net(skb->dev);
-	int accept_source_route = net->ipv6.devconf_all->accept_source_route;
-
-	idev = __in6_dev_get(skb->dev);
-	if (idev && accept_source_route > idev->cnf.accept_source_route)
-		accept_source_route = idev->cnf.accept_source_route;
+	int accept_source_route =
+		IN6_DEV_ACCEPT_SOURCE_ROUTE(__in6_dev_get(skb->dev));
 
 	if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) ||
 	    !pskb_may_pull(skb, (skb_transport_offset(skb) +
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 51d54dc..67345a4 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -81,7 +81,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
 	IP6_UPD_PO_STATS_BH(net, idev, IPSTATS_MIB_IN, skb->len);
 
 	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL ||
-	    !idev || unlikely(idev->cnf.disable_ipv6)) {
+	    !idev || IN6_DEV_DISABLE_IPV6(idev)) {
 		IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDISCARDS);
 		goto drop;
 	}
@@ -296,7 +296,7 @@ int ip6_mc_input(struct sk_buff *skb)
 	/*
 	 *      IPv6 multicast router mode is now supported ;)
 	 */
-	if (dev_net(skb->dev)->ipv6.devconf_all->mc_forwarding &&
+	if (IN6_DEV_MFORWARD(__in6_dev_get(skb->dev)) &&
 	    !(ipv6_addr_type(&hdr->daddr) &
 	      (IPV6_ADDR_LOOPBACK|IPV6_ADDR_LINKLOCAL)) &&
 	    likely(!(IP6CB(skb)->flags & IP6SKB_FORWARDED))) {
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index cb9df0e..db05c4c 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -136,7 +136,7 @@ int ip6_output(struct sock *sk, struct sk_buff *skb)
 {
 	struct net_device *dev = skb_dst(skb)->dev;
 	struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
-	if (unlikely(idev->cnf.disable_ipv6)) {
+	if (IN6_DEV_DISABLE_IPV6(idev)) {
 		IP6_INC_STATS(dev_net(dev), idev,
 			      IPSTATS_MIB_OUTDISCARDS);
 		kfree_skb(skb);
@@ -336,7 +336,7 @@ static unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst)
 	rcu_read_lock();
 	idev = __in6_dev_get(dst->dev);
 	if (idev)
-		mtu = idev->cnf.mtu6;
+		mtu = IN6_DEV_MTU(idev);
 	rcu_read_unlock();
 
 	return mtu;
@@ -368,7 +368,7 @@ int ip6_forward(struct sk_buff *skb)
 	struct net *net = dev_net(dst->dev);
 	u32 mtu;
 
-	if (net->ipv6.devconf_all->forwarding == 0)
+	if (IPV6_DEVCONF_ALL(net, FORWARDING) == 0)
 		goto error;
 
 	if (skb->pkt_type != PACKET_HOST)
@@ -417,8 +417,7 @@ int ip6_forward(struct sk_buff *skb)
 		return -ETIMEDOUT;
 	}
 
-	/* XXX: idev->cnf.proxy_ndp? */
-	if (net->ipv6.devconf_all->proxy_ndp &&
+	if (IN6_DEV_PROXY_NDP(ip6_dst_idev(dst)) &&
 	    pneigh_lookup(&nd_tbl, net, &hdr->daddr, skb->dev, 0)) {
 		int proxied = ip6_forward_proxy_check(skb);
 		if (proxied > 0)
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 8250474..2722e24 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -816,7 +816,7 @@ static int mif6_delete(struct mr6_table *mrt, int vifi, struct list_head *head)
 
 	in6_dev = __in6_dev_get(dev);
 	if (in6_dev) {
-		in6_dev->cnf.mc_forwarding--;
+		IN6_DEV_MFORWARD_DEC(in6_dev);
 		inet6_netconf_notify_devconf(dev_net(dev),
 					     NETCONFA_MC_FORWARDING,
 					     dev->ifindex, &in6_dev->cnf);
@@ -974,7 +974,7 @@ static int mif6_add(struct net *net, struct mr6_table *mrt,
 
 	in6_dev = __in6_dev_get(dev);
 	if (in6_dev) {
-		in6_dev->cnf.mc_forwarding++;
+		IN6_DEV_MFORWARD_INC(in6_dev);
 		inet6_netconf_notify_devconf(dev_net(dev),
 					     NETCONFA_MC_FORWARDING,
 					     dev->ifindex, &in6_dev->cnf);
@@ -1587,7 +1587,7 @@ static int ip6mr_sk_init(struct mr6_table *mrt, struct sock *sk)
 	write_lock_bh(&mrt_lock);
 	if (likely(mrt->mroute6_sk == NULL)) {
 		mrt->mroute6_sk = sk;
-		net->ipv6.devconf_all->mc_forwarding++;
+		IPV6_DEVCONF_ALL(net, MC_FORWARDING)++;
 		inet6_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING,
 					     NETCONFA_IFINDEX_ALL,
 					     net->ipv6.devconf_all);
@@ -1612,7 +1612,7 @@ int ip6mr_sk_done(struct sock *sk)
 		if (sk == mrt->mroute6_sk) {
 			write_lock_bh(&mrt_lock);
 			mrt->mroute6_sk = NULL;
-			net->ipv6.devconf_all->mc_forwarding--;
+			IPV6_DEVCONF_ALL(net, MC_FORWARDING)--;
 			inet6_netconf_notify_devconf(net,
 						     NETCONFA_MC_FORWARDING,
 						     NETCONFA_IFINDEX_ALL,
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index edb58af..d91f501 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -1188,7 +1188,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
 		}
 
 		if (val < 0)
-			val = sock_net(sk)->ipv6.devconf_all->hop_limit;
+			val = IPV6_DEVCONF_ALL(sock_net(sk), HOPLIMIT);
 		break;
 	}
 
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 08b367c..cd49bb5 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -95,7 +95,7 @@ static void mld_ifc_event(struct inet6_dev *idev);
 static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *pmc);
 static void mld_del_delrec(struct inet6_dev *idev, const struct in6_addr *addr);
 static void mld_clear_delrec(struct inet6_dev *idev);
-static bool mld_in_v1_mode(const struct inet6_dev *idev);
+static bool mld_in_v1_mode(struct inet6_dev *idev);
 static int sf_setstate(struct ifmcaddr6 *pmc);
 static void sf_markstate(struct ifmcaddr6 *pmc);
 static void ip6_mc_clear_src(struct ifmcaddr6 *pmc);
@@ -136,9 +136,9 @@ static int unsolicited_report_interval(struct inet6_dev *idev)
 	int iv;
 
 	if (mld_in_v1_mode(idev))
-		iv = idev->cnf.mldv1_unsolicited_report_interval;
+		iv = IN6_DEV_CONF_GET(idev, MLDV1_UNSOLICITED_REPORT_INTERVAL);
 	else
-		iv = idev->cnf.mldv2_unsolicited_report_interval;
+		iv = IN6_DEV_CONF_GET(idev, MLDV2_UNSOLICITED_REPORT_INTERVAL);
 
 	return iv > 0 ? iv : 1;
 }
@@ -1129,30 +1129,17 @@ static bool mld_marksources(struct ifmcaddr6 *pmc, int nsrcs,
 	return true;
 }
 
-static int mld_force_mld_version(const struct inet6_dev *idev)
+static bool mld_in_v2_mode_only(struct inet6_dev *idev)
 {
-	/* Normally, both are 0 here. If enforcement to a particular is
-	 * being used, individual device enforcement will have a lower
-	 * precedence over 'all' device (.../conf/all/force_mld_version).
-	 */
-
-	if (dev_net(idev->dev)->ipv6.devconf_all->force_mld_version != 0)
-		return dev_net(idev->dev)->ipv6.devconf_all->force_mld_version;
-	else
-		return idev->cnf.force_mld_version;
-}
-
-static bool mld_in_v2_mode_only(const struct inet6_dev *idev)
-{
-	return mld_force_mld_version(idev) == 2;
+	return IN6_DEV_FORCE_MLD_VERSION(idev) == 2;
 }
 
-static bool mld_in_v1_mode_only(const struct inet6_dev *idev)
+static bool mld_in_v1_mode_only(struct inet6_dev *idev)
 {
-	return mld_force_mld_version(idev) == 1;
+	return IN6_DEV_FORCE_MLD_VERSION(idev) == 1;
 }
 
-static bool mld_in_v1_mode(const struct inet6_dev *idev)
+static bool mld_in_v1_mode(struct inet6_dev *idev)
 {
 	if (mld_in_v2_mode_only(idev))
 		return false;
@@ -2527,7 +2514,7 @@ void ipv6_mc_destroy_dev(struct inet6_dev *idev)
 	 */
 	__ipv6_dev_mc_dec(idev, &in6addr_linklocal_allnodes);
 
-	if (idev->cnf.forwarding)
+	if (IN6_DEV_FORWARD(idev))
 		__ipv6_dev_mc_dec(idev, &in6addr_linklocal_allrouters);
 
 	write_lock_bh(&idev->lock);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index ca8d4ea..6803f3f 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -483,7 +483,7 @@ void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
 		src_addr = solicited_addr;
 		if (ifp->flags & IFA_F_OPTIMISTIC)
 			override = false;
-		inc_opt |= ifp->idev->cnf.force_tllao;
+		inc_opt |= IN6_DEV_FORCE_TLLAO(ifp->idev);
 		in6_ifa_put(ifp);
 	} else {
 		if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
@@ -533,7 +533,7 @@ static void ndisc_send_unsol_na(struct net_device *dev)
 	read_lock_bh(&idev->lock);
 	list_for_each_entry(ifa, &idev->addr_list, if_list) {
 		ndisc_send_na(dev, NULL, &in6addr_linklocal_allnodes, &ifa->addr,
-			      /*router=*/ !!idev->cnf.forwarding,
+			      /*router=*/ !!IN6_DEV_FORWARD(idev),
 			      /*solicited=*/ false, /*override=*/ true,
 			      /*inc_opt=*/ true);
 	}
@@ -786,8 +786,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
 		}
 
 		if (ipv6_chk_acast_addr(net, dev, &msg->target) ||
-		    (idev->cnf.forwarding &&
-		     (net->ipv6.devconf_all->proxy_ndp || idev->cnf.proxy_ndp) &&
+		    (IN6_DEV_FORWARD(idev) && IN6_DEV_PROXY_NDP(idev) &&
 		     (is_router = pndisc_is_router(&msg->target, dev)) >= 0)) {
 			if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
 			    skb->pkt_type != PACKET_HOST &&
@@ -810,7 +809,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
 	}
 
 	if (is_router < 0)
-		is_router = idev->cnf.forwarding;
+		is_router = IN6_DEV_FORWARD(idev);
 
 	if (dad) {
 		ndisc_send_na(dev, NULL, &in6addr_linklocal_allnodes, &msg->target,
@@ -927,9 +926,9 @@ static void ndisc_recv_na(struct sk_buff *skb)
 		 * has already sent a NA to us.
 		 */
 		if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
-		    net->ipv6.devconf_all->forwarding && net->ipv6.devconf_all->proxy_ndp &&
+		    IN6_DEV_FORWARD(__in6_dev_get(dev)) &&
+		    IN6_DEV_PROXY_NDP(__in6_dev_get(dev)) &&
 		    pneigh_lookup(&nd_tbl, net, &msg->target, dev, 0)) {
-			/* XXX: idev->cnf.proxy_ndp */
 			goto out;
 		}
 
@@ -972,7 +971,7 @@ static void ndisc_recv_rs(struct sk_buff *skb)
 	}
 
 	/* Don't accept RS if we're not in router mode */
-	if (!idev->cnf.forwarding)
+	if (!IN6_DEV_FORWARD(idev))
 		goto out;
 
 	/*
@@ -1130,7 +1129,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 				(ra_msg->icmph.icmp6_addrconf_other ?
 					IF_RA_OTHERCONF : 0);
 
-	if (!in6_dev->cnf.accept_ra_defrtr)
+	if (!IN6_DEV_ACCEPT_RA_DEFRTR(in6_dev))
 		goto skip_defrtr;
 
 	if (ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr, NULL, 0))
@@ -1142,7 +1141,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 	pref = ra_msg->icmph.icmp6_router_pref;
 	/* 10b is handled as if it were 00b (medium) */
 	if (pref == ICMPV6_ROUTER_PREF_INVALID ||
-	    !in6_dev->cnf.accept_ra_rtr_pref)
+	    !IN6_DEV_ACCEPT_RA_RTR_PREF(in6_dev))
 		pref = ICMPV6_ROUTER_PREF_MEDIUM;
 #endif
 
@@ -1190,7 +1189,8 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 	if (rt)
 		rt6_set_expires(rt, jiffies + (HZ * lifetime));
 	if (ra_msg->icmph.icmp6_hop_limit) {
-		in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
+		IN6_DEV_CONF_SET(in6_dev, HOPLIMIT,
+				 ra_msg->icmph.icmp6_hop_limit);
 		if (rt)
 			dst_metric_set(&rt->dst, RTAX_HOPLIMIT,
 				       ra_msg->icmph.icmp6_hop_limit);
@@ -1267,7 +1267,7 @@ skip_linkparms:
 	if (ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr, NULL, 0))
 		goto skip_routeinfo;
 
-	if (in6_dev->cnf.accept_ra_rtr_pref && ndopts.nd_opts_ri) {
+	if (IN6_DEV_ACCEPT_RA_RTR_PREF(in6_dev) && ndopts.nd_opts_ri) {
 		struct nd_opt_hdr *p;
 		for (p = ndopts.nd_opts_ri;
 		     p;
@@ -1279,9 +1279,10 @@ skip_linkparms:
 				continue;
 #endif
 			if (ri->prefix_len == 0 &&
-			    !in6_dev->cnf.accept_ra_defrtr)
+			    !IN6_DEV_ACCEPT_RA_DEFRTR(in6_dev))
 				continue;
-			if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen)
+			if (ri->prefix_len >
+			    IN6_DEV_ACCEPT_RA_RT_INFO_MAX_PLEN(in6_dev))
 				continue;
 			rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3,
 				      &ipv6_hdr(skb)->saddr);
@@ -1297,7 +1298,7 @@ skip_routeinfo:
 		goto out;
 #endif
 
-	if (in6_dev->cnf.accept_ra_pinfo && ndopts.nd_opts_pi) {
+	if (IN6_DEV_ACCEPT_RA_PINFO(in6_dev) && ndopts.nd_opts_pi) {
 		struct nd_opt_hdr *p;
 		for (p = ndopts.nd_opts_pi;
 		     p;
@@ -1317,8 +1318,8 @@ skip_routeinfo:
 
 		if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
 			ND_PRINTK(2, warn, "RA: invalid mtu: %d\n", mtu);
-		} else if (in6_dev->cnf.mtu6 != mtu) {
-			in6_dev->cnf.mtu6 = mtu;
+		} else if (IN6_DEV_CONF_GET(in6_dev, MTU6) != mtu) {
+			IN6_DEV_CONF_SET(in6_dev, MTU6, mtu);
 
 			if (rt)
 				dst_metric_set(&rt->dst, RTAX_MTU, mtu);
@@ -1530,8 +1531,8 @@ static bool ndisc_suppress_frag_ndisc(struct sk_buff *skb)
 	if (!idev)
 		return true;
 	if (IP6CB(skb)->flags & IP6SKB_FRAGMENTED &&
-	    idev->cnf.suppress_frag_ndisc) {
-		net_warn_ratelimited("Received fragmented ndisc packet. Carefully consider disabling suppress_frag_ndisc.\n");
+	    IN6_DEV_SUPPRESS_FRAG_NDISC(idev)) {
+		ND_PRINTK(1, warn, "Received fragmented ndisc packet. Carefully consider disabling suppress_frag_ndisc.\n");
 		return true;
 	}
 	return false;
@@ -1603,7 +1604,7 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event,
 		idev = in6_dev_get(dev);
 		if (!idev)
 			break;
-		if (idev->cnf.ndisc_notify)
+		if (IN6_DEV_NDISC_NOTIFY(idev))
 			ndisc_send_unsol_na(dev);
 		in6_dev_put(idev);
 		break;
diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c
index ffa0293..f86ffd4 100644
--- a/net/ipv6/output_core.c
+++ b/net/ipv6/output_core.c
@@ -60,9 +60,9 @@ int ip6_dst_hoplimit(struct dst_entry *dst)
 		rcu_read_lock();
 		idev = __in6_dev_get(dev);
 		if (idev)
-			hoplimit = idev->cnf.hop_limit;
+			hoplimit = IN6_DEV_HOPLIMIT(idev);
 		else
-			hoplimit = dev_net(dev)->ipv6.devconf_all->hop_limit;
+			hoplimit = IPV6_DEVCONF_ALL(dev_net(dev), HOPLIMIT);
 		rcu_read_unlock();
 	}
 	return hoplimit;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index f23fbd2..0459cf9 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -525,7 +525,8 @@ static void rt6_probe(struct rt6_info *rt)
 	}
 
 	if (!neigh ||
-	    time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) {
+	    time_after(jiffies, neigh->updated +
+				IN6_DEV_RTR_PROBE_INTERVAL(rt->rt6i_idev))) {
 		struct __rt6_probe_work *work;
 
 		work = kmalloc(sizeof(*work), GFP_ATOMIC);
@@ -922,7 +923,7 @@ static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
 	int strict = 0;
 	int attempts = 3;
 	int err;
-	int reachable = net->ipv6.devconf_all->forwarding ? 0 : RT6_LOOKUP_F_REACHABLE;
+	int reachable = IPV6_DEVCONF_ALL(net, FORWARDING) ? 0 : RT6_LOOKUP_F_REACHABLE;
 
 	strict |= flags & RT6_LOOKUP_F_IFACE;
 
@@ -1347,7 +1348,7 @@ static unsigned int ip6_mtu(const struct dst_entry *dst)
 	rcu_read_lock();
 	idev = __in6_dev_get(dst->dev);
 	if (idev)
-		mtu = idev->cnf.mtu6;
+		mtu = IN6_DEV_MTU(idev);
 	rcu_read_unlock();
 
 out:
@@ -1790,7 +1791,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu
 	in6_dev = __in6_dev_get(skb->dev);
 	if (!in6_dev)
 		return;
-	if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects)
+	if (IN6_DEV_FORWARD(in6_dev) || !IN6_DEV_ACCEPT_REDIRECTS(in6_dev))
 		return;
 
 	/* RFC2461 8.1:
@@ -2031,7 +2032,7 @@ restart:
 	read_lock_bh(&table->tb6_lock);
 	for (rt = table->tb6_root.leaf; rt; rt = rt->dst.rt6_next) {
 		if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF) &&
-		    (!rt->rt6i_idev || rt->rt6i_idev->cnf.accept_ra != 2)) {
+		    (!rt->rt6i_idev || IN6_DEV_ACCEPT_RA(rt->rt6i_idev) != 2)) {
 			dst_hold(&rt->dst);
 			read_unlock_bh(&table->tb6_lock);
 			ip6_del_rt(rt);
@@ -2321,7 +2322,7 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg)
 	    !dst_metric_locked(&rt->dst, RTAX_MTU) &&
 	    (dst_mtu(&rt->dst) >= arg->mtu ||
 	     (dst_mtu(&rt->dst) < arg->mtu &&
-	      dst_mtu(&rt->dst) == idev->cnf.mtu6))) {
+	      dst_mtu(&rt->dst) == IN6_DEV_MTU(idev)))) {
 		dst_metric_set(&rt->dst, RTAX_MTU, arg->mtu);
 	}
 	return 0;
-- 
1.9.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [patch net-next 4/5] Documentation: update ipv6 part of networking/ip-sysctl.txt
  2014-06-10 16:19 [patch net-next 0/5] ipv6: change sysctl to behave more like in ipv4 Milos Vyletel
                   ` (2 preceding siblings ...)
  2014-06-10 16:19 ` [patch net-next 3/5] ipv6: consider net.ipv6.conf.all sysctls when making decisions Milos Vyletel
@ 2014-06-10 16:19 ` Milos Vyletel
  2014-06-10 16:19 ` [patch net-next 5/5] ipv6: copy default config values to interfaces Milos Vyletel
  4 siblings, 0 replies; 12+ messages in thread
From: Milos Vyletel @ 2014-06-10 16:19 UTC (permalink / raw)
  To: davem, amwang, netdev
  Cc: Milos Vyletel, Randy Dunlap, Hannes Frederic Sowa, Eric Dumazet,
	Neal Cardwell, Yuchung Cheng, Daniel Borkmann,
	open list:DOCUMENTATION, open list

Documentation was updated with details how net.ipv6.conf.all settings are
used and how they affect current behaviour and interface-specific settings.

Signed-off-by: Milos Vyletel <milos.vyletel@gmail.com>
---
 Documentation/networking/ip-sysctl.txt | 48 ++++++++++++++++++++++++++++++----
 1 file changed, 43 insertions(+), 5 deletions(-)

diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index ab42c95..f0406ff 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1159,13 +1159,51 @@ ip6frag_secret_interval - INTEGER
 	Default: 600
 
 conf/default/*:
-	Change the interface-specific default settings.
+	Change the interface-specific default settings. These settings are
+	applied to all interfaces that have not been up and that did not have
+	this settings set previously. This is usually only during boot before
+	network is set up when sysctl settings are applied.
 
 
 conf/all/*:
-	Change all the interface-specific settings.
-
-	[XXX:  Other special features than forwarding?]
+	Change all the interface-specific settings. Different settings have
+	different effect. There are three different groups based on how they
+	treat conf/all vs interface-specific settings. These groups are
+
+	Both conf/all and interface must enable this feature (andconf)
+		- accept_ra_defrtr
+		- accept_ra_pinfo
+		- accept_ra_rtr_pref
+		- accept_redirects
+		- autoconf
+		- force_tllao
+		- mforward
+		- ndisc_notify
+		- suppress_frag_ndisc
+
+	Either conf/all or interface must enable this feature (orconf)
+		- disable_ipv6
+		- proxy_ndp
+
+	Maximum value of conf/all or interface will be used (maxconf)
+		- accept_dad
+		- accept_ra
+		- accept_ra_rt_info_max_plen
+		- accept_source_route
+		- dad_transmits
+		- hop_limit
+		- max_addresses
+		- max_desync_factor
+		- mtu
+		- optimistic_dad
+		- regen_max_retry
+		- router_probe_interval
+		- router_solicitation_delay
+		- router_solicitation_interval
+		- router_solicitations
+		- temp_prefered_lft
+		- temp_valid_lft
+		- use_tempaddr
 
 conf/all/forwarding - BOOLEAN
 	Enable global IPv6 forwarding between all interfaces.
@@ -1414,7 +1452,7 @@ force_mld_version - INTEGER
 	1 - Enforce to use MLD version 1
 	2 - Enforce to use MLD version 2
 
-suppress_frag_ndisc - INTEGER
+suppress_frag_ndisc - BOOLEAN
 	Control RFC 6980 (Security Implications of IPv6 Fragmentation
 	with IPv6 Neighbor Discovery) behavior:
 	1 - (default) discard fragmented neighbor discovery packets
-- 
1.9.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [patch net-next 5/5] ipv6: copy default config values to interfaces
  2014-06-10 16:19 [patch net-next 0/5] ipv6: change sysctl to behave more like in ipv4 Milos Vyletel
                   ` (3 preceding siblings ...)
  2014-06-10 16:19 ` [patch net-next 4/5] Documentation: update ipv6 part of networking/ip-sysctl.txt Milos Vyletel
@ 2014-06-10 16:19 ` Milos Vyletel
  4 siblings, 0 replies; 12+ messages in thread
From: Milos Vyletel @ 2014-06-10 16:19 UTC (permalink / raw)
  To: davem, amwang, netdev
  Cc: Milos Vyletel, Alexey Kuznetsov, James Morris, Hideaki YOSHIFUJI,
	Patrick McHardy, Hannes Frederic Sowa, Eric Dumazet,
	Florent Fourcot, Paul Durrant, open list

Propagate changes to default sysctl values to all interfaces if they
were not previously configured and interface was not up before. This is
usually only true during boot when we apply /etc/sysctl.conf values
before network is brought up.

Signed-off-by: Milos Vyletel <milos.vyletel@gmail.com>
---
 include/linux/ipv6.h |  2 ++
 include/net/ipv6.h   |  6 ++++++
 net/ipv6/addrconf.c  | 39 +++++++++++++++++++++++++++++++++++++--
 3 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index fe8d38d..e356905 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -1,6 +1,7 @@
 #ifndef _IPV6_H
 #define _IPV6_H
 
+#include <linux/bitmap.h>
 #include <uapi/linux/ipv6.h>
 
 #define ipv6_optlen(p)  (((p)->hdrlen+1) << 3)
@@ -11,6 +12,7 @@
 struct ipv6_devconf {
 	void	*sysctl;
 	__s32	data[IPV6_DEVCONF_MAX];
+	DECLARE_BITMAP(state, IPV6_DEVCONF_MAX);
 };
 
 struct ipv6_params {
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 1ee39a5..eb4e911 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -302,9 +302,15 @@ static inline int ipv6_devconf_get(struct inet6_dev *idev, int index)
 static inline void ipv6_devconf_set(struct inet6_dev *idev, int index,
 				    int val)
 {
+	set_bit(index, idev->cnf.state);
 	idev->cnf.data[index] = val;
 }
 
+static inline void ipv6_devconf_setall(struct inet6_dev *idev)
+{
+	bitmap_fill(idev->cnf.state, IPV6_DEVCONF_MAX);
+}
+
 #define IN6_DEV_CONF_GET(idev, attr) \
 	ipv6_devconf_get((idev), IPV6_DEVCONF_ ## attr)
 #define IN6_DEV_CONF_SET(idev, attr, val) \
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 5b1b578..5218978 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -40,6 +40,7 @@
 
 #define pr_fmt(fmt) "IPv6: " fmt
 
+#include <linux/bitmap.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -852,6 +853,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr,
 		goto out;
 	}
 
+	ipv6_devconf_setall(idev);
 	neigh_parms_data_state_setall(idev->nd_parms);
 
 	ifa->addr = *addr;
@@ -4897,6 +4899,39 @@ int addrconf_sysctl_proxy_ndp(struct ctl_table *ctl, int write,
 	return ret;
 }
 
+static void addrconf_copy_dflt_conf(struct net *net, int i)
+{
+	struct net_device *dev;
+
+	rcu_read_lock();
+	for_each_netdev_rcu(net, dev) {
+		struct inet6_dev *idev = __in6_dev_get(dev);
+
+		if (idev && !test_bit(i, idev->cnf.state))
+			idev->cnf.data[i] = net->ipv6.devconf_dflt->data[i];
+	}
+	rcu_read_unlock();
+}
+
+static int addrconf_sysctl_proc(struct ctl_table *ctl, int write,
+				void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
+
+	if (write) {
+		struct ipv6_devconf *cnf = ctl->extra1;
+		struct net *net = ctl->extra2;
+		int i = (int *)ctl->data - cnf->data;
+
+		set_bit(i, cnf->state);
+
+		if (cnf == net->ipv6.devconf_dflt)
+			addrconf_copy_dflt_conf(net, i);
+	}
+
+	return ret;
+}
+
 #define ADDRCONF_SYSCTL_ENTRY(attr, name, mval, proc) \
 	{ \
 		.procname	= #name, \
@@ -4909,10 +4944,10 @@ int addrconf_sysctl_proxy_ndp(struct ctl_table *ctl, int write,
 	}
 
 #define ADDRCONF_SYSCTL_RW_ENTRY(attr, name) \
-	ADDRCONF_SYSCTL_ENTRY(attr, name, 0644, proc_dointvec)
+	ADDRCONF_SYSCTL_ENTRY(attr, name, 0644, addrconf_sysctl_proc)
 
 #define ADDRCONF_SYSCTL_RO_ENTRY(attr, name) \
-	ADDRCONF_SYSCTL_ENTRY(attr, name, 0444, proc_dointvec)
+	ADDRCONF_SYSCTL_ENTRY(attr, name, 0444, addrconf_sysctl_proc)
 
 #define ADDRCONF_SYSCTL_COMPLEX_ENTRY(attr, name, proc) \
 	ADDRCONF_SYSCTL_ENTRY(attr, name, 0644, proc)
-- 
1.9.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [patch net-next 3/5] ipv6: consider net.ipv6.conf.all sysctls when making decisions
  2014-06-10 16:19 ` [patch net-next 3/5] ipv6: consider net.ipv6.conf.all sysctls when making decisions Milos Vyletel
@ 2014-06-10 17:13   ` Stephen Hemminger
  2014-06-10 17:49     ` Milos Vyletel
  2014-06-10 17:15   ` Florent Fourcot
  1 sibling, 1 reply; 12+ messages in thread
From: Stephen Hemminger @ 2014-06-10 17:13 UTC (permalink / raw)
  To: Milos Vyletel
  Cc: davem, amwang, netdev, Oliver Neukum, Alexey Kuznetsov,
	James Morris, Hideaki YOSHIFUJI, Patrick McHardy,
	Pravin B Shelar, Nicolas Dichtel, Mike Rapoport, Daniel Borkmann,
	Or Gerlitz, Tom Herbert, Hannes Frederic Sowa, Florent Fourcot,
	Eric Dumazet, Paul Durrant, open list:USB CDC ETHERNET...,
	open list

On Tue, 10 Jun 2014 12:19:11 -0400
Milos Vyletel <milos.vyletel@gmail.com> wrote:

> As it is right now net.ipv6.conf.all.* are mostly ignored and instead
> we're only making decisions based on interface specific settings. These
> settings are coppied from net.ipv6.conf.default and changing either all
> or default settings have no effect.

Although this is the right idea conceptually, it risks creating unhappy
users because it changes the semantics of the API. This will probably break
somebody's configuration.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [patch net-next 3/5] ipv6: consider net.ipv6.conf.all sysctls when making decisions
  2014-06-10 16:19 ` [patch net-next 3/5] ipv6: consider net.ipv6.conf.all sysctls when making decisions Milos Vyletel
  2014-06-10 17:13   ` Stephen Hemminger
@ 2014-06-10 17:15   ` Florent Fourcot
  2014-06-10 17:42     ` Milos Vyletel
  1 sibling, 1 reply; 12+ messages in thread
From: Florent Fourcot @ 2014-06-10 17:15 UTC (permalink / raw)
  To: Milos Vyletel, davem, amwang, netdev
  Cc: Oliver Neukum, Alexey Kuznetsov, James Morris, Hideaki YOSHIFUJI,
	Patrick McHardy, stephen hemminger, Pravin B Shelar,
	Nicolas Dichtel, Mike Rapoport, Daniel Borkmann, Or Gerlitz,
	Tom Herbert, Hannes Frederic Sowa, Eric Dumazet, Paul Durrant,
	open list:USB CDC ETHERNET...,
	open list

Hello,

> 
> IN6_DEV_MAXCONF
> 	IN6_DEV_HOPLIMIT
> 	IN6_DEV_MTU

I'm a little bit surprise to set the MTU as the maximum of all/dev
value. Since the default for "all" is IPV6_MIN_MTU, it is probably
harmless, but it could be a little bit surprising for administrators.

>  IN6_DEV_USE_TEMPADDR

For this one, the default is zero, except for point-to-point and
loopback, with -1. I didn't see any difference between 0 and -1 in the
current kernel code, but if I missed something, it could be a little
problem.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [patch net-next 3/5] ipv6: consider net.ipv6.conf.all sysctls when making decisions
  2014-06-10 17:15   ` Florent Fourcot
@ 2014-06-10 17:42     ` Milos Vyletel
  0 siblings, 0 replies; 12+ messages in thread
From: Milos Vyletel @ 2014-06-10 17:42 UTC (permalink / raw)
  To: Florent Fourcot
  Cc: David S. Miller, amwang, netdev, Oliver Neukum, Alexey Kuznetsov,
	James Morris, Hideaki YOSHIFUJI, Patrick McHardy,
	stephen hemminger, Pravin B Shelar, Nicolas Dichtel,
	Mike Rapoport, Daniel Borkmann, Or Gerlitz, Tom Herbert,
	Hannes Frederic Sowa, Eric Dumazet, Paul Durrant,
	open list:USB CDC ETHERNET...,
	open list

> Hello,
>
>>
>> IN6_DEV_MAXCONF
>>       IN6_DEV_HOPLIMIT
>>       IN6_DEV_MTU
>
> I'm a little bit surprise to set the MTU as the maximum of all/dev
> value. Since the default for "all" is IPV6_MIN_MTU, it is probably
> harmless, but it could be a little bit surprising for administrators.
>
>>  IN6_DEV_USE_TEMPADDR
>
> For this one, the default is zero, except for point-to-point and
> loopback, with -1. I didn't see any difference between 0 and -1 in the
> current kernel code, but if I missed something, it could be a little
> problem.

Hi,

these are both valid points. It does not make too much sense to get
max value for MTU and I'd say we should either get min or simply get
interface setting and don't change the current behavior for this particular
one.

use_tempaddr will have special treatment too since it can range from:
use_tempaddr - INTEGER
    Preference for Privacy Extensions (RFC3041).
      <= 0 : disable Privacy Extensions
      == 1 : enable Privacy Extensions, but prefer public
             addresses over temporary addresses.
      >  1 : enable Privacy Extensions and prefer temporary
             addresses over public addresses.
    Default:  0 (for most devices)
         -1 (for point-to-point devices and loopback devices)

Milos

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [patch net-next 3/5] ipv6: consider net.ipv6.conf.all sysctls when making decisions
  2014-06-10 17:13   ` Stephen Hemminger
@ 2014-06-10 17:49     ` Milos Vyletel
  2014-06-11 22:32       ` David Miller
  0 siblings, 1 reply; 12+ messages in thread
From: Milos Vyletel @ 2014-06-10 17:49 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: David S. Miller, amwang, netdev, Oliver Neukum, Alexey Kuznetsov,
	James Morris, Hideaki YOSHIFUJI, Patrick McHardy,
	Pravin B Shelar, Nicolas Dichtel, Mike Rapoport, Daniel Borkmann,
	Or Gerlitz, Tom Herbert, Hannes Frederic Sowa, Florent Fourcot,
	Eric Dumazet, Paul Durrant, open list:USB CDC ETHERNET...,
	open list

On Tue, Jun 10, 2014 at 1:13 PM, Stephen Hemminger
<stephen@networkplumber.org> wrote:
> On Tue, 10 Jun 2014 12:19:11 -0400
> Milos Vyletel <milos.vyletel@gmail.com> wrote:
>
>> As it is right now net.ipv6.conf.all.* are mostly ignored and instead
>> we're only making decisions based on interface specific settings. These
>> settings are coppied from net.ipv6.conf.default and changing either all
>> or default settings have no effect.
>
> Although this is the right idea conceptually, it risks creating unhappy
> users because it changes the semantics of the API. This will probably break
> somebody's configuration.

You're right but in this case I feel we are moving in the right
direction. While the
behavior will change in some cases this change is only adding well known ipv4
behavior for ipv6 sysctls. In fact documentation briefly mentioned that
net.ipv6.conf.all.* should change all the interface-specific settings
but that was
not the case until now.

Milos

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [patch net-next 3/5] ipv6: consider net.ipv6.conf.all sysctls when making decisions
  2014-06-10 17:49     ` Milos Vyletel
@ 2014-06-11 22:32       ` David Miller
  2014-06-12 15:07         ` Milos Vyletel
  0 siblings, 1 reply; 12+ messages in thread
From: David Miller @ 2014-06-11 22:32 UTC (permalink / raw)
  To: milos.vyletel
  Cc: stephen, amwang, netdev, oliver, kuznet, jmorris, yoshfuji,
	kaber, pshelar, nicolas.dichtel, mike.rapoport, dborkman,
	ogerlitz, therbert, hannes, florent.fourcot, edumazet,
	Paul.Durrant, linux-usb, linux-kernel

From: Milos Vyletel <milos.vyletel@gmail.com>
Date: Tue, 10 Jun 2014 13:49:35 -0400

> On Tue, Jun 10, 2014 at 1:13 PM, Stephen Hemminger
> <stephen@networkplumber.org> wrote:
>> On Tue, 10 Jun 2014 12:19:11 -0400
>> Milos Vyletel <milos.vyletel@gmail.com> wrote:
>>
>>> As it is right now net.ipv6.conf.all.* are mostly ignored and instead
>>> we're only making decisions based on interface specific settings. These
>>> settings are coppied from net.ipv6.conf.default and changing either all
>>> or default settings have no effect.
>>
>> Although this is the right idea conceptually, it risks creating unhappy
>> users because it changes the semantics of the API. This will probably break
>> somebody's configuration.
> 
> You're right but in this case I feel we are moving in the right
> direction. While the
> behavior will change in some cases this change is only adding well known ipv4
> behavior for ipv6 sysctls. In fact documentation briefly mentioned that
> net.ipv6.conf.all.* should change all the interface-specific settings
> but that was
> not the case until now.

You can't just break things on people, no matter how much you think the
current behavior is "poorly designed", "inconsistent with other areas of
the networking", etc.  None of those things matter if you have to break
things on people to "fix" it.

I'm not applying this series, sorry.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [patch net-next 3/5] ipv6: consider net.ipv6.conf.all sysctls when making decisions
  2014-06-11 22:32       ` David Miller
@ 2014-06-12 15:07         ` Milos Vyletel
  0 siblings, 0 replies; 12+ messages in thread
From: Milos Vyletel @ 2014-06-12 15:07 UTC (permalink / raw)
  To: David Miller
  Cc: stephen, amwang, netdev, oliver, kuznet, jmorris, yoshfuji,
	kaber, pshelar, nicolas.dichtel, mike.rapoport, dborkman,
	ogerlitz, therbert, hannes, florent.fourcot, edumazet,
	Paul.Durrant, linux-usb, open list:X86 ARCHITECTURE...

David,

my words may have been poorly chosen. Last thing I want is to break things...

What I meant to say is that this changes the behavior of conf.all.*
sysctls from no-op to be part of decision along with interface
specific ones. Default settings still work the same way unless
conf.all.* was manually modified by user (for example setting
conf.all.accept_ra_defrtr=0 did not stop kernel from setting default
router before but it would with this change).

If this is not desired functionality I'm fine with it not being
applied. However if that's the case I suggest removing conf.all.*
altogether since it's no-op and pretty confusing for users (myself
included).

Milos

On Wed, Jun 11, 2014 at 6:32 PM, David Miller <davem@davemloft.net> wrote:
> From: Milos Vyletel <milos.vyletel@gmail.com>
> Date: Tue, 10 Jun 2014 13:49:35 -0400
>
>> On Tue, Jun 10, 2014 at 1:13 PM, Stephen Hemminger
>> <stephen@networkplumber.org> wrote:
>>> On Tue, 10 Jun 2014 12:19:11 -0400
>>> Milos Vyletel <milos.vyletel@gmail.com> wrote:
>>>
>>>> As it is right now net.ipv6.conf.all.* are mostly ignored and instead
>>>> we're only making decisions based on interface specific settings. These
>>>> settings are coppied from net.ipv6.conf.default and changing either all
>>>> or default settings have no effect.
>>>
>>> Although this is the right idea conceptually, it risks creating unhappy
>>> users because it changes the semantics of the API. This will probably break
>>> somebody's configuration.
>>
>> You're right but in this case I feel we are moving in the right
>> direction. While the
>> behavior will change in some cases this change is only adding well known ipv4
>> behavior for ipv6 sysctls. In fact documentation briefly mentioned that
>> net.ipv6.conf.all.* should change all the interface-specific settings
>> but that was
>> not the case until now.
>
> You can't just break things on people, no matter how much you think the
> current behavior is "poorly designed", "inconsistent with other areas of
> the networking", etc.  None of those things matter if you have to break
> things on people to "fix" it.
>
> I'm not applying this series, sorry.

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2014-06-12 15:07 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-10 16:19 [patch net-next 0/5] ipv6: change sysctl to behave more like in ipv4 Milos Vyletel
2014-06-10 16:19 ` [patch net-next 1/5] ipv6: align sysctl table creation code with ipv4 Milos Vyletel
2014-06-10 16:19 ` [patch net-next 2/5] ipv6: rename DEVCONF* to IPV6_DEVCONF* to align " Milos Vyletel
2014-06-10 16:19 ` [patch net-next 3/5] ipv6: consider net.ipv6.conf.all sysctls when making decisions Milos Vyletel
2014-06-10 17:13   ` Stephen Hemminger
2014-06-10 17:49     ` Milos Vyletel
2014-06-11 22:32       ` David Miller
2014-06-12 15:07         ` Milos Vyletel
2014-06-10 17:15   ` Florent Fourcot
2014-06-10 17:42     ` Milos Vyletel
2014-06-10 16:19 ` [patch net-next 4/5] Documentation: update ipv6 part of networking/ip-sysctl.txt Milos Vyletel
2014-06-10 16:19 ` [patch net-next 5/5] ipv6: copy default config values to interfaces Milos Vyletel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.