diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 2d5c18514a2d2d3b3e77e0a0d141d07dafec0c6d..113028fb8f6610c912e57326dbaf6f4bd1c5c649 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -608,6 +608,8 @@ extern struct ctl_table *ipv6_icmp_sysctl_init(struct net *net);
 extern struct ctl_table *ipv6_route_sysctl_init(struct net *net);
 extern int ipv6_sysctl_register(void);
 extern void ipv6_sysctl_unregister(void);
+extern int ipv6_static_sysctl_register(void);
+extern void ipv6_static_sysctl_unregister(void);
 #endif
 
 #endif /* __KERNEL__ */
diff --git a/include/net/route.h b/include/net/route.h
index 3140cc500854064b647245366ee112115dea40e2..4f0d8c14736cba916799c7793848d8d42595483f 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -204,6 +204,4 @@ static inline struct inet_peer *rt_get_peer(struct rtable *rt)
 	return rt->peer;
 }
 
-extern ctl_table ipv4_route_table[];
-
 #endif	/* _ROUTE_H */
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index a507c5e27d0e7d057d0870f9d718903c2d083e4e..380d6474cf661d91fb45ef88699c526b23dabd01 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2914,7 +2914,7 @@ static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table,
 	return 0;
 }
 
-ctl_table ipv4_route_table[] = {
+static ctl_table ipv4_route_table[] = {
 	{
 		.ctl_name	= NET_IPV4_ROUTE_GC_THRESH,
 		.procname	= "gc_thresh",
@@ -3216,6 +3216,15 @@ int __init ip_rt_init(void)
 	return rc;
 }
 
+/*
+ * We really need to sanitize the damn ipv4 init order, then all
+ * this nonsense will go away.
+ */
+void __init ip_static_sysctl_init(void)
+{
+	register_sysctl_paths(ipv4_route_path, ipv4_route_table);
+}
+
 EXPORT_SYMBOL(__ip_select_ident);
 EXPORT_SYMBOL(ip_route_input);
 EXPORT_SYMBOL(ip_route_output_key);
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index d63e9388d92dfff616e432de6d0d4a27f3f6bfdb..770d827f5ab87a75ff6fcaa19a83f3fd7b7f112c 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -401,13 +401,6 @@ static struct ctl_table ipv4_table[] = {
 		.proc_handler	= &ipv4_local_port_range,
 		.strategy	= &ipv4_sysctl_local_port_range,
 	},
-	{
-		.ctl_name	= NET_IPV4_ROUTE,
-		.procname	= "route",
-		.maxlen		= 0,
-		.mode		= 0555,
-		.child		= ipv4_route_table
-	},
 #ifdef CONFIG_IP_MULTICAST
 	{
 		.ctl_name	= NET_IPV4_IGMP_MAX_MEMBERSHIPS,
@@ -882,11 +875,4 @@ static __init int sysctl_ipv4_init(void)
 	return 0;
 }
 
-/* set enough of tree skeleton to get rid of ordering problems */
-void __init ip_static_sysctl_init(void)
-{
-	static ctl_table table[1];
-	register_sysctl_paths(net_ipv4_ctl_path, table);
-}
-
 __initcall(sysctl_ipv4_init);
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index c708ca842298d37590b5d9dd0e6f79bcbe0fb63b..95055f8c3f35eb18d17f4848fe0ae72ed648bbc2 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -934,6 +934,11 @@ static int __init inet6_init(void)
 	if (err)
 		goto out_unregister_sock;
 
+#ifdef CONFIG_SYSCTL
+	err = ipv6_static_sysctl_register();
+	if (err)
+		goto static_sysctl_fail;
+#endif
 	/*
 	 *	ipngwg API draft makes clear that the correct semantics
 	 *	for TCP and UDP is to consider one TCP and UDP instance
@@ -1058,6 +1063,10 @@ ipmr_fail:
 icmp_fail:
 	unregister_pernet_subsys(&inet6_net_ops);
 register_pernet_fail:
+#ifdef CONFIG_SYSCTL
+	ipv6_static_sysctl_unregister();
+static_sysctl_fail:
+#endif
 	cleanup_ipv6_mibs();
 out_unregister_sock:
 	sock_unregister(PF_INET6);
@@ -1113,6 +1122,9 @@ static void __exit inet6_exit(void)
 	rawv6_exit();
 
 	unregister_pernet_subsys(&inet6_net_ops);
+#ifdef CONFIG_SYSCTL
+	ipv6_static_sysctl_unregister();
+#endif
 	cleanup_ipv6_mibs();
 	proto_unregister(&rawv6_prot);
 	proto_unregister(&udplitev6_prot);
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index 5c99274558bf40412b738c4c71484c2a082e7029..e6dfaeac6be3f9a646b832a57938b7b5832da53b 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -150,3 +150,19 @@ void ipv6_sysctl_unregister(void)
 	unregister_net_sysctl_table(ip6_header);
 	unregister_pernet_subsys(&ipv6_sysctl_net_ops);
 }
+
+static struct ctl_table_header *ip6_base;
+
+int ipv6_static_sysctl_register(void)
+{
+	static struct ctl_table empty[1];
+	ip6_base = register_net_sysctl_rotable(net_ipv6_ctl_path, empty);
+	if (ip6_base == NULL)
+		return -ENOMEM;
+	return 0;
+}
+
+void ipv6_static_sysctl_unregister(void)
+{
+	unregister_net_sysctl_table(ip6_base);
+}
diff --git a/net/sysctl_net.c b/net/sysctl_net.c
index cefbc367d8beb0d4f1d3b801d9a364ea29cc49fa..972201cd5fa76791be3d558252d3efb5b009f92e 100644
--- a/net/sysctl_net.c
+++ b/net/sysctl_net.c
@@ -73,7 +73,9 @@ static struct ctl_table_root net_sysctl_ro_root = {
 
 static int sysctl_net_init(struct net *net)
 {
-	setup_sysctl_set(&net->sysctls, NULL, is_seen);
+	setup_sysctl_set(&net->sysctls,
+			 &net_sysctl_ro_root.default_set,
+			 is_seen);
 	return 0;
 }