blob: d7cf26f730d72c64487b1c5858b78019b44202da [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001// SPDX-License-Identifier: GPL-2.0
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
3 * sysctl_net_ipv6.c: sysctl interface to net IPV6 subsystem.
4 *
5 * Changes:
6 * YOSHIFUJI Hideaki @USAGI: added icmp sysctl table.
7 */
8
9#include <linux/mm.h>
10#include <linux/sysctl.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070011#include <linux/in6.h>
12#include <linux/ipv6.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090013#include <linux/slab.h>
Paul Gortmakerbc3b2d72011-07-15 11:47:34 -040014#include <linux/export.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070015#include <net/ndisc.h>
16#include <net/ipv6.h>
17#include <net/addrconf.h>
Pavel Emelyanov04128f22007-10-15 02:33:45 -070018#include <net/inet_frag.h>
David Ahernb4bac172018-03-02 08:32:18 -080019#include <net/netevent.h>
Ido Schimmeled139232021-05-17 21:15:22 +030020#include <net/ip_fib.h>
Huw Davies4fee5242016-06-27 15:06:17 -040021#ifdef CONFIG_NETLABEL
22#include <net/calipso.h>
23#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070024
Ido Schimmel05d44872020-09-02 16:16:59 +030025static int two = 2;
Ido Schimmel73c2c5c2021-05-17 21:15:23 +030026static int three = 3;
Eric Dumazeta346abe2019-07-01 06:39:36 -070027static int flowlabel_reflect_max = 0x7;
Tom Herbert42240902015-07-31 16:52:12 -070028static int auto_flowlabels_max = IP6_AUTO_FLOW_LABEL_MAX;
Ido Schimmeled139232021-05-17 21:15:22 +030029static u32 rt6_multipath_hash_fields_all_mask =
30 FIB_MULTIPATH_HASH_FIELD_ALL_MASK;
Tom Herbert42240902015-07-31 16:52:12 -070031
David Ahernb4bac172018-03-02 08:32:18 -080032static int proc_rt6_multipath_hash_policy(struct ctl_table *table, int write,
Christoph Hellwig32927392020-04-24 08:43:38 +020033 void *buffer, size_t *lenp, loff_t *ppos)
David Ahernb4bac172018-03-02 08:32:18 -080034{
35 struct net *net;
36 int ret;
37
38 net = container_of(table->data, struct net,
39 ipv6.sysctl.multipath_hash_policy);
Eric Dumazeta6175632021-03-31 10:52:12 -070040 ret = proc_dou8vec_minmax(table, write, buffer, lenp, ppos);
David Ahernb4bac172018-03-02 08:32:18 -080041 if (write && ret == 0)
42 call_netevent_notifiers(NETEVENT_IPV6_MPATH_HASH_UPDATE, net);
43
44 return ret;
45}
Hannes Frederic Sowa2f711932014-09-02 15:49:25 +020046
Ido Schimmeleb0e4d592021-05-19 15:08:18 +030047static int
48proc_rt6_multipath_hash_fields(struct ctl_table *table, int write, void *buffer,
49 size_t *lenp, loff_t *ppos)
50{
51 struct net *net;
52 int ret;
53
54 net = container_of(table->data, struct net,
55 ipv6.sysctl.multipath_hash_fields);
56 ret = proc_douintvec_minmax(table, write, buffer, lenp, ppos);
57 if (write && ret == 0)
58 call_netevent_notifiers(NETEVENT_IPV6_MPATH_HASH_UPDATE, net);
59
60 return ret;
61}
62
Joe Perchesfe2c6332013-06-11 23:04:25 -070063static struct ctl_table ipv6_table_template[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070064 {
Linus Torvalds1da177e2005-04-16 15:20:36 -070065 .procname = "bindv6only",
Daniel Lezcano99bc9c42008-01-10 02:54:53 -080066 .data = &init_net.ipv6.sysctl.bindv6only,
Eric Dumazeta6175632021-03-31 10:52:12 -070067 .maxlen = sizeof(u8),
Linus Torvalds1da177e2005-04-16 15:20:36 -070068 .mode = 0644,
Eric Dumazeta6175632021-03-31 10:52:12 -070069 .proc_handler = proc_dou8vec_minmax,
Linus Torvalds1da177e2005-04-16 15:20:36 -070070 },
FX Le Bail509aba32014-01-07 14:57:27 +010071 {
72 .procname = "anycast_src_echo_reply",
FX Le Bailec35b612014-01-13 15:59:01 +010073 .data = &init_net.ipv6.sysctl.anycast_src_echo_reply,
Eric Dumazeta6175632021-03-31 10:52:12 -070074 .maxlen = sizeof(u8),
FX Le Bail509aba32014-01-07 14:57:27 +010075 .mode = 0644,
Eric Dumazeta6175632021-03-31 10:52:12 -070076 .proc_handler = proc_dou8vec_minmax,
FX Le Bail509aba32014-01-07 14:57:27 +010077 },
Florent Fourcot6444f722014-01-17 17:15:05 +010078 {
79 .procname = "flowlabel_consistency",
80 .data = &init_net.ipv6.sysctl.flowlabel_consistency,
Eric Dumazeta6175632021-03-31 10:52:12 -070081 .maxlen = sizeof(u8),
Florent Fourcot6444f722014-01-17 17:15:05 +010082 .mode = 0644,
Eric Dumazeta6175632021-03-31 10:52:12 -070083 .proc_handler = proc_dou8vec_minmax,
Florent Fourcot6444f722014-01-17 17:15:05 +010084 },
Lorenzo Colittie1108612014-05-13 10:17:33 -070085 {
Tom Herbertcb1ce2e2014-07-01 21:33:10 -070086 .procname = "auto_flowlabels",
87 .data = &init_net.ipv6.sysctl.auto_flowlabels,
Eric Dumazeta6175632021-03-31 10:52:12 -070088 .maxlen = sizeof(u8),
Tom Herbertcb1ce2e2014-07-01 21:33:10 -070089 .mode = 0644,
Eric Dumazeta6175632021-03-31 10:52:12 -070090 .proc_handler = proc_dou8vec_minmax,
Tom Herbert42240902015-07-31 16:52:12 -070091 .extra2 = &auto_flowlabels_max
Tom Herbertcb1ce2e2014-07-01 21:33:10 -070092 },
93 {
Lorenzo Colittie1108612014-05-13 10:17:33 -070094 .procname = "fwmark_reflect",
95 .data = &init_net.ipv6.sysctl.fwmark_reflect,
Eric Dumazeta6175632021-03-31 10:52:12 -070096 .maxlen = sizeof(u8),
Lorenzo Colittie1108612014-05-13 10:17:33 -070097 .mode = 0644,
Eric Dumazeta6175632021-03-31 10:52:12 -070098 .proc_handler = proc_dou8vec_minmax,
Lorenzo Colittie1108612014-05-13 10:17:33 -070099 },
Hannes Frederic Sowa1855b7c2015-03-23 23:36:05 +0100100 {
101 .procname = "idgen_retries",
102 .data = &init_net.ipv6.sysctl.idgen_retries,
103 .maxlen = sizeof(int),
104 .mode = 0644,
105 .proc_handler = proc_dointvec,
106 },
107 {
108 .procname = "idgen_delay",
109 .data = &init_net.ipv6.sysctl.idgen_delay,
110 .maxlen = sizeof(int),
111 .mode = 0644,
112 .proc_handler = proc_dointvec_jiffies,
113 },
Tom Herbert82a584b2015-04-29 15:33:21 -0700114 {
115 .procname = "flowlabel_state_ranges",
116 .data = &init_net.ipv6.sysctl.flowlabel_state_ranges,
Eric Dumazeta6175632021-03-31 10:52:12 -0700117 .maxlen = sizeof(u8),
Tom Herbert82a584b2015-04-29 15:33:21 -0700118 .mode = 0644,
Eric Dumazeta6175632021-03-31 10:52:12 -0700119 .proc_handler = proc_dou8vec_minmax,
Tom Herbert82a584b2015-04-29 15:33:21 -0700120 },
Tom Herbert35a256f2015-07-08 16:58:22 -0700121 {
122 .procname = "ip_nonlocal_bind",
123 .data = &init_net.ipv6.sysctl.ip_nonlocal_bind,
Eric Dumazeta6175632021-03-31 10:52:12 -0700124 .maxlen = sizeof(u8),
Tom Herbert35a256f2015-07-08 16:58:22 -0700125 .mode = 0644,
Eric Dumazeta6175632021-03-31 10:52:12 -0700126 .proc_handler = proc_dou8vec_minmax,
Tom Herbert35a256f2015-07-08 16:58:22 -0700127 },
Jakub Sitnicki22b67222017-08-23 09:55:41 +0200128 {
129 .procname = "flowlabel_reflect",
130 .data = &init_net.ipv6.sysctl.flowlabel_reflect,
131 .maxlen = sizeof(int),
132 .mode = 0644,
Eiichi Tsukata00dc3302019-06-28 11:37:14 +0900133 .proc_handler = proc_dointvec_minmax,
Matteo Croceeec48442019-07-18 15:58:50 -0700134 .extra1 = SYSCTL_ZERO,
Eric Dumazeta346abe2019-07-01 06:39:36 -0700135 .extra2 = &flowlabel_reflect_max,
Jakub Sitnicki22b67222017-08-23 09:55:41 +0200136 },
Tom Herbert47d3d7a2017-10-30 14:16:00 -0700137 {
138 .procname = "max_dst_opts_number",
139 .data = &init_net.ipv6.sysctl.max_dst_opts_cnt,
140 .maxlen = sizeof(int),
141 .mode = 0644,
142 .proc_handler = proc_dointvec
143 },
144 {
145 .procname = "max_hbh_opts_number",
146 .data = &init_net.ipv6.sysctl.max_hbh_opts_cnt,
147 .maxlen = sizeof(int),
148 .mode = 0644,
149 .proc_handler = proc_dointvec
150 },
151 {
152 .procname = "max_dst_opts_length",
153 .data = &init_net.ipv6.sysctl.max_dst_opts_len,
154 .maxlen = sizeof(int),
155 .mode = 0644,
156 .proc_handler = proc_dointvec
157 },
158 {
159 .procname = "max_hbh_length",
160 .data = &init_net.ipv6.sysctl.max_hbh_opts_len,
161 .maxlen = sizeof(int),
162 .mode = 0644,
163 .proc_handler = proc_dointvec
164 },
David Ahernb4bac172018-03-02 08:32:18 -0800165 {
166 .procname = "fib_multipath_hash_policy",
167 .data = &init_net.ipv6.sysctl.multipath_hash_policy,
Eric Dumazeta6175632021-03-31 10:52:12 -0700168 .maxlen = sizeof(u8),
David Ahernb4bac172018-03-02 08:32:18 -0800169 .mode = 0644,
170 .proc_handler = proc_rt6_multipath_hash_policy,
Matteo Croceeec48442019-07-18 15:58:50 -0700171 .extra1 = SYSCTL_ZERO,
Ido Schimmel73c2c5c2021-05-17 21:15:23 +0300172 .extra2 = &three,
David Ahernb4bac172018-03-02 08:32:18 -0800173 },
Ahmed Abdelsalamb5facfd2018-04-24 20:23:16 +0200174 {
Ido Schimmeled139232021-05-17 21:15:22 +0300175 .procname = "fib_multipath_hash_fields",
176 .data = &init_net.ipv6.sysctl.multipath_hash_fields,
177 .maxlen = sizeof(u32),
178 .mode = 0644,
Ido Schimmeleb0e4d592021-05-19 15:08:18 +0300179 .proc_handler = proc_rt6_multipath_hash_fields,
Ido Schimmeled139232021-05-17 21:15:22 +0300180 .extra1 = SYSCTL_ONE,
181 .extra2 = &rt6_multipath_hash_fields_all_mask,
182 },
183 {
Ahmed Abdelsalamb5facfd2018-04-24 20:23:16 +0200184 .procname = "seg6_flowlabel",
185 .data = &init_net.ipv6.sysctl.seg6_flowlabel,
186 .maxlen = sizeof(int),
187 .mode = 0644,
188 .proc_handler = proc_dointvec
189 },
Amit Cohen907eea42021-02-01 21:47:55 +0200190 {
191 .procname = "fib_notify_on_flag_change",
192 .data = &init_net.ipv6.sysctl.fib_notify_on_flag_change,
Eric Dumazeta6175632021-03-31 10:52:12 -0700193 .maxlen = sizeof(u8),
Amit Cohen907eea42021-02-01 21:47:55 +0200194 .mode = 0644,
Eric Dumazeta6175632021-03-31 10:52:12 -0700195 .proc_handler = proc_dou8vec_minmax,
Amit Cohen907eea42021-02-01 21:47:55 +0200196 .extra1 = SYSCTL_ZERO,
Amit Cohen6fad3612021-02-07 10:22:53 +0200197 .extra2 = &two,
Amit Cohen907eea42021-02-01 21:47:55 +0200198 },
Eric W. Biedermanf8572d82009-11-05 13:32:03 -0800199 { }
Pavel Emelyanov34ac2572008-05-19 13:53:30 -0700200};
201
Joe Perchesfe2c6332013-06-11 23:04:25 -0700202static struct ctl_table ipv6_rotable[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203 {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204 .procname = "mld_max_msf",
205 .data = &sysctl_mld_max_msf,
206 .maxlen = sizeof(int),
207 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -0800208 .proc_handler = proc_dointvec
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209 },
Hannes Frederic Sowa2f711932014-09-02 15:49:25 +0200210 {
211 .procname = "mld_qrv",
212 .data = &sysctl_mld_qrv,
213 .maxlen = sizeof(int),
214 .mode = 0644,
215 .proc_handler = proc_dointvec_minmax,
Matteo Croceeec48442019-07-18 15:58:50 -0700216 .extra1 = SYSCTL_ONE
Hannes Frederic Sowa2f711932014-09-02 15:49:25 +0200217 },
Huw Davies4fee5242016-06-27 15:06:17 -0400218#ifdef CONFIG_NETLABEL
219 {
220 .procname = "calipso_cache_enable",
221 .data = &calipso_cache_enabled,
222 .maxlen = sizeof(int),
223 .mode = 0644,
224 .proc_handler = proc_dointvec,
225 },
226 {
227 .procname = "calipso_cache_bucket_size",
228 .data = &calipso_cache_bucketsize,
229 .maxlen = sizeof(int),
230 .mode = 0644,
231 .proc_handler = proc_dointvec,
232 },
233#endif /* CONFIG_NETLABEL */
Eric W. Biedermanf8572d82009-11-05 13:32:03 -0800234 { }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235};
236
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +0000237static int __net_init ipv6_sysctl_net_init(struct net *net)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238{
Daniel Lezcano760f2d02008-01-10 02:53:43 -0800239 struct ctl_table *ipv6_table;
240 struct ctl_table *ipv6_route_table;
241 struct ctl_table *ipv6_icmp_table;
Cambda Zhud2f7e562020-03-03 14:54:34 +0800242 int err, i;
Daniel Lezcano760f2d02008-01-10 02:53:43 -0800243
244 err = -ENOMEM;
245 ipv6_table = kmemdup(ipv6_table_template, sizeof(ipv6_table_template),
246 GFP_KERNEL);
247 if (!ipv6_table)
248 goto out;
Cambda Zhud2f7e562020-03-03 14:54:34 +0800249 /* Update the variables to point into the current struct net */
250 for (i = 0; i < ARRAY_SIZE(ipv6_table_template) - 1; i++)
251 ipv6_table[i].data += (void *)net - (void *)&init_net;
Daniel Lezcano760f2d02008-01-10 02:53:43 -0800252
253 ipv6_route_table = ipv6_route_sysctl_init(net);
254 if (!ipv6_route_table)
255 goto out_ipv6_table;
256
257 ipv6_icmp_table = ipv6_icmp_sysctl_init(net);
258 if (!ipv6_icmp_table)
259 goto out_ipv6_route_table;
Daniel Lezcano760f2d02008-01-10 02:53:43 -0800260
Eric W. Biederman6dceb032012-04-19 13:37:09 +0000261 net->ipv6.sysctl.hdr = register_net_sysctl(net, "net/ipv6", ipv6_table);
262 if (!net->ipv6.sysctl.hdr)
Daniel Lezcano760f2d02008-01-10 02:53:43 -0800263 goto out_ipv6_icmp_table;
Daniel Lezcano291480c2008-01-10 02:47:55 -0800264
Eric W. Biederman6dceb032012-04-19 13:37:09 +0000265 net->ipv6.sysctl.route_hdr =
266 register_net_sysctl(net, "net/ipv6/route", ipv6_route_table);
267 if (!net->ipv6.sysctl.route_hdr)
268 goto out_unregister_ipv6_table;
269
270 net->ipv6.sysctl.icmp_hdr =
271 register_net_sysctl(net, "net/ipv6/icmp", ipv6_icmp_table);
272 if (!net->ipv6.sysctl.icmp_hdr)
273 goto out_unregister_route_table;
274
Daniel Lezcano760f2d02008-01-10 02:53:43 -0800275 err = 0;
276out:
277 return err;
Eric W. Biederman6dceb032012-04-19 13:37:09 +0000278out_unregister_route_table:
279 unregister_net_sysctl_table(net->ipv6.sysctl.route_hdr);
280out_unregister_ipv6_table:
281 unregister_net_sysctl_table(net->ipv6.sysctl.hdr);
Daniel Lezcano760f2d02008-01-10 02:53:43 -0800282out_ipv6_icmp_table:
283 kfree(ipv6_icmp_table);
284out_ipv6_route_table:
285 kfree(ipv6_route_table);
286out_ipv6_table:
287 kfree(ipv6_table);
288 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289}
290
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +0000291static void __net_exit ipv6_sysctl_net_exit(struct net *net)
Daniel Lezcano89918fc2008-01-10 02:49:34 -0800292{
Daniel Lezcano760f2d02008-01-10 02:53:43 -0800293 struct ctl_table *ipv6_table;
294 struct ctl_table *ipv6_route_table;
295 struct ctl_table *ipv6_icmp_table;
296
Eric W. Biederman6dceb032012-04-19 13:37:09 +0000297 ipv6_table = net->ipv6.sysctl.hdr->ctl_table_arg;
298 ipv6_route_table = net->ipv6.sysctl.route_hdr->ctl_table_arg;
299 ipv6_icmp_table = net->ipv6.sysctl.icmp_hdr->ctl_table_arg;
Daniel Lezcano760f2d02008-01-10 02:53:43 -0800300
Eric W. Biederman6dceb032012-04-19 13:37:09 +0000301 unregister_net_sysctl_table(net->ipv6.sysctl.icmp_hdr);
302 unregister_net_sysctl_table(net->ipv6.sysctl.route_hdr);
303 unregister_net_sysctl_table(net->ipv6.sysctl.hdr);
Daniel Lezcano760f2d02008-01-10 02:53:43 -0800304
305 kfree(ipv6_table);
306 kfree(ipv6_route_table);
307 kfree(ipv6_icmp_table);
Daniel Lezcano89918fc2008-01-10 02:49:34 -0800308}
309
310static struct pernet_operations ipv6_sysctl_net_ops = {
311 .init = ipv6_sysctl_net_init,
312 .exit = ipv6_sysctl_net_exit,
313};
314
Pavel Emelyanov34ac2572008-05-19 13:53:30 -0700315static struct ctl_table_header *ip6_header;
316
Daniel Lezcano89918fc2008-01-10 02:49:34 -0800317int ipv6_sysctl_register(void)
318{
Fernando Carrijoc19a28e2009-01-07 18:09:08 -0800319 int err = -ENOMEM;
Pavel Emelyanov34ac2572008-05-19 13:53:30 -0700320
Eric W. Biederman43444752012-04-19 13:22:55 +0000321 ip6_header = register_net_sysctl(&init_net, "net/ipv6", ipv6_rotable);
Ian Morris63159f22015-03-29 14:00:04 +0100322 if (!ip6_header)
Pavel Emelyanov34ac2572008-05-19 13:53:30 -0700323 goto out;
324
325 err = register_pernet_subsys(&ipv6_sysctl_net_ops);
326 if (err)
327 goto err_pernet;
328out:
329 return err;
330
331err_pernet:
332 unregister_net_sysctl_table(ip6_header);
333 goto out;
Daniel Lezcano89918fc2008-01-10 02:49:34 -0800334}
335
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336void ipv6_sysctl_unregister(void)
337{
Pavel Emelyanov34ac2572008-05-19 13:53:30 -0700338 unregister_net_sysctl_table(ip6_header);
Daniel Lezcano89918fc2008-01-10 02:49:34 -0800339 unregister_pernet_subsys(&ipv6_sysctl_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340}