1// SPDX-License-Identifier: GPL-2.0-or-later
2/* SCTP kernel implementation
3 * (C) Copyright IBM Corp. 2002, 2004
4 * Copyright (c) 2002 Intel Corp.
5 *
6 * This file is part of the SCTP kernel implementation
7 *
8 * Sysctl related interfaces for SCTP.
9 *
10 * Please send any bug reports or fixes you make to the
11 * email address(es):
12 *    lksctp developers <linux-sctp@vger.kernel.org>
13 *
14 * Written or modified by:
15 *    Mingqin Liu           <liuming@us.ibm.com>
16 *    Jon Grimm             <jgrimm@us.ibm.com>
17 *    Ardelle Fan           <ardelle.fan@intel.com>
18 *    Ryan Layer            <rmlayer@us.ibm.com>
19 *    Sridhar Samudrala     <sri@us.ibm.com>
20 */
21
22#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23
24#include <net/sctp/structs.h>
25#include <net/sctp/sctp.h>
26#include <linux/sysctl.h>
27
28static int timer_max = 86400000; /* ms in one day */
29static int sack_timer_min = 1;
30static int sack_timer_max = 500;
31static int addr_scope_max = SCTP_SCOPE_POLICY_MAX;
32static int rwnd_scale_max = 16;
33static int rto_alpha_min = 0;
34static int rto_beta_min = 0;
35static int rto_alpha_max = 1000;
36static int rto_beta_max = 1000;
37static int pf_expose_max = SCTP_PF_EXPOSE_MAX;
38static int ps_retrans_max = SCTP_PS_RETRANS_MAX;
39static int udp_port_max = 65535;
40
41static unsigned long max_autoclose_min = 0;
42static unsigned long max_autoclose_max =
43	(MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX)
44	? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ;
45
46static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
47				 void *buffer, size_t *lenp, loff_t *ppos);
48static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
49				void *buffer, size_t *lenp, loff_t *ppos);
50static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, void *buffer,
51				size_t *lenp, loff_t *ppos);
52static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write, void *buffer,
53				 size_t *lenp, loff_t *ppos);
54static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
55				   void *buffer, size_t *lenp, loff_t *ppos);
56static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
57			     void *buffer, size_t *lenp, loff_t *ppos);
58static int proc_sctp_do_probe_interval(struct ctl_table *ctl, int write,
59				       void *buffer, size_t *lenp, loff_t *ppos);
60
61static struct ctl_table sctp_table[] = {
62	{
63		.procname	= "sctp_mem",
64		.data		= &sysctl_sctp_mem,
65		.maxlen		= sizeof(sysctl_sctp_mem),
66		.mode		= 0644,
67		.proc_handler	= proc_doulongvec_minmax
68	},
69	{
70		.procname	= "sctp_rmem",
71		.data		= &sysctl_sctp_rmem,
72		.maxlen		= sizeof(sysctl_sctp_rmem),
73		.mode		= 0644,
74		.proc_handler	= proc_dointvec,
75	},
76	{
77		.procname	= "sctp_wmem",
78		.data		= &sysctl_sctp_wmem,
79		.maxlen		= sizeof(sysctl_sctp_wmem),
80		.mode		= 0644,
81		.proc_handler	= proc_dointvec,
82	},
83
84	{ /* sentinel */ }
85};
86
87/* The following index defines are used in sctp_sysctl_net_register().
88 * If you add new items to the sctp_net_table, please ensure that
89 * the index values of these defines hold the same meaning indicated by
90 * their macro names when they appear in sctp_net_table.
91 */
92#define SCTP_RTO_MIN_IDX       0
93#define SCTP_RTO_MAX_IDX       1
94#define SCTP_PF_RETRANS_IDX    2
95#define SCTP_PS_RETRANS_IDX    3
96
97static struct ctl_table sctp_net_table[] = {
98	[SCTP_RTO_MIN_IDX] = {
99		.procname	= "rto_min",
100		.data		= &init_net.sctp.rto_min,
101		.maxlen		= sizeof(unsigned int),
102		.mode		= 0644,
103		.proc_handler	= proc_sctp_do_rto_min,
104		.extra1         = SYSCTL_ONE,
105		.extra2         = &init_net.sctp.rto_max
106	},
107	[SCTP_RTO_MAX_IDX] =  {
108		.procname	= "rto_max",
109		.data		= &init_net.sctp.rto_max,
110		.maxlen		= sizeof(unsigned int),
111		.mode		= 0644,
112		.proc_handler	= proc_sctp_do_rto_max,
113		.extra1         = &init_net.sctp.rto_min,
114		.extra2         = &timer_max
115	},
116	[SCTP_PF_RETRANS_IDX] = {
117		.procname	= "pf_retrans",
118		.data		= &init_net.sctp.pf_retrans,
119		.maxlen		= sizeof(int),
120		.mode		= 0644,
121		.proc_handler	= proc_dointvec_minmax,
122		.extra1		= SYSCTL_ZERO,
123		.extra2		= &init_net.sctp.ps_retrans,
124	},
125	[SCTP_PS_RETRANS_IDX] = {
126		.procname	= "ps_retrans",
127		.data		= &init_net.sctp.ps_retrans,
128		.maxlen		= sizeof(int),
129		.mode		= 0644,
130		.proc_handler	= proc_dointvec_minmax,
131		.extra1		= &init_net.sctp.pf_retrans,
132		.extra2		= &ps_retrans_max,
133	},
134	{
135		.procname	= "rto_initial",
136		.data		= &init_net.sctp.rto_initial,
137		.maxlen		= sizeof(unsigned int),
138		.mode		= 0644,
139		.proc_handler	= proc_dointvec_minmax,
140		.extra1         = SYSCTL_ONE,
141		.extra2         = &timer_max
142	},
143	{
144		.procname	= "rto_alpha_exp_divisor",
145		.data		= &init_net.sctp.rto_alpha,
146		.maxlen		= sizeof(int),
147		.mode		= 0644,
148		.proc_handler	= proc_sctp_do_alpha_beta,
149		.extra1		= &rto_alpha_min,
150		.extra2		= &rto_alpha_max,
151	},
152	{
153		.procname	= "rto_beta_exp_divisor",
154		.data		= &init_net.sctp.rto_beta,
155		.maxlen		= sizeof(int),
156		.mode		= 0644,
157		.proc_handler	= proc_sctp_do_alpha_beta,
158		.extra1		= &rto_beta_min,
159		.extra2		= &rto_beta_max,
160	},
161	{
162		.procname	= "max_burst",
163		.data		= &init_net.sctp.max_burst,
164		.maxlen		= sizeof(int),
165		.mode		= 0644,
166		.proc_handler	= proc_dointvec_minmax,
167		.extra1		= SYSCTL_ZERO,
168		.extra2		= SYSCTL_INT_MAX,
169	},
170	{
171		.procname	= "cookie_preserve_enable",
172		.data		= &init_net.sctp.cookie_preserve_enable,
173		.maxlen		= sizeof(int),
174		.mode		= 0644,
175		.proc_handler	= proc_dointvec,
176	},
177	{
178		.procname	= "cookie_hmac_alg",
179		.data		= &init_net.sctp.sctp_hmac_alg,
180		.maxlen		= 8,
181		.mode		= 0644,
182		.proc_handler	= proc_sctp_do_hmac_alg,
183	},
184	{
185		.procname	= "valid_cookie_life",
186		.data		= &init_net.sctp.valid_cookie_life,
187		.maxlen		= sizeof(unsigned int),
188		.mode		= 0644,
189		.proc_handler	= proc_dointvec_minmax,
190		.extra1         = SYSCTL_ONE,
191		.extra2         = &timer_max
192	},
193	{
194		.procname	= "sack_timeout",
195		.data		= &init_net.sctp.sack_timeout,
196		.maxlen		= sizeof(int),
197		.mode		= 0644,
198		.proc_handler	= proc_dointvec_minmax,
199		.extra1         = &sack_timer_min,
200		.extra2         = &sack_timer_max,
201	},
202	{
203		.procname	= "hb_interval",
204		.data		= &init_net.sctp.hb_interval,
205		.maxlen		= sizeof(unsigned int),
206		.mode		= 0644,
207		.proc_handler	= proc_dointvec_minmax,
208		.extra1         = SYSCTL_ONE,
209		.extra2         = &timer_max
210	},
211	{
212		.procname	= "association_max_retrans",
213		.data		= &init_net.sctp.max_retrans_association,
214		.maxlen		= sizeof(int),
215		.mode		= 0644,
216		.proc_handler	= proc_dointvec_minmax,
217		.extra1		= SYSCTL_ONE,
218		.extra2		= SYSCTL_INT_MAX,
219	},
220	{
221		.procname	= "path_max_retrans",
222		.data		= &init_net.sctp.max_retrans_path,
223		.maxlen		= sizeof(int),
224		.mode		= 0644,
225		.proc_handler	= proc_dointvec_minmax,
226		.extra1		= SYSCTL_ONE,
227		.extra2		= SYSCTL_INT_MAX,
228	},
229	{
230		.procname	= "max_init_retransmits",
231		.data		= &init_net.sctp.max_retrans_init,
232		.maxlen		= sizeof(int),
233		.mode		= 0644,
234		.proc_handler	= proc_dointvec_minmax,
235		.extra1		= SYSCTL_ONE,
236		.extra2		= SYSCTL_INT_MAX,
237	},
238	{
239		.procname	= "sndbuf_policy",
240		.data		= &init_net.sctp.sndbuf_policy,
241		.maxlen		= sizeof(int),
242		.mode		= 0644,
243		.proc_handler	= proc_dointvec,
244	},
245	{
246		.procname	= "rcvbuf_policy",
247		.data		= &init_net.sctp.rcvbuf_policy,
248		.maxlen		= sizeof(int),
249		.mode		= 0644,
250		.proc_handler	= proc_dointvec,
251	},
252	{
253		.procname	= "default_auto_asconf",
254		.data		= &init_net.sctp.default_auto_asconf,
255		.maxlen		= sizeof(int),
256		.mode		= 0644,
257		.proc_handler	= proc_dointvec,
258	},
259	{
260		.procname	= "addip_enable",
261		.data		= &init_net.sctp.addip_enable,
262		.maxlen		= sizeof(int),
263		.mode		= 0644,
264		.proc_handler	= proc_dointvec,
265	},
266	{
267		.procname	= "addip_noauth_enable",
268		.data		= &init_net.sctp.addip_noauth,
269		.maxlen		= sizeof(int),
270		.mode		= 0644,
271		.proc_handler	= proc_dointvec,
272	},
273	{
274		.procname	= "prsctp_enable",
275		.data		= &init_net.sctp.prsctp_enable,
276		.maxlen		= sizeof(int),
277		.mode		= 0644,
278		.proc_handler	= proc_dointvec,
279	},
280	{
281		.procname	= "reconf_enable",
282		.data		= &init_net.sctp.reconf_enable,
283		.maxlen		= sizeof(int),
284		.mode		= 0644,
285		.proc_handler	= proc_dointvec,
286	},
287	{
288		.procname	= "auth_enable",
289		.data		= &init_net.sctp.auth_enable,
290		.maxlen		= sizeof(int),
291		.mode		= 0644,
292		.proc_handler	= proc_sctp_do_auth,
293	},
294	{
295		.procname	= "intl_enable",
296		.data		= &init_net.sctp.intl_enable,
297		.maxlen		= sizeof(int),
298		.mode		= 0644,
299		.proc_handler	= proc_dointvec,
300	},
301	{
302		.procname	= "ecn_enable",
303		.data		= &init_net.sctp.ecn_enable,
304		.maxlen		= sizeof(int),
305		.mode		= 0644,
306		.proc_handler	= proc_dointvec,
307	},
308	{
309		.procname	= "plpmtud_probe_interval",
310		.data		= &init_net.sctp.probe_interval,
311		.maxlen		= sizeof(int),
312		.mode		= 0644,
313		.proc_handler	= proc_sctp_do_probe_interval,
314	},
315	{
316		.procname	= "udp_port",
317		.data		= &init_net.sctp.udp_port,
318		.maxlen		= sizeof(int),
319		.mode		= 0644,
320		.proc_handler	= proc_sctp_do_udp_port,
321		.extra1		= SYSCTL_ZERO,
322		.extra2		= &udp_port_max,
323	},
324	{
325		.procname	= "encap_port",
326		.data		= &init_net.sctp.encap_port,
327		.maxlen		= sizeof(int),
328		.mode		= 0644,
329		.proc_handler	= proc_dointvec_minmax,
330		.extra1		= SYSCTL_ZERO,
331		.extra2		= &udp_port_max,
332	},
333	{
334		.procname	= "addr_scope_policy",
335		.data		= &init_net.sctp.scope_policy,
336		.maxlen		= sizeof(int),
337		.mode		= 0644,
338		.proc_handler	= proc_dointvec_minmax,
339		.extra1		= SYSCTL_ZERO,
340		.extra2		= &addr_scope_max,
341	},
342	{
343		.procname	= "rwnd_update_shift",
344		.data		= &init_net.sctp.rwnd_upd_shift,
345		.maxlen		= sizeof(int),
346		.mode		= 0644,
347		.proc_handler	= &proc_dointvec_minmax,
348		.extra1		= SYSCTL_ONE,
349		.extra2		= &rwnd_scale_max,
350	},
351	{
352		.procname	= "max_autoclose",
353		.data		= &init_net.sctp.max_autoclose,
354		.maxlen		= sizeof(unsigned long),
355		.mode		= 0644,
356		.proc_handler	= &proc_doulongvec_minmax,
357		.extra1		= &max_autoclose_min,
358		.extra2		= &max_autoclose_max,
359	},
360#ifdef CONFIG_NET_L3_MASTER_DEV
361	{
362		.procname	= "l3mdev_accept",
363		.data		= &init_net.sctp.l3mdev_accept,
364		.maxlen		= sizeof(int),
365		.mode		= 0644,
366		.proc_handler	= proc_dointvec_minmax,
367		.extra1		= SYSCTL_ZERO,
368		.extra2		= SYSCTL_ONE,
369	},
370#endif
371	{
372		.procname	= "pf_enable",
373		.data		= &init_net.sctp.pf_enable,
374		.maxlen		= sizeof(int),
375		.mode		= 0644,
376		.proc_handler	= proc_dointvec,
377	},
378	{
379		.procname	= "pf_expose",
380		.data		= &init_net.sctp.pf_expose,
381		.maxlen		= sizeof(int),
382		.mode		= 0644,
383		.proc_handler	= proc_dointvec_minmax,
384		.extra1		= SYSCTL_ZERO,
385		.extra2		= &pf_expose_max,
386	},
387
388	{ /* sentinel */ }
389};
390
391static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
392				 void *buffer, size_t *lenp, loff_t *ppos)
393{
394	struct net *net = current->nsproxy->net_ns;
395	struct ctl_table tbl;
396	bool changed = false;
397	char *none = "none";
398	char tmp[8] = {0};
399	int ret;
400
401	memset(&tbl, 0, sizeof(struct ctl_table));
402
403	if (write) {
404		tbl.data = tmp;
405		tbl.maxlen = sizeof(tmp);
406	} else {
407		tbl.data = net->sctp.sctp_hmac_alg ? : none;
408		tbl.maxlen = strlen(tbl.data);
409	}
410
411	ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
412	if (write && ret == 0) {
413#ifdef CONFIG_CRYPTO_MD5
414		if (!strncmp(tmp, "md5", 3)) {
415			net->sctp.sctp_hmac_alg = "md5";
416			changed = true;
417		}
418#endif
419#ifdef CONFIG_CRYPTO_SHA1
420		if (!strncmp(tmp, "sha1", 4)) {
421			net->sctp.sctp_hmac_alg = "sha1";
422			changed = true;
423		}
424#endif
425		if (!strncmp(tmp, "none", 4)) {
426			net->sctp.sctp_hmac_alg = NULL;
427			changed = true;
428		}
429		if (!changed)
430			ret = -EINVAL;
431	}
432
433	return ret;
434}
435
436static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
437				void *buffer, size_t *lenp, loff_t *ppos)
438{
439	struct net *net = current->nsproxy->net_ns;
440	unsigned int min = *(unsigned int *) ctl->extra1;
441	unsigned int max = *(unsigned int *) ctl->extra2;
442	struct ctl_table tbl;
443	int ret, new_value;
444
445	memset(&tbl, 0, sizeof(struct ctl_table));
446	tbl.maxlen = sizeof(unsigned int);
447
448	if (write)
449		tbl.data = &new_value;
450	else
451		tbl.data = &net->sctp.rto_min;
452
453	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
454	if (write && ret == 0) {
455		if (new_value > max || new_value < min)
456			return -EINVAL;
457
458		net->sctp.rto_min = new_value;
459	}
460
461	return ret;
462}
463
464static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
465				void *buffer, size_t *lenp, loff_t *ppos)
466{
467	struct net *net = current->nsproxy->net_ns;
468	unsigned int min = *(unsigned int *) ctl->extra1;
469	unsigned int max = *(unsigned int *) ctl->extra2;
470	struct ctl_table tbl;
471	int ret, new_value;
472
473	memset(&tbl, 0, sizeof(struct ctl_table));
474	tbl.maxlen = sizeof(unsigned int);
475
476	if (write)
477		tbl.data = &new_value;
478	else
479		tbl.data = &net->sctp.rto_max;
480
481	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
482	if (write && ret == 0) {
483		if (new_value > max || new_value < min)
484			return -EINVAL;
485
486		net->sctp.rto_max = new_value;
487	}
488
489	return ret;
490}
491
492static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
493				   void *buffer, size_t *lenp, loff_t *ppos)
494{
495	if (write)
496		pr_warn_once("Changing rto_alpha or rto_beta may lead to "
497			     "suboptimal rtt/srtt estimations!\n");
498
499	return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos);
500}
501
502static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
503			     void *buffer, size_t *lenp, loff_t *ppos)
504{
505	struct net *net = current->nsproxy->net_ns;
506	struct ctl_table tbl;
507	int new_value, ret;
508
509	memset(&tbl, 0, sizeof(struct ctl_table));
510	tbl.maxlen = sizeof(unsigned int);
511
512	if (write)
513		tbl.data = &new_value;
514	else
515		tbl.data = &net->sctp.auth_enable;
516
517	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
518	if (write && ret == 0) {
519		struct sock *sk = net->sctp.ctl_sock;
520
521		net->sctp.auth_enable = new_value;
522		/* Update the value in the control socket */
523		lock_sock(sk);
524		sctp_sk(sk)->ep->auth_enable = new_value;
525		release_sock(sk);
526	}
527
528	return ret;
529}
530
531static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write,
532				 void *buffer, size_t *lenp, loff_t *ppos)
533{
534	struct net *net = current->nsproxy->net_ns;
535	unsigned int min = *(unsigned int *)ctl->extra1;
536	unsigned int max = *(unsigned int *)ctl->extra2;
537	struct ctl_table tbl;
538	int ret, new_value;
539
540	memset(&tbl, 0, sizeof(struct ctl_table));
541	tbl.maxlen = sizeof(unsigned int);
542
543	if (write)
544		tbl.data = &new_value;
545	else
546		tbl.data = &net->sctp.udp_port;
547
548	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
549	if (write && ret == 0) {
550		struct sock *sk = net->sctp.ctl_sock;
551
552		if (new_value > max || new_value < min)
553			return -EINVAL;
554
555		net->sctp.udp_port = new_value;
556		sctp_udp_sock_stop(net);
557		if (new_value) {
558			ret = sctp_udp_sock_start(net);
559			if (ret)
560				net->sctp.udp_port = 0;
561		}
562
563		/* Update the value in the control socket */
564		lock_sock(sk);
565		sctp_sk(sk)->udp_port = htons(net->sctp.udp_port);
566		release_sock(sk);
567	}
568
569	return ret;
570}
571
572static int proc_sctp_do_probe_interval(struct ctl_table *ctl, int write,
573				       void *buffer, size_t *lenp, loff_t *ppos)
574{
575	struct net *net = current->nsproxy->net_ns;
576	struct ctl_table tbl;
577	int ret, new_value;
578
579	memset(&tbl, 0, sizeof(struct ctl_table));
580	tbl.maxlen = sizeof(unsigned int);
581
582	if (write)
583		tbl.data = &new_value;
584	else
585		tbl.data = &net->sctp.probe_interval;
586
587	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
588	if (write && ret == 0) {
589		if (new_value && new_value < SCTP_PROBE_TIMER_MIN)
590			return -EINVAL;
591
592		net->sctp.probe_interval = new_value;
593	}
594
595	return ret;
596}
597
598int sctp_sysctl_net_register(struct net *net)
599{
600	struct ctl_table *table;
601	int i;
602
603	table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL);
604	if (!table)
605		return -ENOMEM;
606
607	for (i = 0; table[i].data; i++)
608		table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp;
609
610	table[SCTP_RTO_MIN_IDX].extra2 = &net->sctp.rto_max;
611	table[SCTP_RTO_MAX_IDX].extra1 = &net->sctp.rto_min;
612	table[SCTP_PF_RETRANS_IDX].extra2 = &net->sctp.ps_retrans;
613	table[SCTP_PS_RETRANS_IDX].extra1 = &net->sctp.pf_retrans;
614
615	net->sctp.sysctl_header = register_net_sysctl_sz(net, "net/sctp",
616							 table,
617							 ARRAY_SIZE(sctp_net_table));
618	if (net->sctp.sysctl_header == NULL) {
619		kfree(table);
620		return -ENOMEM;
621	}
622	return 0;
623}
624
625void sctp_sysctl_net_unregister(struct net *net)
626{
627	struct ctl_table *table;
628
629	table = net->sctp.sysctl_header->ctl_table_arg;
630	unregister_net_sysctl_table(net->sctp.sysctl_header);
631	kfree(table);
632}
633
634static struct ctl_table_header *sctp_sysctl_header;
635
636/* Sysctl registration.  */
637void sctp_sysctl_register(void)
638{
639	sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table);
640}
641
642/* Sysctl deregistration.  */
643void sctp_sysctl_unregister(void)
644{
645	unregister_net_sysctl_table(sctp_sysctl_header);
646}
647