xref: /kernel/linux/linux-5.10/net/sctp/sysctl.c (revision 8c2ecf20)
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;
39
40static unsigned long max_autoclose_min = 0;
41static unsigned long max_autoclose_max =
42	(MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX)
43	? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ;
44
45static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
46				 void *buffer, size_t *lenp, loff_t *ppos);
47static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
48				void *buffer, size_t *lenp, loff_t *ppos);
49static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, void *buffer,
50				size_t *lenp, loff_t *ppos);
51static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
52				   void *buffer, size_t *lenp, loff_t *ppos);
53static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
54			     void *buffer, size_t *lenp, loff_t *ppos);
55
56static struct ctl_table sctp_table[] = {
57	{
58		.procname	= "sctp_mem",
59		.data		= &sysctl_sctp_mem,
60		.maxlen		= sizeof(sysctl_sctp_mem),
61		.mode		= 0644,
62		.proc_handler	= proc_doulongvec_minmax
63	},
64	{
65		.procname	= "sctp_rmem",
66		.data		= &sysctl_sctp_rmem,
67		.maxlen		= sizeof(sysctl_sctp_rmem),
68		.mode		= 0644,
69		.proc_handler	= proc_dointvec,
70	},
71	{
72		.procname	= "sctp_wmem",
73		.data		= &sysctl_sctp_wmem,
74		.maxlen		= sizeof(sysctl_sctp_wmem),
75		.mode		= 0644,
76		.proc_handler	= proc_dointvec,
77	},
78
79	{ /* sentinel */ }
80};
81
82/* The following index defines are used in sctp_sysctl_net_register().
83 * If you add new items to the sctp_net_table, please ensure that
84 * the index values of these defines hold the same meaning indicated by
85 * their macro names when they appear in sctp_net_table.
86 */
87#define SCTP_RTO_MIN_IDX       0
88#define SCTP_RTO_MAX_IDX       1
89#define SCTP_PF_RETRANS_IDX    2
90#define SCTP_PS_RETRANS_IDX    3
91
92static struct ctl_table sctp_net_table[] = {
93	[SCTP_RTO_MIN_IDX] = {
94		.procname	= "rto_min",
95		.data		= &init_net.sctp.rto_min,
96		.maxlen		= sizeof(unsigned int),
97		.mode		= 0644,
98		.proc_handler	= proc_sctp_do_rto_min,
99		.extra1         = SYSCTL_ONE,
100		.extra2         = &init_net.sctp.rto_max
101	},
102	[SCTP_RTO_MAX_IDX] =  {
103		.procname	= "rto_max",
104		.data		= &init_net.sctp.rto_max,
105		.maxlen		= sizeof(unsigned int),
106		.mode		= 0644,
107		.proc_handler	= proc_sctp_do_rto_max,
108		.extra1         = &init_net.sctp.rto_min,
109		.extra2         = &timer_max
110	},
111	[SCTP_PF_RETRANS_IDX] = {
112		.procname	= "pf_retrans",
113		.data		= &init_net.sctp.pf_retrans,
114		.maxlen		= sizeof(int),
115		.mode		= 0644,
116		.proc_handler	= proc_dointvec_minmax,
117		.extra1		= SYSCTL_ZERO,
118		.extra2		= &init_net.sctp.ps_retrans,
119	},
120	[SCTP_PS_RETRANS_IDX] = {
121		.procname	= "ps_retrans",
122		.data		= &init_net.sctp.ps_retrans,
123		.maxlen		= sizeof(int),
124		.mode		= 0644,
125		.proc_handler	= proc_dointvec_minmax,
126		.extra1		= &init_net.sctp.pf_retrans,
127		.extra2		= &ps_retrans_max,
128	},
129	{
130		.procname	= "rto_initial",
131		.data		= &init_net.sctp.rto_initial,
132		.maxlen		= sizeof(unsigned int),
133		.mode		= 0644,
134		.proc_handler	= proc_dointvec_minmax,
135		.extra1         = SYSCTL_ONE,
136		.extra2         = &timer_max
137	},
138	{
139		.procname	= "rto_alpha_exp_divisor",
140		.data		= &init_net.sctp.rto_alpha,
141		.maxlen		= sizeof(int),
142		.mode		= 0644,
143		.proc_handler	= proc_sctp_do_alpha_beta,
144		.extra1		= &rto_alpha_min,
145		.extra2		= &rto_alpha_max,
146	},
147	{
148		.procname	= "rto_beta_exp_divisor",
149		.data		= &init_net.sctp.rto_beta,
150		.maxlen		= sizeof(int),
151		.mode		= 0644,
152		.proc_handler	= proc_sctp_do_alpha_beta,
153		.extra1		= &rto_beta_min,
154		.extra2		= &rto_beta_max,
155	},
156	{
157		.procname	= "max_burst",
158		.data		= &init_net.sctp.max_burst,
159		.maxlen		= sizeof(int),
160		.mode		= 0644,
161		.proc_handler	= proc_dointvec_minmax,
162		.extra1		= SYSCTL_ZERO,
163		.extra2		= SYSCTL_INT_MAX,
164	},
165	{
166		.procname	= "cookie_preserve_enable",
167		.data		= &init_net.sctp.cookie_preserve_enable,
168		.maxlen		= sizeof(int),
169		.mode		= 0644,
170		.proc_handler	= proc_dointvec,
171	},
172	{
173		.procname	= "cookie_hmac_alg",
174		.data		= &init_net.sctp.sctp_hmac_alg,
175		.maxlen		= 8,
176		.mode		= 0644,
177		.proc_handler	= proc_sctp_do_hmac_alg,
178	},
179	{
180		.procname	= "valid_cookie_life",
181		.data		= &init_net.sctp.valid_cookie_life,
182		.maxlen		= sizeof(unsigned int),
183		.mode		= 0644,
184		.proc_handler	= proc_dointvec_minmax,
185		.extra1         = SYSCTL_ONE,
186		.extra2         = &timer_max
187	},
188	{
189		.procname	= "sack_timeout",
190		.data		= &init_net.sctp.sack_timeout,
191		.maxlen		= sizeof(int),
192		.mode		= 0644,
193		.proc_handler	= proc_dointvec_minmax,
194		.extra1         = &sack_timer_min,
195		.extra2         = &sack_timer_max,
196	},
197	{
198		.procname	= "hb_interval",
199		.data		= &init_net.sctp.hb_interval,
200		.maxlen		= sizeof(unsigned int),
201		.mode		= 0644,
202		.proc_handler	= proc_dointvec_minmax,
203		.extra1         = SYSCTL_ONE,
204		.extra2         = &timer_max
205	},
206	{
207		.procname	= "association_max_retrans",
208		.data		= &init_net.sctp.max_retrans_association,
209		.maxlen		= sizeof(int),
210		.mode		= 0644,
211		.proc_handler	= proc_dointvec_minmax,
212		.extra1		= SYSCTL_ONE,
213		.extra2		= SYSCTL_INT_MAX,
214	},
215	{
216		.procname	= "path_max_retrans",
217		.data		= &init_net.sctp.max_retrans_path,
218		.maxlen		= sizeof(int),
219		.mode		= 0644,
220		.proc_handler	= proc_dointvec_minmax,
221		.extra1		= SYSCTL_ONE,
222		.extra2		= SYSCTL_INT_MAX,
223	},
224	{
225		.procname	= "max_init_retransmits",
226		.data		= &init_net.sctp.max_retrans_init,
227		.maxlen		= sizeof(int),
228		.mode		= 0644,
229		.proc_handler	= proc_dointvec_minmax,
230		.extra1		= SYSCTL_ONE,
231		.extra2		= SYSCTL_INT_MAX,
232	},
233	{
234		.procname	= "sndbuf_policy",
235		.data		= &init_net.sctp.sndbuf_policy,
236		.maxlen		= sizeof(int),
237		.mode		= 0644,
238		.proc_handler	= proc_dointvec,
239	},
240	{
241		.procname	= "rcvbuf_policy",
242		.data		= &init_net.sctp.rcvbuf_policy,
243		.maxlen		= sizeof(int),
244		.mode		= 0644,
245		.proc_handler	= proc_dointvec,
246	},
247	{
248		.procname	= "default_auto_asconf",
249		.data		= &init_net.sctp.default_auto_asconf,
250		.maxlen		= sizeof(int),
251		.mode		= 0644,
252		.proc_handler	= proc_dointvec,
253	},
254	{
255		.procname	= "addip_enable",
256		.data		= &init_net.sctp.addip_enable,
257		.maxlen		= sizeof(int),
258		.mode		= 0644,
259		.proc_handler	= proc_dointvec,
260	},
261	{
262		.procname	= "addip_noauth_enable",
263		.data		= &init_net.sctp.addip_noauth,
264		.maxlen		= sizeof(int),
265		.mode		= 0644,
266		.proc_handler	= proc_dointvec,
267	},
268	{
269		.procname	= "prsctp_enable",
270		.data		= &init_net.sctp.prsctp_enable,
271		.maxlen		= sizeof(int),
272		.mode		= 0644,
273		.proc_handler	= proc_dointvec,
274	},
275	{
276		.procname	= "reconf_enable",
277		.data		= &init_net.sctp.reconf_enable,
278		.maxlen		= sizeof(int),
279		.mode		= 0644,
280		.proc_handler	= proc_dointvec,
281	},
282	{
283		.procname	= "auth_enable",
284		.data		= &init_net.sctp.auth_enable,
285		.maxlen		= sizeof(int),
286		.mode		= 0644,
287		.proc_handler	= proc_sctp_do_auth,
288	},
289	{
290		.procname	= "intl_enable",
291		.data		= &init_net.sctp.intl_enable,
292		.maxlen		= sizeof(int),
293		.mode		= 0644,
294		.proc_handler	= proc_dointvec,
295	},
296	{
297		.procname	= "ecn_enable",
298		.data		= &init_net.sctp.ecn_enable,
299		.maxlen		= sizeof(int),
300		.mode		= 0644,
301		.proc_handler	= proc_dointvec,
302	},
303	{
304		.procname	= "addr_scope_policy",
305		.data		= &init_net.sctp.scope_policy,
306		.maxlen		= sizeof(int),
307		.mode		= 0644,
308		.proc_handler	= proc_dointvec_minmax,
309		.extra1		= SYSCTL_ZERO,
310		.extra2		= &addr_scope_max,
311	},
312	{
313		.procname	= "rwnd_update_shift",
314		.data		= &init_net.sctp.rwnd_upd_shift,
315		.maxlen		= sizeof(int),
316		.mode		= 0644,
317		.proc_handler	= &proc_dointvec_minmax,
318		.extra1		= SYSCTL_ONE,
319		.extra2		= &rwnd_scale_max,
320	},
321	{
322		.procname	= "max_autoclose",
323		.data		= &init_net.sctp.max_autoclose,
324		.maxlen		= sizeof(unsigned long),
325		.mode		= 0644,
326		.proc_handler	= &proc_doulongvec_minmax,
327		.extra1		= &max_autoclose_min,
328		.extra2		= &max_autoclose_max,
329	},
330	{
331		.procname	= "pf_enable",
332		.data		= &init_net.sctp.pf_enable,
333		.maxlen		= sizeof(int),
334		.mode		= 0644,
335		.proc_handler	= proc_dointvec,
336	},
337	{
338		.procname	= "pf_expose",
339		.data		= &init_net.sctp.pf_expose,
340		.maxlen		= sizeof(int),
341		.mode		= 0644,
342		.proc_handler	= proc_dointvec_minmax,
343		.extra1		= SYSCTL_ZERO,
344		.extra2		= &pf_expose_max,
345	},
346
347	{ /* sentinel */ }
348};
349
350static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
351				 void *buffer, size_t *lenp, loff_t *ppos)
352{
353	struct net *net = current->nsproxy->net_ns;
354	struct ctl_table tbl;
355	bool changed = false;
356	char *none = "none";
357	char tmp[8] = {0};
358	int ret;
359
360	memset(&tbl, 0, sizeof(struct ctl_table));
361
362	if (write) {
363		tbl.data = tmp;
364		tbl.maxlen = sizeof(tmp);
365	} else {
366		tbl.data = net->sctp.sctp_hmac_alg ? : none;
367		tbl.maxlen = strlen(tbl.data);
368	}
369
370	ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
371	if (write && ret == 0) {
372#ifdef CONFIG_CRYPTO_MD5
373		if (!strncmp(tmp, "md5", 3)) {
374			net->sctp.sctp_hmac_alg = "md5";
375			changed = true;
376		}
377#endif
378#ifdef CONFIG_CRYPTO_SHA1
379		if (!strncmp(tmp, "sha1", 4)) {
380			net->sctp.sctp_hmac_alg = "sha1";
381			changed = true;
382		}
383#endif
384		if (!strncmp(tmp, "none", 4)) {
385			net->sctp.sctp_hmac_alg = NULL;
386			changed = true;
387		}
388		if (!changed)
389			ret = -EINVAL;
390	}
391
392	return ret;
393}
394
395static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
396				void *buffer, size_t *lenp, loff_t *ppos)
397{
398	struct net *net = current->nsproxy->net_ns;
399	unsigned int min = *(unsigned int *) ctl->extra1;
400	unsigned int max = *(unsigned int *) ctl->extra2;
401	struct ctl_table tbl;
402	int ret, new_value;
403
404	memset(&tbl, 0, sizeof(struct ctl_table));
405	tbl.maxlen = sizeof(unsigned int);
406
407	if (write)
408		tbl.data = &new_value;
409	else
410		tbl.data = &net->sctp.rto_min;
411
412	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
413	if (write && ret == 0) {
414		if (new_value > max || new_value < min)
415			return -EINVAL;
416
417		net->sctp.rto_min = new_value;
418	}
419
420	return ret;
421}
422
423static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
424				void *buffer, size_t *lenp, loff_t *ppos)
425{
426	struct net *net = current->nsproxy->net_ns;
427	unsigned int min = *(unsigned int *) ctl->extra1;
428	unsigned int max = *(unsigned int *) ctl->extra2;
429	struct ctl_table tbl;
430	int ret, new_value;
431
432	memset(&tbl, 0, sizeof(struct ctl_table));
433	tbl.maxlen = sizeof(unsigned int);
434
435	if (write)
436		tbl.data = &new_value;
437	else
438		tbl.data = &net->sctp.rto_max;
439
440	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
441	if (write && ret == 0) {
442		if (new_value > max || new_value < min)
443			return -EINVAL;
444
445		net->sctp.rto_max = new_value;
446	}
447
448	return ret;
449}
450
451static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
452				   void *buffer, size_t *lenp, loff_t *ppos)
453{
454	if (write)
455		pr_warn_once("Changing rto_alpha or rto_beta may lead to "
456			     "suboptimal rtt/srtt estimations!\n");
457
458	return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos);
459}
460
461static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
462			     void *buffer, size_t *lenp, loff_t *ppos)
463{
464	struct net *net = current->nsproxy->net_ns;
465	struct ctl_table tbl;
466	int new_value, ret;
467
468	memset(&tbl, 0, sizeof(struct ctl_table));
469	tbl.maxlen = sizeof(unsigned int);
470
471	if (write)
472		tbl.data = &new_value;
473	else
474		tbl.data = &net->sctp.auth_enable;
475
476	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
477	if (write && ret == 0) {
478		struct sock *sk = net->sctp.ctl_sock;
479
480		net->sctp.auth_enable = new_value;
481		/* Update the value in the control socket */
482		lock_sock(sk);
483		sctp_sk(sk)->ep->auth_enable = new_value;
484		release_sock(sk);
485	}
486
487	return ret;
488}
489
490int sctp_sysctl_net_register(struct net *net)
491{
492	struct ctl_table *table;
493	int i;
494
495	table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL);
496	if (!table)
497		return -ENOMEM;
498
499	for (i = 0; table[i].data; i++)
500		table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp;
501
502	table[SCTP_RTO_MIN_IDX].extra2 = &net->sctp.rto_max;
503	table[SCTP_RTO_MAX_IDX].extra1 = &net->sctp.rto_min;
504	table[SCTP_PF_RETRANS_IDX].extra2 = &net->sctp.ps_retrans;
505	table[SCTP_PS_RETRANS_IDX].extra1 = &net->sctp.pf_retrans;
506
507	net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table);
508	if (net->sctp.sysctl_header == NULL) {
509		kfree(table);
510		return -ENOMEM;
511	}
512	return 0;
513}
514
515void sctp_sysctl_net_unregister(struct net *net)
516{
517	struct ctl_table *table;
518
519	table = net->sctp.sysctl_header->ctl_table_arg;
520	unregister_net_sysctl_table(net->sctp.sysctl_header);
521	kfree(table);
522}
523
524static struct ctl_table_header *sctp_sysctl_header;
525
526/* Sysctl registration.  */
527void sctp_sysctl_register(void)
528{
529	sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table);
530}
531
532/* Sysctl deregistration.  */
533void sctp_sysctl_unregister(void)
534{
535	unregister_net_sysctl_table(sctp_sysctl_header);
536}
537