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