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