| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * sysctl_net_ipv6.c: sysctl interface to net IPV6 subsystem. | 
 | 3 |  * | 
 | 4 |  * Changes: | 
 | 5 |  * YOSHIFUJI Hideaki @USAGI:	added icmp sysctl table. | 
 | 6 |  */ | 
 | 7 |  | 
 | 8 | #include <linux/mm.h> | 
 | 9 | #include <linux/sysctl.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 10 | #include <linux/in6.h> | 
 | 11 | #include <linux/ipv6.h> | 
| Tejun Heo | 5a0e3ad | 2010-03-24 17:04:11 +0900 | [diff] [blame] | 12 | #include <linux/slab.h> | 
| Paul Gortmaker | bc3b2d7 | 2011-07-15 11:47:34 -0400 | [diff] [blame] | 13 | #include <linux/export.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 14 | #include <net/ndisc.h> | 
 | 15 | #include <net/ipv6.h> | 
 | 16 | #include <net/addrconf.h> | 
| Pavel Emelyanov | 04128f2 | 2007-10-15 02:33:45 -0700 | [diff] [blame] | 17 | #include <net/inet_frag.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 18 |  | 
| Hannes Frederic Sowa | 2f71193 | 2014-09-02 15:49:25 +0200 | [diff] [blame] | 19 | static int one = 1; | 
 | 20 |  | 
| Joe Perches | fe2c633 | 2013-06-11 23:04:25 -0700 | [diff] [blame] | 21 | static struct ctl_table ipv6_table_template[] = { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 22 | 	{ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 23 | 		.procname	= "bindv6only", | 
| Daniel Lezcano | 99bc9c4 | 2008-01-10 02:54:53 -0800 | [diff] [blame] | 24 | 		.data		= &init_net.ipv6.sysctl.bindv6only, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 25 | 		.maxlen		= sizeof(int), | 
 | 26 | 		.mode		= 0644, | 
| Alexey Dobriyan | 6d9f239 | 2008-11-03 18:21:05 -0800 | [diff] [blame] | 27 | 		.proc_handler	= proc_dointvec | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 28 | 	}, | 
| FX Le Bail | 509aba3 | 2014-01-07 14:57:27 +0100 | [diff] [blame] | 29 | 	{ | 
 | 30 | 		.procname	= "anycast_src_echo_reply", | 
| FX Le Bail | ec35b61 | 2014-01-13 15:59:01 +0100 | [diff] [blame] | 31 | 		.data		= &init_net.ipv6.sysctl.anycast_src_echo_reply, | 
| FX Le Bail | 509aba3 | 2014-01-07 14:57:27 +0100 | [diff] [blame] | 32 | 		.maxlen		= sizeof(int), | 
 | 33 | 		.mode		= 0644, | 
 | 34 | 		.proc_handler	= proc_dointvec | 
 | 35 | 	}, | 
| Florent Fourcot | 6444f72 | 2014-01-17 17:15:05 +0100 | [diff] [blame] | 36 | 	{ | 
 | 37 | 		.procname	= "flowlabel_consistency", | 
 | 38 | 		.data		= &init_net.ipv6.sysctl.flowlabel_consistency, | 
 | 39 | 		.maxlen		= sizeof(int), | 
 | 40 | 		.mode		= 0644, | 
 | 41 | 		.proc_handler	= proc_dointvec | 
 | 42 | 	}, | 
| Lorenzo Colitti | e110861 | 2014-05-13 10:17:33 -0700 | [diff] [blame] | 43 | 	{ | 
| Tom Herbert | cb1ce2e | 2014-07-01 21:33:10 -0700 | [diff] [blame] | 44 | 		.procname	= "auto_flowlabels", | 
 | 45 | 		.data		= &init_net.ipv6.sysctl.auto_flowlabels, | 
 | 46 | 		.maxlen		= sizeof(int), | 
 | 47 | 		.mode		= 0644, | 
 | 48 | 		.proc_handler	= proc_dointvec | 
 | 49 | 	}, | 
 | 50 | 	{ | 
| Lorenzo Colitti | e110861 | 2014-05-13 10:17:33 -0700 | [diff] [blame] | 51 | 		.procname	= "fwmark_reflect", | 
 | 52 | 		.data		= &init_net.ipv6.sysctl.fwmark_reflect, | 
 | 53 | 		.maxlen		= sizeof(int), | 
 | 54 | 		.mode		= 0644, | 
 | 55 | 		.proc_handler	= proc_dointvec | 
 | 56 | 	}, | 
| Hannes Frederic Sowa | 1855b7c | 2015-03-23 23:36:05 +0100 | [diff] [blame] | 57 | 	{ | 
 | 58 | 		.procname	= "idgen_retries", | 
 | 59 | 		.data		= &init_net.ipv6.sysctl.idgen_retries, | 
 | 60 | 		.maxlen		= sizeof(int), | 
 | 61 | 		.mode		= 0644, | 
 | 62 | 		.proc_handler	= proc_dointvec, | 
 | 63 | 	}, | 
 | 64 | 	{ | 
 | 65 | 		.procname	= "idgen_delay", | 
 | 66 | 		.data		= &init_net.ipv6.sysctl.idgen_delay, | 
 | 67 | 		.maxlen		= sizeof(int), | 
 | 68 | 		.mode		= 0644, | 
 | 69 | 		.proc_handler	= proc_dointvec_jiffies, | 
 | 70 | 	}, | 
| Eric W. Biederman | f8572d8 | 2009-11-05 13:32:03 -0800 | [diff] [blame] | 71 | 	{ } | 
| Pavel Emelyanov | 34ac257 | 2008-05-19 13:53:30 -0700 | [diff] [blame] | 72 | }; | 
 | 73 |  | 
