Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[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
38 static unsigned long max_autoclose_min = 0;
39 static unsigned long max_autoclose_max =
40         (MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX)
41         ? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ;
42
43 static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
44                                 void __user *buffer, size_t *lenp,
45                                 loff_t *ppos);
46 static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
47                                 void __user *buffer, size_t *lenp,
48                                 loff_t *ppos);
49 static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
50                                 void __user *buffer, size_t *lenp,
51                                 loff_t *ppos);
52 static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
53                                    void __user *buffer, size_t *lenp,
54                                    loff_t *ppos);
55 static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
56                              void __user *buffer, size_t *lenp,
57                              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         = SYSCTL_INT_MAX,
216         },
217         {
218                 .procname       = "sndbuf_policy",
219                 .data           = &init_net.sctp.sndbuf_policy,
220                 .maxlen         = sizeof(int),
221                 .mode           = 0644,
222                 .proc_handler   = proc_dointvec,
223         },
224         {
225                 .procname       = "rcvbuf_policy",
226                 .data           = &init_net.sctp.rcvbuf_policy,
227                 .maxlen         = sizeof(int),
228                 .mode           = 0644,
229                 .proc_handler   = proc_dointvec,
230         },
231         {
232                 .procname       = "default_auto_asconf",
233                 .data           = &init_net.sctp.default_auto_asconf,
234                 .maxlen         = sizeof(int),
235                 .mode           = 0644,
236                 .proc_handler   = proc_dointvec,
237         },
238         {
239                 .procname       = "addip_enable",
240                 .data           = &init_net.sctp.addip_enable,
241                 .maxlen         = sizeof(int),
242                 .mode           = 0644,
243                 .proc_handler   = proc_dointvec,
244         },
245         {
246                 .procname       = "addip_noauth_enable",
247                 .data           = &init_net.sctp.addip_noauth,
248                 .maxlen         = sizeof(int),
249                 .mode           = 0644,
250                 .proc_handler   = proc_dointvec,
251         },
252         {
253                 .procname       = "prsctp_enable",
254                 .data           = &init_net.sctp.prsctp_enable,
255                 .maxlen         = sizeof(int),
256                 .mode           = 0644,
257                 .proc_handler   = proc_dointvec,
258         },
259         {
260                 .procname       = "reconf_enable",
261                 .data           = &init_net.sctp.reconf_enable,
262                 .maxlen         = sizeof(int),
263                 .mode           = 0644,
264                 .proc_handler   = proc_dointvec,
265         },
266         {
267                 .procname       = "auth_enable",
268                 .data           = &init_net.sctp.auth_enable,
269                 .maxlen         = sizeof(int),
270                 .mode           = 0644,
271                 .proc_handler   = proc_sctp_do_auth,
272         },
273         {
274                 .procname       = "intl_enable",
275                 .data           = &init_net.sctp.intl_enable,
276                 .maxlen         = sizeof(int),
277                 .mode           = 0644,
278                 .proc_handler   = proc_dointvec,
279         },
280         {
281                 .procname       = "addr_scope_policy",
282                 .data           = &init_net.sctp.scope_policy,
283                 .maxlen         = sizeof(int),
284                 .mode           = 0644,
285                 .proc_handler   = proc_dointvec_minmax,
286                 .extra1         = SYSCTL_ZERO,
287                 .extra2         = &addr_scope_max,
288         },
289         {
290                 .procname       = "rwnd_update_shift",
291                 .data           = &init_net.sctp.rwnd_upd_shift,
292                 .maxlen         = sizeof(int),
293                 .mode           = 0644,
294                 .proc_handler   = &proc_dointvec_minmax,
295                 .extra1         = SYSCTL_ONE,
296                 .extra2         = &rwnd_scale_max,
297         },
298         {
299                 .procname       = "max_autoclose",
300                 .data           = &init_net.sctp.max_autoclose,
301                 .maxlen         = sizeof(unsigned long),
302                 .mode           = 0644,
303                 .proc_handler   = &proc_doulongvec_minmax,
304                 .extra1         = &max_autoclose_min,
305                 .extra2         = &max_autoclose_max,
306         },
307         {
308                 .procname       = "pf_enable",
309                 .data           = &init_net.sctp.pf_enable,
310                 .maxlen         = sizeof(int),
311                 .mode           = 0644,
312                 .proc_handler   = proc_dointvec,
313         },
314
315         { /* sentinel */ }
316 };
317
318 static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
319                                 void __user *buffer, size_t *lenp,
320                                 loff_t *ppos)
321 {
322         struct net *net = current->nsproxy->net_ns;
323         struct ctl_table tbl;
324         bool changed = false;
325         char *none = "none";
326         char tmp[8] = {0};
327         int ret;
328
329         memset(&tbl, 0, sizeof(struct ctl_table));
330
331         if (write) {
332                 tbl.data = tmp;
333                 tbl.maxlen = sizeof(tmp);
334         } else {
335                 tbl.data = net->sctp.sctp_hmac_alg ? : none;
336                 tbl.maxlen = strlen(tbl.data);
337         }
338
339         ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
340         if (write && ret == 0) {
341 #ifdef CONFIG_CRYPTO_MD5
342                 if (!strncmp(tmp, "md5", 3)) {
343                         net->sctp.sctp_hmac_alg = "md5";
344                         changed = true;
345                 }
346 #endif
347 #ifdef CONFIG_CRYPTO_SHA1
348                 if (!strncmp(tmp, "sha1", 4)) {
349                         net->sctp.sctp_hmac_alg = "sha1";
350                         changed = true;
351                 }
352 #endif
353                 if (!strncmp(tmp, "none", 4)) {
354                         net->sctp.sctp_hmac_alg = NULL;
355                         changed = true;
356                 }
357                 if (!changed)
358                         ret = -EINVAL;
359         }
360
361         return ret;
362 }
363
364 static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
365                                 void __user *buffer, size_t *lenp,
366                                 loff_t *ppos)
367 {
368         struct net *net = current->nsproxy->net_ns;
369         unsigned int min = *(unsigned int *) ctl->extra1;
370         unsigned int max = *(unsigned int *) ctl->extra2;
371         struct ctl_table tbl;
372         int ret, new_value;
373
374         memset(&tbl, 0, sizeof(struct ctl_table));
375         tbl.maxlen = sizeof(unsigned int);
376
377         if (write)
378                 tbl.data = &new_value;
379         else
380                 tbl.data = &net->sctp.rto_min;
381
382         ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
383         if (write && ret == 0) {
384                 if (new_value > max || new_value < min)
385                         return -EINVAL;
386
387                 net->sctp.rto_min = new_value;
388         }
389
390         return ret;
391 }
392
393 static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
394                                 void __user *buffer, size_t *lenp,
395                                 loff_t *ppos)
396 {
397         struct net *net = current->nsproxy->net_ns;
398         unsigned int min = *(unsigned int *) ctl->extra1;
399         unsigned int max = *(unsigned int *) ctl->extra2;
400         struct ctl_table tbl;
401         int ret, new_value;
402
403         memset(&tbl, 0, sizeof(struct ctl_table));
404         tbl.maxlen = sizeof(unsigned int);
405
406         if (write)
407                 tbl.data = &new_value;
408         else
409                 tbl.data = &net->sctp.rto_max;
410
411         ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
412         if (write && ret == 0) {
413                 if (new_value > max || new_value < min)
414                         return -EINVAL;
415
416                 net->sctp.rto_max = new_value;
417         }
418
419         return ret;
420 }
421
422 static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
423                                    void __user *buffer, size_t *lenp,
424                                    loff_t *ppos)
425 {
426         if (write)
427                 pr_warn_once("Changing rto_alpha or rto_beta may lead to "
428                              "suboptimal rtt/srtt estimations!\n");
429
430         return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos);
431 }
432
433 static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
434                              void __user *buffer, size_t *lenp,
435                              loff_t *ppos)
436 {
437         struct net *net = current->nsproxy->net_ns;
438         struct ctl_table tbl;
439         int new_value, ret;
440
441         memset(&tbl, 0, sizeof(struct ctl_table));
442         tbl.maxlen = sizeof(unsigned int);
443
444         if (write)
445                 tbl.data = &new_value;
446         else
447                 tbl.data = &net->sctp.auth_enable;
448
449         ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
450         if (write && ret == 0) {
451                 struct sock *sk = net->sctp.ctl_sock;
452
453                 net->sctp.auth_enable = new_value;
454                 /* Update the value in the control socket */
455                 lock_sock(sk);
456                 sctp_sk(sk)->ep->auth_enable = new_value;
457                 release_sock(sk);
458         }
459
460         return ret;
461 }
462
463 int sctp_sysctl_net_register(struct net *net)
464 {
465         struct ctl_table *table;
466         int i;
467
468         table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL);
469         if (!table)
470                 return -ENOMEM;
471
472         for (i = 0; table[i].data; i++)
473                 table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp;
474
475         net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table);
476         if (net->sctp.sysctl_header == NULL) {
477                 kfree(table);
478                 return -ENOMEM;
479         }
480         return 0;
481 }
482
483 void sctp_sysctl_net_unregister(struct net *net)
484 {
485         struct ctl_table *table;
486
487         table = net->sctp.sysctl_header->ctl_table_arg;
488         unregister_net_sysctl_table(net->sctp.sysctl_header);
489         kfree(table);
490 }
491
492 static struct ctl_table_header *sctp_sysctl_header;
493
494 /* Sysctl registration.  */
495 void sctp_sysctl_register(void)
496 {
497         sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table);
498 }
499
500 /* Sysctl deregistration.  */
501 void sctp_sysctl_unregister(void)
502 {
503         unregister_net_sysctl_table(sctp_sysctl_header);
504 }