Linux Audio

Check our new training course

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