xref: /openbmc/linux/net/sctp/sysctl.c (revision 47505b8b)
147505b8bSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
260c778b2SVlad Yasevich /* SCTP kernel implementation
31da177e4SLinus Torvalds  * (C) Copyright IBM Corp. 2002, 2004
41da177e4SLinus Torvalds  * Copyright (c) 2002 Intel Corp.
51da177e4SLinus Torvalds  *
660c778b2SVlad Yasevich  * This file is part of the SCTP kernel implementation
71da177e4SLinus Torvalds  *
81da177e4SLinus Torvalds  * Sysctl related interfaces for SCTP.
91da177e4SLinus Torvalds  *
101da177e4SLinus Torvalds  * Please send any bug reports or fixes you make to the
111da177e4SLinus Torvalds  * email address(es):
1291705c61SDaniel Borkmann  *    lksctp developers <linux-sctp@vger.kernel.org>
131da177e4SLinus Torvalds  *
141da177e4SLinus Torvalds  * Written or modified by:
151da177e4SLinus Torvalds  *    Mingqin Liu           <liuming@us.ibm.com>
161da177e4SLinus Torvalds  *    Jon Grimm             <jgrimm@us.ibm.com>
171da177e4SLinus Torvalds  *    Ardelle Fan           <ardelle.fan@intel.com>
181da177e4SLinus Torvalds  *    Ryan Layer            <rmlayer@us.ibm.com>
191da177e4SLinus Torvalds  *    Sridhar Samudrala     <sri@us.ibm.com>
201da177e4SLinus Torvalds  */
211da177e4SLinus Torvalds 
22b58537a1SDaniel Borkmann #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23b58537a1SDaniel Borkmann 
241da177e4SLinus Torvalds #include <net/sctp/structs.h>
258c5955d8SAdrian Bunk #include <net/sctp/sctp.h>
261da177e4SLinus Torvalds #include <linux/sysctl.h>
271da177e4SLinus Torvalds 
283fd091e7SVladislav Yasevich static int zero = 0;
293fd091e7SVladislav Yasevich static int one = 1;
303fd091e7SVladislav Yasevich static int timer_max = 86400000; /* ms in one day */
313fd091e7SVladislav Yasevich static int int_max = INT_MAX;
32d48e074dSJean-Mickael Guerin static int sack_timer_min = 1;
33d48e074dSJean-Mickael Guerin static int sack_timer_max = 500;
34701ef3e6SXin Long static int addr_scope_max = SCTP_SCOPE_POLICY_MAX;
3590f2f531SVlad Yasevich static int rwnd_scale_max = 16;
36b58537a1SDaniel Borkmann static int rto_alpha_min = 0;
37b58537a1SDaniel Borkmann static int rto_beta_min = 0;
38b58537a1SDaniel Borkmann static int rto_alpha_max = 1000;
39b58537a1SDaniel Borkmann static int rto_beta_max = 1000;
40b58537a1SDaniel Borkmann 
412692ba61SXi Wang static unsigned long max_autoclose_min = 0;
422692ba61SXi Wang static unsigned long max_autoclose_max =
432692ba61SXi Wang 	(MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX)
442692ba61SXi Wang 	? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ;
451da177e4SLinus Torvalds 
46b486b228Swangweidong static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
473c68198eSNeil Horman 				void __user *buffer, size_t *lenp,
483c68198eSNeil Horman 				loff_t *ppos);
494f3fdf3bSwangweidong static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
504f3fdf3bSwangweidong 				void __user *buffer, size_t *lenp,
514f3fdf3bSwangweidong 				loff_t *ppos);
524f3fdf3bSwangweidong static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
534f3fdf3bSwangweidong 				void __user *buffer, size_t *lenp,
544f3fdf3bSwangweidong 				loff_t *ppos);
55b58537a1SDaniel Borkmann static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
56b58537a1SDaniel Borkmann 				   void __user *buffer, size_t *lenp,
57b58537a1SDaniel Borkmann 				   loff_t *ppos);
58b14878ccSVlad Yasevich static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
59b14878ccSVlad Yasevich 			     void __user *buffer, size_t *lenp,
60b14878ccSVlad Yasevich 			     loff_t *ppos);
614f3fdf3bSwangweidong 
62fe2c6338SJoe Perches static struct ctl_table sctp_table[] = {
631da177e4SLinus Torvalds 	{
644d93df0aSNeil Horman 		.procname	= "sctp_mem",
654d93df0aSNeil Horman 		.data		= &sysctl_sctp_mem,
664d93df0aSNeil Horman 		.maxlen		= sizeof(sysctl_sctp_mem),
674d93df0aSNeil Horman 		.mode		= 0644,
688d987e5cSEric Dumazet 		.proc_handler	= proc_doulongvec_minmax
694d93df0aSNeil Horman 	},
704d93df0aSNeil Horman 	{
714d93df0aSNeil Horman 		.procname	= "sctp_rmem",
724d93df0aSNeil Horman 		.data		= &sysctl_sctp_rmem,
734d93df0aSNeil Horman 		.maxlen		= sizeof(sysctl_sctp_rmem),
744d93df0aSNeil Horman 		.mode		= 0644,
756d9f239aSAlexey Dobriyan 		.proc_handler	= proc_dointvec,
764d93df0aSNeil Horman 	},
774d93df0aSNeil Horman 	{
784d93df0aSNeil Horman 		.procname	= "sctp_wmem",
794d93df0aSNeil Horman 		.data		= &sysctl_sctp_wmem,
804d93df0aSNeil Horman 		.maxlen		= sizeof(sysctl_sctp_wmem),
814d93df0aSNeil Horman 		.mode		= 0644,
826d9f239aSAlexey Dobriyan 		.proc_handler	= proc_dointvec,
834d93df0aSNeil Horman 	},
84e1fc3b14SEric W. Biederman 
85e1fc3b14SEric W. Biederman 	{ /* sentinel */ }
86e1fc3b14SEric W. Biederman };
87e1fc3b14SEric W. Biederman 
88fe2c6338SJoe Perches static struct ctl_table sctp_net_table[] = {
89a29a5bd4SVlad Yasevich 	{
90e1fc3b14SEric W. Biederman 		.procname	= "rto_initial",
91e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.rto_initial,
92e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(unsigned int),
93e1fc3b14SEric W. Biederman 		.mode		= 0644,
94e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec_minmax,
95e1fc3b14SEric W. Biederman 		.extra1         = &one,
96e1fc3b14SEric W. Biederman 		.extra2         = &timer_max
97e1fc3b14SEric W. Biederman 	},
98e1fc3b14SEric W. Biederman 	{
99e1fc3b14SEric W. Biederman 		.procname	= "rto_min",
100e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.rto_min,
101e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(unsigned int),
102e1fc3b14SEric W. Biederman 		.mode		= 0644,
1034f3fdf3bSwangweidong 		.proc_handler	= proc_sctp_do_rto_min,
104e1fc3b14SEric W. Biederman 		.extra1         = &one,
1054f3fdf3bSwangweidong 		.extra2         = &init_net.sctp.rto_max
106e1fc3b14SEric W. Biederman 	},
107e1fc3b14SEric W. Biederman 	{
108e1fc3b14SEric W. Biederman 		.procname	= "rto_max",
109e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.rto_max,
110e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(unsigned int),
111e1fc3b14SEric W. Biederman 		.mode		= 0644,
1124f3fdf3bSwangweidong 		.proc_handler	= proc_sctp_do_rto_max,
1134f3fdf3bSwangweidong 		.extra1         = &init_net.sctp.rto_min,
114e1fc3b14SEric W. Biederman 		.extra2         = &timer_max
115e1fc3b14SEric W. Biederman 	},
116e1fc3b14SEric W. Biederman 	{
117e1fc3b14SEric W. Biederman 		.procname	= "rto_alpha_exp_divisor",
118e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.rto_alpha,
119e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
120b58537a1SDaniel Borkmann 		.mode		= 0644,
121b58537a1SDaniel Borkmann 		.proc_handler	= proc_sctp_do_alpha_beta,
122b58537a1SDaniel Borkmann 		.extra1		= &rto_alpha_min,
123b58537a1SDaniel Borkmann 		.extra2		= &rto_alpha_max,
124e1fc3b14SEric W. Biederman 	},
125e1fc3b14SEric W. Biederman 	{
126e1fc3b14SEric W. Biederman 		.procname	= "rto_beta_exp_divisor",
127e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.rto_beta,
128e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
129b58537a1SDaniel Borkmann 		.mode		= 0644,
130b58537a1SDaniel Borkmann 		.proc_handler	= proc_sctp_do_alpha_beta,
131b58537a1SDaniel Borkmann 		.extra1		= &rto_beta_min,
132b58537a1SDaniel Borkmann 		.extra2		= &rto_beta_max,
133e1fc3b14SEric W. Biederman 	},
134e1fc3b14SEric W. Biederman 	{
135e1fc3b14SEric W. Biederman 		.procname	= "max_burst",
136e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.max_burst,
137e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
138e1fc3b14SEric W. Biederman 		.mode		= 0644,
139e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec_minmax,
140e1fc3b14SEric W. Biederman 		.extra1		= &zero,
141e1fc3b14SEric W. Biederman 		.extra2		= &int_max
142e1fc3b14SEric W. Biederman 	},
143e1fc3b14SEric W. Biederman 	{
144e1fc3b14SEric W. Biederman 		.procname	= "cookie_preserve_enable",
145e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.cookie_preserve_enable,
146e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
147e1fc3b14SEric W. Biederman 		.mode		= 0644,
148e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec,
149e1fc3b14SEric W. Biederman 	},
150e1fc3b14SEric W. Biederman 	{
1513c68198eSNeil Horman 		.procname	= "cookie_hmac_alg",
15222a1f514Swangweidong 		.data		= &init_net.sctp.sctp_hmac_alg,
1533c68198eSNeil Horman 		.maxlen		= 8,
1543c68198eSNeil Horman 		.mode		= 0644,
1553c68198eSNeil Horman 		.proc_handler	= proc_sctp_do_hmac_alg,
1563c68198eSNeil Horman 	},
1573c68198eSNeil Horman 	{
158e1fc3b14SEric W. Biederman 		.procname	= "valid_cookie_life",
159e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.valid_cookie_life,
160e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(unsigned int),
161e1fc3b14SEric W. Biederman 		.mode		= 0644,
162e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec_minmax,
163e1fc3b14SEric W. Biederman 		.extra1         = &one,
164e1fc3b14SEric W. Biederman 		.extra2         = &timer_max
165e1fc3b14SEric W. Biederman 	},
166e1fc3b14SEric W. Biederman 	{
167e1fc3b14SEric W. Biederman 		.procname	= "sack_timeout",
168e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.sack_timeout,
169e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
170e1fc3b14SEric W. Biederman 		.mode		= 0644,
171e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec_minmax,
172e1fc3b14SEric W. Biederman 		.extra1         = &sack_timer_min,
173e1fc3b14SEric W. Biederman 		.extra2         = &sack_timer_max,
174e1fc3b14SEric W. Biederman 	},
175e1fc3b14SEric W. Biederman 	{
176e1fc3b14SEric W. Biederman 		.procname	= "hb_interval",
177e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.hb_interval,
178e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(unsigned int),
179e1fc3b14SEric W. Biederman 		.mode		= 0644,
180e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec_minmax,
181e1fc3b14SEric W. Biederman 		.extra1         = &one,
182e1fc3b14SEric W. Biederman 		.extra2         = &timer_max
183e1fc3b14SEric W. Biederman 	},
184e1fc3b14SEric W. Biederman 	{
185e1fc3b14SEric W. Biederman 		.procname	= "association_max_retrans",
186e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.max_retrans_association,
187e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
188e1fc3b14SEric W. Biederman 		.mode		= 0644,
189e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec_minmax,
190e1fc3b14SEric W. Biederman 		.extra1		= &one,
191e1fc3b14SEric W. Biederman 		.extra2		= &int_max
192e1fc3b14SEric W. Biederman 	},
193e1fc3b14SEric W. Biederman 	{
194e1fc3b14SEric W. Biederman 		.procname	= "path_max_retrans",
195e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.max_retrans_path,
196e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
197e1fc3b14SEric W. Biederman 		.mode		= 0644,
198e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec_minmax,
199e1fc3b14SEric W. Biederman 		.extra1		= &one,
200e1fc3b14SEric W. Biederman 		.extra2		= &int_max
201e1fc3b14SEric W. Biederman 	},
202e1fc3b14SEric W. Biederman 	{
203e1fc3b14SEric W. Biederman 		.procname	= "max_init_retransmits",
204e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.max_retrans_init,
205e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
206e1fc3b14SEric W. Biederman 		.mode		= 0644,
207e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec_minmax,
208e1fc3b14SEric W. Biederman 		.extra1		= &one,
209e1fc3b14SEric W. Biederman 		.extra2		= &int_max
210e1fc3b14SEric W. Biederman 	},
211e1fc3b14SEric W. Biederman 	{
212e1fc3b14SEric W. Biederman 		.procname	= "pf_retrans",
213e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.pf_retrans,
214e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
215e1fc3b14SEric W. Biederman 		.mode		= 0644,
216e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec_minmax,
217e1fc3b14SEric W. Biederman 		.extra1		= &zero,
218e1fc3b14SEric W. Biederman 		.extra2		= &int_max
219e1fc3b14SEric W. Biederman 	},
220e1fc3b14SEric W. Biederman 	{
221e1fc3b14SEric W. Biederman 		.procname	= "sndbuf_policy",
222e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.sndbuf_policy,
223e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
224e1fc3b14SEric W. Biederman 		.mode		= 0644,
225e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec,
226e1fc3b14SEric W. Biederman 	},
227e1fc3b14SEric W. Biederman 	{
228e1fc3b14SEric W. Biederman 		.procname	= "rcvbuf_policy",
229e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.rcvbuf_policy,
230e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
231e1fc3b14SEric W. Biederman 		.mode		= 0644,
232e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec,
233e1fc3b14SEric W. Biederman 	},
234e1fc3b14SEric W. Biederman 	{
235e1fc3b14SEric W. Biederman 		.procname	= "default_auto_asconf",
236e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.default_auto_asconf,
237e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
238e1fc3b14SEric W. Biederman 		.mode		= 0644,
239e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec,
240e1fc3b14SEric W. Biederman 	},
241e1fc3b14SEric W. Biederman 	{
242e1fc3b14SEric W. Biederman 		.procname	= "addip_enable",
243e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.addip_enable,
244a29a5bd4SVlad Yasevich 		.maxlen		= sizeof(int),
245a29a5bd4SVlad Yasevich 		.mode		= 0644,
2466d9f239aSAlexey Dobriyan 		.proc_handler	= proc_dointvec,
247a29a5bd4SVlad Yasevich 	},
24873d9c4fdSVlad Yasevich 	{
24973d9c4fdSVlad Yasevich 		.procname	= "addip_noauth_enable",
250e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.addip_noauth,
251e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
252e1fc3b14SEric W. Biederman 		.mode		= 0644,
253e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec,
254e1fc3b14SEric W. Biederman 	},
255e1fc3b14SEric W. Biederman 	{
256e1fc3b14SEric W. Biederman 		.procname	= "prsctp_enable",
257e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.prsctp_enable,
258e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
259e1fc3b14SEric W. Biederman 		.mode		= 0644,
260e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec,
261e1fc3b14SEric W. Biederman 	},
262e1fc3b14SEric W. Biederman 	{
263c0d8bab6SXin Long 		.procname	= "reconf_enable",
264c0d8bab6SXin Long 		.data		= &init_net.sctp.reconf_enable,
265c0d8bab6SXin Long 		.maxlen		= sizeof(int),
266c0d8bab6SXin Long 		.mode		= 0644,
267c0d8bab6SXin Long 		.proc_handler	= proc_dointvec,
268c0d8bab6SXin Long 	},
269c0d8bab6SXin Long 	{
270e1fc3b14SEric W. Biederman 		.procname	= "auth_enable",
271e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.auth_enable,
27273d9c4fdSVlad Yasevich 		.maxlen		= sizeof(int),
27373d9c4fdSVlad Yasevich 		.mode		= 0644,
274b14878ccSVlad Yasevich 		.proc_handler	= proc_sctp_do_auth,
27573d9c4fdSVlad Yasevich 	},
27672388433SBhaskar Dutta 	{
277463118c3SXin Long 		.procname	= "intl_enable",
278463118c3SXin Long 		.data		= &init_net.sctp.intl_enable,
279463118c3SXin Long 		.maxlen		= sizeof(int),
280463118c3SXin Long 		.mode		= 0644,
281463118c3SXin Long 		.proc_handler	= proc_dointvec,
282463118c3SXin Long 	},
283463118c3SXin Long 	{
28472388433SBhaskar Dutta 		.procname	= "addr_scope_policy",
285e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.scope_policy,
28672388433SBhaskar Dutta 		.maxlen		= sizeof(int),
28772388433SBhaskar Dutta 		.mode		= 0644,
2886d456111SEric W. Biederman 		.proc_handler	= proc_dointvec_minmax,
28972388433SBhaskar Dutta 		.extra1		= &zero,
29072388433SBhaskar Dutta 		.extra2		= &addr_scope_max,
29172388433SBhaskar Dutta 	},
29290f2f531SVlad Yasevich 	{
29390f2f531SVlad Yasevich 		.procname	= "rwnd_update_shift",
294e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.rwnd_upd_shift,
29590f2f531SVlad Yasevich 		.maxlen		= sizeof(int),
29690f2f531SVlad Yasevich 		.mode		= 0644,
29790f2f531SVlad Yasevich 		.proc_handler	= &proc_dointvec_minmax,
29890f2f531SVlad Yasevich 		.extra1		= &one,
29990f2f531SVlad Yasevich 		.extra2		= &rwnd_scale_max,
30090f2f531SVlad Yasevich 	},
3012692ba61SXi Wang 	{
3022692ba61SXi Wang 		.procname	= "max_autoclose",
303e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.max_autoclose,
3042692ba61SXi Wang 		.maxlen		= sizeof(unsigned long),
3052692ba61SXi Wang 		.mode		= 0644,
3062692ba61SXi Wang 		.proc_handler	= &proc_doulongvec_minmax,
3072692ba61SXi Wang 		.extra1		= &max_autoclose_min,
3082692ba61SXi Wang 		.extra2		= &max_autoclose_max,
3092692ba61SXi Wang 	},
310566178f8SZhu Yanjun 	{
311566178f8SZhu Yanjun 		.procname	= "pf_enable",
312566178f8SZhu Yanjun 		.data		= &init_net.sctp.pf_enable,
313566178f8SZhu Yanjun 		.maxlen		= sizeof(int),
314566178f8SZhu Yanjun 		.mode		= 0644,
315566178f8SZhu Yanjun 		.proc_handler	= proc_dointvec,
316566178f8SZhu Yanjun 	},
31771acc0ddSDavid S. Miller 
318d7fc02c7SLinus Torvalds 	{ /* sentinel */ }
3191da177e4SLinus Torvalds };
3201da177e4SLinus Torvalds 
321b486b228Swangweidong static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
3223c68198eSNeil Horman 				void __user *buffer, size_t *lenp,
3233c68198eSNeil Horman 				loff_t *ppos)
3243c68198eSNeil Horman {
3253c68198eSNeil Horman 	struct net *net = current->nsproxy->net_ns;
326fe2c6338SJoe Perches 	struct ctl_table tbl;
327ff5e92c1SDaniel Borkmann 	bool changed = false;
3283c68198eSNeil Horman 	char *none = "none";
329320f1a4aSSasha Levin 	char tmp[8] = {0};
330ff5e92c1SDaniel Borkmann 	int ret;
3313c68198eSNeil Horman 
3323c68198eSNeil Horman 	memset(&tbl, 0, sizeof(struct ctl_table));
3333c68198eSNeil Horman 
3343c68198eSNeil Horman 	if (write) {
3353c68198eSNeil Horman 		tbl.data = tmp;
336ff5e92c1SDaniel Borkmann 		tbl.maxlen = sizeof(tmp);
3373c68198eSNeil Horman 	} else {
3383c68198eSNeil Horman 		tbl.data = net->sctp.sctp_hmac_alg ? : none;
3393c68198eSNeil Horman 		tbl.maxlen = strlen(tbl.data);
3403c68198eSNeil Horman 	}
3413c68198eSNeil Horman 
342ff5e92c1SDaniel Borkmann 	ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
343ff5e92c1SDaniel Borkmann 	if (write && ret == 0) {
3443c68198eSNeil Horman #ifdef CONFIG_CRYPTO_MD5
3453c68198eSNeil Horman 		if (!strncmp(tmp, "md5", 3)) {
3463c68198eSNeil Horman 			net->sctp.sctp_hmac_alg = "md5";
347ff5e92c1SDaniel Borkmann 			changed = true;
3483c68198eSNeil Horman 		}
3493c68198eSNeil Horman #endif
3503c68198eSNeil Horman #ifdef CONFIG_CRYPTO_SHA1
3513c68198eSNeil Horman 		if (!strncmp(tmp, "sha1", 4)) {
3523c68198eSNeil Horman 			net->sctp.sctp_hmac_alg = "sha1";
353ff5e92c1SDaniel Borkmann 			changed = true;
3543c68198eSNeil Horman 		}
3553c68198eSNeil Horman #endif
3563c68198eSNeil Horman 		if (!strncmp(tmp, "none", 4)) {
3573c68198eSNeil Horman 			net->sctp.sctp_hmac_alg = NULL;
358ff5e92c1SDaniel Borkmann 			changed = true;
3593c68198eSNeil Horman 		}
3603c68198eSNeil Horman 		if (!changed)
3613c68198eSNeil Horman 			ret = -EINVAL;
3623c68198eSNeil Horman 	}
3633c68198eSNeil Horman 
3643c68198eSNeil Horman 	return ret;
3653c68198eSNeil Horman }
3663c68198eSNeil Horman 
3674f3fdf3bSwangweidong static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
3684f3fdf3bSwangweidong 				void __user *buffer, size_t *lenp,
3694f3fdf3bSwangweidong 				loff_t *ppos)
3704f3fdf3bSwangweidong {
3714f3fdf3bSwangweidong 	struct net *net = current->nsproxy->net_ns;
3724f3fdf3bSwangweidong 	unsigned int min = *(unsigned int *) ctl->extra1;
3734f3fdf3bSwangweidong 	unsigned int max = *(unsigned int *) ctl->extra2;
374ff5e92c1SDaniel Borkmann 	struct ctl_table tbl;
375ff5e92c1SDaniel Borkmann 	int ret, new_value;
3764f3fdf3bSwangweidong 
3774f3fdf3bSwangweidong 	memset(&tbl, 0, sizeof(struct ctl_table));
3784f3fdf3bSwangweidong 	tbl.maxlen = sizeof(unsigned int);
3794f3fdf3bSwangweidong 
3804f3fdf3bSwangweidong 	if (write)
3814f3fdf3bSwangweidong 		tbl.data = &new_value;
3824f3fdf3bSwangweidong 	else
3834f3fdf3bSwangweidong 		tbl.data = &net->sctp.rto_min;
384ff5e92c1SDaniel Borkmann 
3854f3fdf3bSwangweidong 	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
386ff5e92c1SDaniel Borkmann 	if (write && ret == 0) {
387ff5e92c1SDaniel Borkmann 		if (new_value > max || new_value < min)
3884f3fdf3bSwangweidong 			return -EINVAL;
389ff5e92c1SDaniel Borkmann 
3904f3fdf3bSwangweidong 		net->sctp.rto_min = new_value;
3914f3fdf3bSwangweidong 	}
392ff5e92c1SDaniel Borkmann 
3934f3fdf3bSwangweidong 	return ret;
3944f3fdf3bSwangweidong }
3954f3fdf3bSwangweidong 
3964f3fdf3bSwangweidong static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
3974f3fdf3bSwangweidong 				void __user *buffer, size_t *lenp,
3984f3fdf3bSwangweidong 				loff_t *ppos)
3994f3fdf3bSwangweidong {
4004f3fdf3bSwangweidong 	struct net *net = current->nsproxy->net_ns;
4014f3fdf3bSwangweidong 	unsigned int min = *(unsigned int *) ctl->extra1;
4024f3fdf3bSwangweidong 	unsigned int max = *(unsigned int *) ctl->extra2;
403ff5e92c1SDaniel Borkmann 	struct ctl_table tbl;
404ff5e92c1SDaniel Borkmann 	int ret, new_value;
4054f3fdf3bSwangweidong 
4064f3fdf3bSwangweidong 	memset(&tbl, 0, sizeof(struct ctl_table));
4074f3fdf3bSwangweidong 	tbl.maxlen = sizeof(unsigned int);
4084f3fdf3bSwangweidong 
4094f3fdf3bSwangweidong 	if (write)
4104f3fdf3bSwangweidong 		tbl.data = &new_value;
4114f3fdf3bSwangweidong 	else
4124f3fdf3bSwangweidong 		tbl.data = &net->sctp.rto_max;
413ff5e92c1SDaniel Borkmann 
4144f3fdf3bSwangweidong 	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
415ff5e92c1SDaniel Borkmann 	if (write && ret == 0) {
416ff5e92c1SDaniel Borkmann 		if (new_value > max || new_value < min)
4174f3fdf3bSwangweidong 			return -EINVAL;
418ff5e92c1SDaniel Borkmann 
4194f3fdf3bSwangweidong 		net->sctp.rto_max = new_value;
4204f3fdf3bSwangweidong 	}
421ff5e92c1SDaniel Borkmann 
4224f3fdf3bSwangweidong 	return ret;
4234f3fdf3bSwangweidong }
4244f3fdf3bSwangweidong 
425b58537a1SDaniel Borkmann static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
426b58537a1SDaniel Borkmann 				   void __user *buffer, size_t *lenp,
427b58537a1SDaniel Borkmann 				   loff_t *ppos)
428b58537a1SDaniel Borkmann {
429eaea2da7SDaniel Borkmann 	if (write)
430b58537a1SDaniel Borkmann 		pr_warn_once("Changing rto_alpha or rto_beta may lead to "
431b58537a1SDaniel Borkmann 			     "suboptimal rtt/srtt estimations!\n");
432b58537a1SDaniel Borkmann 
433b58537a1SDaniel Borkmann 	return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos);
434b58537a1SDaniel Borkmann }
435b58537a1SDaniel Borkmann 
436b14878ccSVlad Yasevich static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
437b14878ccSVlad Yasevich 			     void __user *buffer, size_t *lenp,
438b14878ccSVlad Yasevich 			     loff_t *ppos)
439b14878ccSVlad Yasevich {
440b14878ccSVlad Yasevich 	struct net *net = current->nsproxy->net_ns;
441b14878ccSVlad Yasevich 	struct ctl_table tbl;
442b14878ccSVlad Yasevich 	int new_value, ret;
443b14878ccSVlad Yasevich 
444b14878ccSVlad Yasevich 	memset(&tbl, 0, sizeof(struct ctl_table));
445b14878ccSVlad Yasevich 	tbl.maxlen = sizeof(unsigned int);
446b14878ccSVlad Yasevich 
447b14878ccSVlad Yasevich 	if (write)
448b14878ccSVlad Yasevich 		tbl.data = &new_value;
449b14878ccSVlad Yasevich 	else
450b14878ccSVlad Yasevich 		tbl.data = &net->sctp.auth_enable;
451b14878ccSVlad Yasevich 
452b14878ccSVlad Yasevich 	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
45324599e61SDaniel Borkmann 	if (write && ret == 0) {
454b14878ccSVlad Yasevich 		struct sock *sk = net->sctp.ctl_sock;
455b14878ccSVlad Yasevich 
456b14878ccSVlad Yasevich 		net->sctp.auth_enable = new_value;
457b14878ccSVlad Yasevich 		/* Update the value in the control socket */
458b14878ccSVlad Yasevich 		lock_sock(sk);
459b14878ccSVlad Yasevich 		sctp_sk(sk)->ep->auth_enable = new_value;
460b14878ccSVlad Yasevich 		release_sock(sk);
461b14878ccSVlad Yasevich 	}
462b14878ccSVlad Yasevich 
463b14878ccSVlad Yasevich 	return ret;
464b14878ccSVlad Yasevich }
465b14878ccSVlad Yasevich 
466ebb7e95dSEric W. Biederman int sctp_sysctl_net_register(struct net *net)
467ebb7e95dSEric W. Biederman {
468eb9f3705Swangweidong 	struct ctl_table *table;
469e1fc3b14SEric W. Biederman 	int i;
470ebb7e95dSEric W. Biederman 
471ebb7e95dSEric W. Biederman 	table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL);
472ebb7e95dSEric W. Biederman 	if (!table)
473ebb7e95dSEric W. Biederman 		return -ENOMEM;
474ebb7e95dSEric W. Biederman 
475e1fc3b14SEric W. Biederman 	for (i = 0; table[i].data; i++)
476e1fc3b14SEric W. Biederman 		table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp;
477e1fc3b14SEric W. Biederman 
478ebb7e95dSEric W. Biederman 	net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table);
479f66138c8Swangweidong 	if (net->sctp.sysctl_header == NULL) {
480f66138c8Swangweidong 		kfree(table);
481f66138c8Swangweidong 		return -ENOMEM;
482f66138c8Swangweidong 	}
483ebb7e95dSEric W. Biederman 	return 0;
484ebb7e95dSEric W. Biederman }
485ebb7e95dSEric W. Biederman 
486ebb7e95dSEric W. Biederman void sctp_sysctl_net_unregister(struct net *net)
487ebb7e95dSEric W. Biederman {
4885f19d121SVlad Yasevich 	struct ctl_table *table;
4895f19d121SVlad Yasevich 
4905f19d121SVlad Yasevich 	table = net->sctp.sysctl_header->ctl_table_arg;
491ebb7e95dSEric W. Biederman 	unregister_net_sysctl_table(net->sctp.sysctl_header);
4925f19d121SVlad Yasevich 	kfree(table);
493ebb7e95dSEric W. Biederman }
494ebb7e95dSEric W. Biederman 
4951da177e4SLinus Torvalds static struct ctl_table_header *sctp_sysctl_header;
4961da177e4SLinus Torvalds 
4971da177e4SLinus Torvalds /* Sysctl registration.  */
4981da177e4SLinus Torvalds void sctp_sysctl_register(void)
4991da177e4SLinus Torvalds {
500ec8f23ceSEric W. Biederman 	sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table);
5011da177e4SLinus Torvalds }
5021da177e4SLinus Torvalds 
5031da177e4SLinus Torvalds /* Sysctl deregistration.  */
5041da177e4SLinus Torvalds void sctp_sysctl_unregister(void)
5051da177e4SLinus Torvalds {
5065dd3df10SEric W. Biederman 	unregister_net_sysctl_table(sctp_sysctl_header);
5071da177e4SLinus Torvalds }
508