| Joe Perches | fe2c633 | 2013-06-11 23:04:25 -0700 | [diff] [blame] | 74 | static struct ctl_table ipv6_rotable[] = { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 75 | 	{ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 76 | 		.procname	= "mld_max_msf", | 
 | 77 | 		.data		= &sysctl_mld_max_msf, | 
 | 78 | 		.maxlen		= sizeof(int), | 
 | 79 | 		.mode		= 0644, | 
| Alexey Dobriyan | 6d9f239 | 2008-11-03 18:21:05 -0800 | [diff] [blame] | 80 | 		.proc_handler	= proc_dointvec | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 81 | 	}, | 
| Hannes Frederic Sowa | 2f71193 | 2014-09-02 15:49:25 +0200 | [diff] [blame] | 82 | 	{ | 
 | 83 | 		.procname	= "mld_qrv", | 
 | 84 | 		.data		= &sysctl_mld_qrv, | 
 | 85 | 		.maxlen		= sizeof(int), | 
 | 86 | 		.mode		= 0644, | 
 | 87 | 		.proc_handler	= proc_dointvec_minmax, | 
 | 88 | 		.extra1		= &one | 
 | 89 | 	}, | 
| Eric W. Biederman | f8572d8 | 2009-11-05 13:32:03 -0800 | [diff] [blame] | 90 | 	{ } | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 91 | }; | 
 | 92 |  | 
