Linux Audio

Check our new training course

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