File Index
Files and directories
Sign in
FILE

sysctl.c

File preview with syntax highlighting.

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