| Alexey Dobriyan | 2c8c1e7 | 2010-01-17 03:35:32 +0000 | [diff] [blame] | 93 | static int __net_init ipv6_sysctl_net_init(struct net *net) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 94 | { | 
| Daniel Lezcano | 760f2d0 | 2008-01-10 02:53:43 -0800 | [diff] [blame] | 95 | 	struct ctl_table *ipv6_table; | 
 | 96 | 	struct ctl_table *ipv6_route_table; | 
 | 97 | 	struct ctl_table *ipv6_icmp_table; | 
 | 98 | 	int err; | 
 | 99 |  | 
 | 100 | 	err = -ENOMEM; | 
 | 101 | 	ipv6_table = kmemdup(ipv6_table_template, sizeof(ipv6_table_template), | 
 | 102 | 			     GFP_KERNEL); | 
 | 103 | 	if (!ipv6_table) | 
 | 104 | 		goto out; | 
| Eric W. Biederman | 6dceb03 | 2012-04-19 13:37:09 +0000 | [diff] [blame] | 105 | 	ipv6_table[0].data = &net->ipv6.sysctl.bindv6only; | 
| FX Le Bail | ec35b61 | 2014-01-13 15:59:01 +0100 | [diff] [blame] | 106 | 	ipv6_table[1].data = &net->ipv6.sysctl.anycast_src_echo_reply; | 
| Florent Fourcot | 6444f72 | 2014-01-17 17:15:05 +0100 | [diff] [blame] | 107 | 	ipv6_table[2].data = &net->ipv6.sysctl.flowlabel_consistency; | 
| Tom Herbert | cb1ce2e | 2014-07-01 21:33:10 -0700 | [diff] [blame] | 108 | 	ipv6_table[3].data = &net->ipv6.sysctl.auto_flowlabels; | 
| David S. Miller | d247b6a | 2014-08-05 18:46:26 -0700 | [diff] [blame] | 109 | 	ipv6_table[4].data = &net->ipv6.sysctl.fwmark_reflect; | 
| Hannes Frederic Sowa | 1855b7c | 2015-03-23 23:36:05 +0100 | [diff] [blame] | 110 | 	ipv6_table[5].data = &net->ipv6.sysctl.idgen_retries; | 
 | 111 | 	ipv6_table[6].data = &net->ipv6.sysctl.idgen_delay; | 
| Daniel Lezcano | 760f2d0 | 2008-01-10 02:53:43 -0800 | [diff] [blame] | 112 |  | 
 | 113 | 	ipv6_route_table = ipv6_route_sysctl_init(net); | 
 | 114 | 	if (!ipv6_route_table) | 
 | 115 | 		goto out_ipv6_table; | 
 | 116 |  | 
 | 117 | 	ipv6_icmp_table = ipv6_icmp_sysctl_init(net); | 
 | 118 | 	if (!ipv6_icmp_table) | 
 | 119 | 		goto out_ipv6_route_table; | 
| Daniel Lezcano | 760f2d0 | 2008-01-10 02:53:43 -0800 | [diff] [blame] | 120 |  | 
| Eric W. Biederman | 6dceb03 | 2012-04-19 13:37:09 +0000 | [diff] [blame] | 121 | 	net->ipv6.sysctl.hdr = register_net_sysctl(net, "net/ipv6", ipv6_table); | 
 | 122 | 	if (!net->ipv6.sysctl.hdr) | 
| Daniel Lezcano | 760f2d0 | 2008-01-10 02:53:43 -0800 | [diff] [blame] | 123 | 		goto out_ipv6_icmp_table; | 
| Daniel Lezcano | 291480c | 2008-01-10 02:47:55 -0800 | [diff] [blame] | 124 |  | 
| Eric W. Biederman | 6dceb03 | 2012-04-19 13:37:09 +0000 | [diff] [blame] | 125 | 	net->ipv6.sysctl.route_hdr = | 
 | 126 | 		register_net_sysctl(net, "net/ipv6/route", ipv6_route_table); | 
 | 127 | 	if (!net->ipv6.sysctl.route_hdr) | 
 | 128 | 		goto out_unregister_ipv6_table; | 
 | 129 |  | 
 | 130 | 	net->ipv6.sysctl.icmp_hdr = | 
 | 131 | 		register_net_sysctl(net, "net/ipv6/icmp", ipv6_icmp_table); | 
 | 132 | 	if (!net->ipv6.sysctl.icmp_hdr) | 
 | 133 | 		goto out_unregister_route_table; | 
 | 134 |  | 
| Daniel Lezcano | 760f2d0 | 2008-01-10 02:53:43 -0800 | [diff] [blame] | 135 | 	err = 0; | 
 | 136 | out: | 
 | 137 | 	return err; | 
| Eric W. Biederman | 6dceb03 | 2012-04-19 13:37:09 +0000 | [diff] [blame] | 138 | out_unregister_route_table: | 
 | 139 | 	unregister_net_sysctl_table(net->ipv6.sysctl.route_hdr); | 
 | 140 | out_unregister_ipv6_table: | 
 | 141 | 	unregister_net_sysctl_table(net->ipv6.sysctl.hdr); | 
| Daniel Lezcano | 760f2d0 | 2008-01-10 02:53:43 -0800 | [diff] [blame] | 142 | out_ipv6_icmp_table: | 
 | 143 | 	kfree(ipv6_icmp_table); | 
 | 144 | out_ipv6_route_table: | 
 | 145 | 	kfree(ipv6_route_table); | 
 | 146 | out_ipv6_table: | 
 | 147 | 	kfree(ipv6_table); | 
 | 148 | 	goto out; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 149 | } | 
 | 150 |  | 
