• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
28 static int timer_max = 86400000; /* ms in one day */
29 static int sack_timer_min = 1;
30 static int sack_timer_max = 500;
31 static int addr_scope_max = SCTP_SCOPE_POLICY_MAX;
32 static int rwnd_scale_max = 16;
33 static int rto_alpha_min = 0;
34 static int rto_beta_min = 0;
35 static int rto_alpha_max = 1000;
36 static int rto_beta_max = 1000;
37 static int pf_expose_max = SCTP_PF_EXPOSE_MAX;
38 static int ps_retrans_max = SCTP_PS_RETRANS_MAX;
39 
40 static unsigned long max_autoclose_min = 0;
41 static unsigned long max_autoclose_max =
42 	(MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX)
43 	? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ;
44 
45 static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
46 				 void *buffer, size_t *lenp, loff_t *ppos);
47 static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
48 				void *buffer, size_t *lenp, loff_t *ppos);
49 static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, void *buffer,
50 				size_t *lenp, loff_t *ppos);
51 static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
52 				   void *buffer, size_t *lenp, loff_t *ppos);
53 static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
54 			     void *buffer, size_t *lenp, loff_t *ppos);
55 
56 static 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 
92 static 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 
proc_sctp_do_hmac_alg(struct ctl_table * ctl,int write,void * buffer,size_t * lenp,loff_t * ppos)350 static 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 
proc_sctp_do_rto_min(struct ctl_table * ctl,int write,void * buffer,size_t * lenp,loff_t * ppos)395 static 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 
proc_sctp_do_rto_max(struct ctl_table * ctl,int write,void * buffer,size_t * lenp,loff_t * ppos)423 static 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 
proc_sctp_do_alpha_beta(struct ctl_table * ctl,int write,void * buffer,size_t * lenp,loff_t * ppos)451 static 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 
proc_sctp_do_auth(struct ctl_table * ctl,int write,void * buffer,size_t * lenp,loff_t * ppos)461 static 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 
sctp_sysctl_net_register(struct net * net)490 int 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 
sctp_sysctl_net_unregister(struct net * net)515 void 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 
524 static struct ctl_table_header *sctp_sysctl_header;
525 
526 /* Sysctl registration.  */
sctp_sysctl_register(void)527 void sctp_sysctl_register(void)
528 {
529 	sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table);
530 }
531 
532 /* Sysctl deregistration.  */
sctp_sysctl_unregister(void)533 void sctp_sysctl_unregister(void)
534 {
535 	unregister_net_sysctl_table(sctp_sysctl_header);
536 }
537