Linux Audio

Check our new training course

Loading...
v5.4
  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;
 37
 38static unsigned long max_autoclose_min = 0;
 39static unsigned long max_autoclose_max =
 40	(MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX)
 41	? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ;
 42
 43static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
 44				void __user *buffer, size_t *lenp,
 45				loff_t *ppos);
 46static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
 47				void __user *buffer, size_t *lenp,
 48				loff_t *ppos);
 49static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
 50				void __user *buffer, size_t *lenp,
 51				loff_t *ppos);
 52static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
 53				   void __user *buffer, size_t *lenp,
 54				   loff_t *ppos);
 55static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
 56			     void __user *buffer, size_t *lenp,
 57			     loff_t *ppos);
 58
 59static 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
 85static 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	= "ecn_enable",
282		.data		= &init_net.sctp.ecn_enable,
283		.maxlen		= sizeof(int),
284		.mode		= 0644,
285		.proc_handler	= proc_dointvec,
286	},
287	{
288		.procname	= "addr_scope_policy",
289		.data		= &init_net.sctp.scope_policy,
290		.maxlen		= sizeof(int),
291		.mode		= 0644,
292		.proc_handler	= proc_dointvec_minmax,
293		.extra1		= SYSCTL_ZERO,
294		.extra2		= &addr_scope_max,
295	},
296	{
297		.procname	= "rwnd_update_shift",
298		.data		= &init_net.sctp.rwnd_upd_shift,
299		.maxlen		= sizeof(int),
300		.mode		= 0644,
301		.proc_handler	= &proc_dointvec_minmax,
302		.extra1		= SYSCTL_ONE,
303		.extra2		= &rwnd_scale_max,
304	},
305	{
306		.procname	= "max_autoclose",
307		.data		= &init_net.sctp.max_autoclose,
308		.maxlen		= sizeof(unsigned long),
309		.mode		= 0644,
310		.proc_handler	= &proc_doulongvec_minmax,
311		.extra1		= &max_autoclose_min,
312		.extra2		= &max_autoclose_max,
313	},
314	{
315		.procname	= "pf_enable",
316		.data		= &init_net.sctp.pf_enable,
317		.maxlen		= sizeof(int),
318		.mode		= 0644,
319		.proc_handler	= proc_dointvec,
320	},
321
322	{ /* sentinel */ }
323};
324
325static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
326				void __user *buffer, size_t *lenp,
327				loff_t *ppos)
328{
329	struct net *net = current->nsproxy->net_ns;
330	struct ctl_table tbl;
331	bool changed = false;
332	char *none = "none";
333	char tmp[8] = {0};
334	int ret;
335
336	memset(&tbl, 0, sizeof(struct ctl_table));
337
338	if (write) {
339		tbl.data = tmp;
340		tbl.maxlen = sizeof(tmp);
341	} else {
342		tbl.data = net->sctp.sctp_hmac_alg ? : none;
343		tbl.maxlen = strlen(tbl.data);
344	}
345
346	ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
347	if (write && ret == 0) {
348#ifdef CONFIG_CRYPTO_MD5
349		if (!strncmp(tmp, "md5", 3)) {
350			net->sctp.sctp_hmac_alg = "md5";
351			changed = true;
352		}
353#endif
354#ifdef CONFIG_CRYPTO_SHA1
355		if (!strncmp(tmp, "sha1", 4)) {
356			net->sctp.sctp_hmac_alg = "sha1";
357			changed = true;
358		}
359#endif
360		if (!strncmp(tmp, "none", 4)) {
361			net->sctp.sctp_hmac_alg = NULL;
362			changed = true;
363		}
364		if (!changed)
365			ret = -EINVAL;
366	}
367
368	return ret;
369}
370
371static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
372				void __user *buffer, size_t *lenp,
373				loff_t *ppos)
374{
375	struct net *net = current->nsproxy->net_ns;
376	unsigned int min = *(unsigned int *) ctl->extra1;
377	unsigned int max = *(unsigned int *) ctl->extra2;
378	struct ctl_table tbl;
379	int ret, new_value;
380
381	memset(&tbl, 0, sizeof(struct ctl_table));
382	tbl.maxlen = sizeof(unsigned int);
383
384	if (write)
385		tbl.data = &new_value;
386	else
387		tbl.data = &net->sctp.rto_min;
388
389	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
390	if (write && ret == 0) {
391		if (new_value > max || new_value < min)
392			return -EINVAL;
393
394		net->sctp.rto_min = new_value;
395	}
396
397	return ret;
398}
399
400static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
401				void __user *buffer, size_t *lenp,
402				loff_t *ppos)
403{
404	struct net *net = current->nsproxy->net_ns;
405	unsigned int min = *(unsigned int *) ctl->extra1;
406	unsigned int max = *(unsigned int *) ctl->extra2;
407	struct ctl_table tbl;
408	int ret, new_value;
409
410	memset(&tbl, 0, sizeof(struct ctl_table));
411	tbl.maxlen = sizeof(unsigned int);
412
413	if (write)
414		tbl.data = &new_value;
415	else
416		tbl.data = &net->sctp.rto_max;
417
418	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
419	if (write && ret == 0) {
420		if (new_value > max || new_value < min)
421			return -EINVAL;
422
423		net->sctp.rto_max = new_value;
424	}
425
426	return ret;
427}
428
429static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
430				   void __user *buffer, size_t *lenp,
431				   loff_t *ppos)
432{
433	if (write)
434		pr_warn_once("Changing rto_alpha or rto_beta may lead to "
435			     "suboptimal rtt/srtt estimations!\n");
436
437	return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos);
438}
439
440static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
441			     void __user *buffer, size_t *lenp,
442			     loff_t *ppos)
443{
444	struct net *net = current->nsproxy->net_ns;
445	struct ctl_table tbl;
446	int new_value, ret;
447
448	memset(&tbl, 0, sizeof(struct ctl_table));
449	tbl.maxlen = sizeof(unsigned int);
450
451	if (write)
452		tbl.data = &new_value;
453	else
454		tbl.data = &net->sctp.auth_enable;
455
456	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
457	if (write && ret == 0) {
458		struct sock *sk = net->sctp.ctl_sock;
459
460		net->sctp.auth_enable = new_value;
461		/* Update the value in the control socket */
462		lock_sock(sk);
463		sctp_sk(sk)->ep->auth_enable = new_value;
464		release_sock(sk);
465	}
466
467	return ret;
468}
469
470int sctp_sysctl_net_register(struct net *net)
471{
472	struct ctl_table *table;
473	int i;
474
475	table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL);
476	if (!table)
477		return -ENOMEM;
478
479	for (i = 0; table[i].data; i++)
480		table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp;
481
482	net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table);
483	if (net->sctp.sysctl_header == NULL) {
484		kfree(table);
485		return -ENOMEM;
486	}
487	return 0;
488}
489
490void sctp_sysctl_net_unregister(struct net *net)
491{
492	struct ctl_table *table;
493
494	table = net->sctp.sysctl_header->ctl_table_arg;
495	unregister_net_sysctl_table(net->sctp.sysctl_header);
496	kfree(table);
497}
498
499static struct ctl_table_header *sctp_sysctl_header;
500
501/* Sysctl registration.  */
502void sctp_sysctl_register(void)
503{
504	sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table);
505}
506
507/* Sysctl deregistration.  */
508void sctp_sysctl_unregister(void)
509{
510	unregister_net_sysctl_table(sctp_sysctl_header);
511}
v4.6
 
  1/* SCTP kernel implementation
  2 * (C) Copyright IBM Corp. 2002, 2004
  3 * Copyright (c) 2002 Intel Corp.
  4 *
  5 * This file is part of the SCTP kernel implementation
  6 *
  7 * Sysctl related interfaces for SCTP.
  8 *
  9 * This SCTP implementation is free software;
 10 * you can redistribute it and/or modify it under the terms of
 11 * the GNU General Public License as published by
 12 * the Free Software Foundation; either version 2, or (at your option)
 13 * any later version.
 14 *
 15 * This SCTP implementation is distributed in the hope that it
 16 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
 17 *                 ************************
 18 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 19 * See the GNU General Public License for more details.
 20 *
 21 * You should have received a copy of the GNU General Public License
 22 * along with GNU CC; see the file COPYING.  If not, see
 23 * <http://www.gnu.org/licenses/>.
 24 *
 25 * Please send any bug reports or fixes you make to the
 26 * email address(es):
 27 *    lksctp developers <linux-sctp@vger.kernel.org>
 28 *
 29 * Written or modified by:
 30 *    Mingqin Liu           <liuming@us.ibm.com>
 31 *    Jon Grimm             <jgrimm@us.ibm.com>
 32 *    Ardelle Fan           <ardelle.fan@intel.com>
 33 *    Ryan Layer            <rmlayer@us.ibm.com>
 34 *    Sridhar Samudrala     <sri@us.ibm.com>
 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 zero = 0;
 44static int one = 1;
 45static int timer_max = 86400000; /* ms in one day */
 46static int int_max = INT_MAX;
 47static int sack_timer_min = 1;
 48static int sack_timer_max = 500;
 49static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */
 50static int rwnd_scale_max = 16;
 51static int rto_alpha_min = 0;
 52static int rto_beta_min = 0;
 53static int rto_alpha_max = 1000;
 54static int rto_beta_max = 1000;
 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_alpha_beta(struct ctl_table *ctl, int write,
 71				   void __user *buffer, size_t *lenp,
 72				   loff_t *ppos);
 73static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
 74			     void __user *buffer, size_t *lenp,
 75			     loff_t *ppos);
 76
 77static struct ctl_table sctp_table[] = {
 78	{
 79		.procname	= "sctp_mem",
 80		.data		= &sysctl_sctp_mem,
 81		.maxlen		= sizeof(sysctl_sctp_mem),
 82		.mode		= 0644,
 83		.proc_handler	= proc_doulongvec_minmax
 84	},
 85	{
 86		.procname	= "sctp_rmem",
 87		.data		= &sysctl_sctp_rmem,
 88		.maxlen		= sizeof(sysctl_sctp_rmem),
 89		.mode		= 0644,
 90		.proc_handler	= proc_dointvec,
 91	},
 92	{
 93		.procname	= "sctp_wmem",
 94		.data		= &sysctl_sctp_wmem,
 95		.maxlen		= sizeof(sysctl_sctp_wmem),
 96		.mode		= 0644,
 97		.proc_handler	= proc_dointvec,
 98	},
 99
100	{ /* sentinel */ }
101};
102
103static struct ctl_table sctp_net_table[] = {
104	{
105		.procname	= "rto_initial",
106		.data		= &init_net.sctp.rto_initial,
107		.maxlen		= sizeof(unsigned int),
108		.mode		= 0644,
109		.proc_handler	= proc_dointvec_minmax,
110		.extra1         = &one,
111		.extra2         = &timer_max
112	},
113	{
114		.procname	= "rto_min",
115		.data		= &init_net.sctp.rto_min,
116		.maxlen		= sizeof(unsigned int),
117		.mode		= 0644,
118		.proc_handler	= proc_sctp_do_rto_min,
119		.extra1         = &one,
120		.extra2         = &init_net.sctp.rto_max
121	},
122	{
123		.procname	= "rto_max",
124		.data		= &init_net.sctp.rto_max,
125		.maxlen		= sizeof(unsigned int),
126		.mode		= 0644,
127		.proc_handler	= proc_sctp_do_rto_max,
128		.extra1         = &init_net.sctp.rto_min,
129		.extra2         = &timer_max
130	},
131	{
132		.procname	= "rto_alpha_exp_divisor",
133		.data		= &init_net.sctp.rto_alpha,
134		.maxlen		= sizeof(int),
135		.mode		= 0644,
136		.proc_handler	= proc_sctp_do_alpha_beta,
137		.extra1		= &rto_alpha_min,
138		.extra2		= &rto_alpha_max,
139	},
140	{
141		.procname	= "rto_beta_exp_divisor",
142		.data		= &init_net.sctp.rto_beta,
143		.maxlen		= sizeof(int),
144		.mode		= 0644,
145		.proc_handler	= proc_sctp_do_alpha_beta,
146		.extra1		= &rto_beta_min,
147		.extra2		= &rto_beta_max,
148	},
149	{
150		.procname	= "max_burst",
151		.data		= &init_net.sctp.max_burst,
152		.maxlen		= sizeof(int),
153		.mode		= 0644,
154		.proc_handler	= proc_dointvec_minmax,
155		.extra1		= &zero,
156		.extra2		= &int_max
157	},
158	{
159		.procname	= "cookie_preserve_enable",
160		.data		= &init_net.sctp.cookie_preserve_enable,
161		.maxlen		= sizeof(int),
162		.mode		= 0644,
163		.proc_handler	= proc_dointvec,
164	},
165	{
166		.procname	= "cookie_hmac_alg",
167		.data		= &init_net.sctp.sctp_hmac_alg,
168		.maxlen		= 8,
169		.mode		= 0644,
170		.proc_handler	= proc_sctp_do_hmac_alg,
171	},
172	{
173		.procname	= "valid_cookie_life",
174		.data		= &init_net.sctp.valid_cookie_life,
175		.maxlen		= sizeof(unsigned int),
176		.mode		= 0644,
177		.proc_handler	= proc_dointvec_minmax,
178		.extra1         = &one,
179		.extra2         = &timer_max
180	},
181	{
182		.procname	= "sack_timeout",
183		.data		= &init_net.sctp.sack_timeout,
184		.maxlen		= sizeof(int),
185		.mode		= 0644,
186		.proc_handler	= proc_dointvec_minmax,
187		.extra1         = &sack_timer_min,
188		.extra2         = &sack_timer_max,
189	},
190	{
191		.procname	= "hb_interval",
192		.data		= &init_net.sctp.hb_interval,
193		.maxlen		= sizeof(unsigned int),
194		.mode		= 0644,
195		.proc_handler	= proc_dointvec_minmax,
196		.extra1         = &one,
197		.extra2         = &timer_max
198	},
199	{
200		.procname	= "association_max_retrans",
201		.data		= &init_net.sctp.max_retrans_association,
202		.maxlen		= sizeof(int),
203		.mode		= 0644,
204		.proc_handler	= proc_dointvec_minmax,
205		.extra1		= &one,
206		.extra2		= &int_max
207	},
208	{
209		.procname	= "path_max_retrans",
210		.data		= &init_net.sctp.max_retrans_path,
211		.maxlen		= sizeof(int),
212		.mode		= 0644,
213		.proc_handler	= proc_dointvec_minmax,
214		.extra1		= &one,
215		.extra2		= &int_max
216	},
217	{
218		.procname	= "max_init_retransmits",
219		.data		= &init_net.sctp.max_retrans_init,
220		.maxlen		= sizeof(int),
221		.mode		= 0644,
222		.proc_handler	= proc_dointvec_minmax,
223		.extra1		= &one,
224		.extra2		= &int_max
225	},
226	{
227		.procname	= "pf_retrans",
228		.data		= &init_net.sctp.pf_retrans,
229		.maxlen		= sizeof(int),
230		.mode		= 0644,
231		.proc_handler	= proc_dointvec_minmax,
232		.extra1		= &zero,
233		.extra2		= &int_max
234	},
235	{
236		.procname	= "sndbuf_policy",
237		.data		= &init_net.sctp.sndbuf_policy,
238		.maxlen		= sizeof(int),
239		.mode		= 0644,
240		.proc_handler	= proc_dointvec,
241	},
242	{
243		.procname	= "rcvbuf_policy",
244		.data		= &init_net.sctp.rcvbuf_policy,
245		.maxlen		= sizeof(int),
246		.mode		= 0644,
247		.proc_handler	= proc_dointvec,
248	},
249	{
250		.procname	= "default_auto_asconf",
251		.data		= &init_net.sctp.default_auto_asconf,
252		.maxlen		= sizeof(int),
253		.mode		= 0644,
254		.proc_handler	= proc_dointvec,
255	},
256	{
257		.procname	= "addip_enable",
258		.data		= &init_net.sctp.addip_enable,
259		.maxlen		= sizeof(int),
260		.mode		= 0644,
261		.proc_handler	= proc_dointvec,
262	},
263	{
264		.procname	= "addip_noauth_enable",
265		.data		= &init_net.sctp.addip_noauth,
266		.maxlen		= sizeof(int),
267		.mode		= 0644,
268		.proc_handler	= proc_dointvec,
269	},
270	{
271		.procname	= "prsctp_enable",
272		.data		= &init_net.sctp.prsctp_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	= "addr_scope_policy",
286		.data		= &init_net.sctp.scope_policy,
287		.maxlen		= sizeof(int),
288		.mode		= 0644,
289		.proc_handler	= proc_dointvec_minmax,
290		.extra1		= &zero,
291		.extra2		= &addr_scope_max,
292	},
293	{
294		.procname	= "rwnd_update_shift",
295		.data		= &init_net.sctp.rwnd_upd_shift,
296		.maxlen		= sizeof(int),
297		.mode		= 0644,
298		.proc_handler	= &proc_dointvec_minmax,
299		.extra1		= &one,
300		.extra2		= &rwnd_scale_max,
301	},
302	{
303		.procname	= "max_autoclose",
304		.data		= &init_net.sctp.max_autoclose,
305		.maxlen		= sizeof(unsigned long),
306		.mode		= 0644,
307		.proc_handler	= &proc_doulongvec_minmax,
308		.extra1		= &max_autoclose_min,
309		.extra2		= &max_autoclose_max,
310	},
311	{
312		.procname	= "pf_enable",
313		.data		= &init_net.sctp.pf_enable,
314		.maxlen		= sizeof(int),
315		.mode		= 0644,
316		.proc_handler	= proc_dointvec,
317	},
318
319	{ /* sentinel */ }
320};
321
322static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
323				void __user *buffer, size_t *lenp,
324				loff_t *ppos)
325{
326	struct net *net = current->nsproxy->net_ns;
327	struct ctl_table tbl;
328	bool changed = false;
329	char *none = "none";
330	char tmp[8] = {0};
331	int ret;
332
333	memset(&tbl, 0, sizeof(struct ctl_table));
334
335	if (write) {
336		tbl.data = tmp;
337		tbl.maxlen = sizeof(tmp);
338	} else {
339		tbl.data = net->sctp.sctp_hmac_alg ? : none;
340		tbl.maxlen = strlen(tbl.data);
341	}
342
343	ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
344	if (write && ret == 0) {
345#ifdef CONFIG_CRYPTO_MD5
346		if (!strncmp(tmp, "md5", 3)) {
347			net->sctp.sctp_hmac_alg = "md5";
348			changed = true;
349		}
350#endif
351#ifdef CONFIG_CRYPTO_SHA1
352		if (!strncmp(tmp, "sha1", 4)) {
353			net->sctp.sctp_hmac_alg = "sha1";
354			changed = true;
355		}
356#endif
357		if (!strncmp(tmp, "none", 4)) {
358			net->sctp.sctp_hmac_alg = NULL;
359			changed = true;
360		}
361		if (!changed)
362			ret = -EINVAL;
363	}
364
365	return ret;
366}
367
368static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
369				void __user *buffer, size_t *lenp,
370				loff_t *ppos)
371{
372	struct net *net = current->nsproxy->net_ns;
373	unsigned int min = *(unsigned int *) ctl->extra1;
374	unsigned int max = *(unsigned int *) ctl->extra2;
375	struct ctl_table tbl;
376	int ret, new_value;
377
378	memset(&tbl, 0, sizeof(struct ctl_table));
379	tbl.maxlen = sizeof(unsigned int);
380
381	if (write)
382		tbl.data = &new_value;
383	else
384		tbl.data = &net->sctp.rto_min;
385
386	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
387	if (write && ret == 0) {
388		if (new_value > max || new_value < min)
389			return -EINVAL;
390
391		net->sctp.rto_min = new_value;
392	}
393
394	return ret;
395}
396
397static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
398				void __user *buffer, size_t *lenp,
399				loff_t *ppos)
400{
401	struct net *net = current->nsproxy->net_ns;
402	unsigned int min = *(unsigned int *) ctl->extra1;
403	unsigned int max = *(unsigned int *) ctl->extra2;
404	struct ctl_table tbl;
405	int ret, new_value;
406
407	memset(&tbl, 0, sizeof(struct ctl_table));
408	tbl.maxlen = sizeof(unsigned int);
409
410	if (write)
411		tbl.data = &new_value;
412	else
413		tbl.data = &net->sctp.rto_max;
414
415	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
416	if (write && ret == 0) {
417		if (new_value > max || new_value < min)
418			return -EINVAL;
419
420		net->sctp.rto_max = new_value;
421	}
422
423	return ret;
424}
425
426static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
427				   void __user *buffer, size_t *lenp,
428				   loff_t *ppos)
429{
430	if (write)
431		pr_warn_once("Changing rto_alpha or rto_beta may lead to "
432			     "suboptimal rtt/srtt estimations!\n");
433
434	return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos);
435}
436
437static int proc_sctp_do_auth(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	struct ctl_table tbl;
443	int new_value, ret;
444
445	memset(&tbl, 0, sizeof(struct ctl_table));
446	tbl.maxlen = sizeof(unsigned int);
447
448	if (write)
449		tbl.data = &new_value;
450	else
451		tbl.data = &net->sctp.auth_enable;
452
453	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
454	if (write && ret == 0) {
455		struct sock *sk = net->sctp.ctl_sock;
456
457		net->sctp.auth_enable = new_value;
458		/* Update the value in the control socket */
459		lock_sock(sk);
460		sctp_sk(sk)->ep->auth_enable = new_value;
461		release_sock(sk);
462	}
463
464	return ret;
465}
466
467int sctp_sysctl_net_register(struct net *net)
468{
469	struct ctl_table *table;
470	int i;
471
472	table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL);
473	if (!table)
474		return -ENOMEM;
475
476	for (i = 0; table[i].data; i++)
477		table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp;
478
479	net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table);
480	if (net->sctp.sysctl_header == NULL) {
481		kfree(table);
482		return -ENOMEM;
483	}
484	return 0;
485}
486
487void sctp_sysctl_net_unregister(struct net *net)
488{
489	struct ctl_table *table;
490
491	table = net->sctp.sysctl_header->ctl_table_arg;
492	unregister_net_sysctl_table(net->sctp.sysctl_header);
493	kfree(table);
494}
495
496static struct ctl_table_header *sctp_sysctl_header;
497
498/* Sysctl registration.  */
499void sctp_sysctl_register(void)
500{
501	sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table);
502}
503
504/* Sysctl deregistration.  */
505void sctp_sysctl_unregister(void)
506{
507	unregister_net_sysctl_table(sctp_sysctl_header);
508}