| Alexey Dobriyan | 2c8c1e7 | 2010-01-17 03:35:32 +0000 | [diff] [blame] | 151 | static void __net_exit ipv6_sysctl_net_exit(struct net *net) | 
| Daniel Lezcano | 89918fc | 2008-01-10 02:49:34 -0800 | [diff] [blame] | 152 | { | 
| Daniel Lezcano | 760f2d0 | 2008-01-10 02:53:43 -0800 | [diff] [blame] | 153 | 	struct ctl_table *ipv6_table; | 
 | 154 | 	struct ctl_table *ipv6_route_table; | 
 | 155 | 	struct ctl_table *ipv6_icmp_table; | 
 | 156 |  | 
| Eric W. Biederman | 6dceb03 | 2012-04-19 13:37:09 +0000 | [diff] [blame] | 157 | 	ipv6_table = net->ipv6.sysctl.hdr->ctl_table_arg; | 
 | 158 | 	ipv6_route_table = net->ipv6.sysctl.route_hdr->ctl_table_arg; | 
 | 159 | 	ipv6_icmp_table = net->ipv6.sysctl.icmp_hdr->ctl_table_arg; | 
| Daniel Lezcano | 760f2d0 | 2008-01-10 02:53:43 -0800 | [diff] [blame] | 160 |  | 
| Eric W. Biederman | 6dceb03 | 2012-04-19 13:37:09 +0000 | [diff] [blame] | 161 | 	unregister_net_sysctl_table(net->ipv6.sysctl.icmp_hdr); | 
 | 162 | 	unregister_net_sysctl_table(net->ipv6.sysctl.route_hdr); | 
 | 163 | 	unregister_net_sysctl_table(net->ipv6.sysctl.hdr); | 
| Daniel Lezcano | 760f2d0 | 2008-01-10 02:53:43 -0800 | [diff] [blame] | 164 |  | 
 | 165 | 	kfree(ipv6_table); | 
 | 166 | 	kfree(ipv6_route_table); | 
 | 167 | 	kfree(ipv6_icmp_table); | 
| Daniel Lezcano | 89918fc | 2008-01-10 02:49:34 -0800 | [diff] [blame] | 168 | } | 
 | 169 |  | 
 | 170 | static struct pernet_operations ipv6_sysctl_net_ops = { | 
 | 171 | 	.init = ipv6_sysctl_net_init, | 
 | 172 | 	.exit = ipv6_sysctl_net_exit, | 
 | 173 | }; | 
 | 174 |  | 
| Pavel Emelyanov | 34ac257 | 2008-05-19 13:53:30 -0700 | [diff] [blame] | 175 | static struct ctl_table_header *ip6_header; | 
 | 176 |  | 
| Daniel Lezcano | 89918fc | 2008-01-10 02:49:34 -0800 | [diff] [blame] | 177 | int ipv6_sysctl_register(void) | 
 | 178 | { | 
| Fernando Carrijo | c19a28e | 2009-01-07 18:09:08 -0800 | [diff] [blame] | 179 | 	int err = -ENOMEM; | 
| Pavel Emelyanov | 34ac257 | 2008-05-19 13:53:30 -0700 | [diff] [blame] | 180 |  | 
| Eric W. Biederman | 4344475 | 2012-04-19 13:22:55 +0000 | [diff] [blame] | 181 | 	ip6_header = register_net_sysctl(&init_net, "net/ipv6", ipv6_rotable); | 
| Ian Morris | 63159f2 | 2015-03-29 14:00:04 +0100 | [diff] [blame] | 182 | 	if (!ip6_header) | 
| Pavel Emelyanov | 34ac257 | 2008-05-19 13:53:30 -0700 | [diff] [blame] | 183 | 		goto out; | 
 | 184 |  | 
 | 185 | 	err = register_pernet_subsys(&ipv6_sysctl_net_ops); | 
 | 186 | 	if (err) | 
 | 187 | 		goto err_pernet; | 
 | 188 | out: | 
 | 189 | 	return err; | 
 | 190 |  | 
 | 191 | err_pernet: | 
 | 192 | 	unregister_net_sysctl_table(ip6_header); | 
 | 193 | 	goto out; | 
| Daniel Lezcano | 89918fc | 2008-01-10 02:49:34 -0800 | [diff] [blame] | 194 | } | 
 | 195 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 196 | void ipv6_sysctl_unregister(void) | 
 | 197 | { | 
| Pavel Emelyanov | 34ac257 | 2008-05-19 13:53:30 -0700 | [diff] [blame] | 198 | 	unregister_net_sysctl_table(ip6_header); | 
| Daniel Lezcano | 89918fc | 2008-01-10 02:49:34 -0800 | [diff] [blame] | 199 | 	unregister_pernet_subsys(&ipv6_sysctl_net_ops); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 200 | } |