xref: /openbmc/linux/net/sctp/sysctl.c (revision c899710f)
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 timer_max = 86400000; /* ms in one day */
29d48e074dSJean-Mickael Guerin static int sack_timer_min = 1;
30d48e074dSJean-Mickael Guerin static int sack_timer_max = 500;
31701ef3e6SXin Long static int addr_scope_max = SCTP_SCOPE_POLICY_MAX;
3290f2f531SVlad Yasevich static int rwnd_scale_max = 16;
33b58537a1SDaniel Borkmann static int rto_alpha_min = 0;
34b58537a1SDaniel Borkmann static int rto_beta_min = 0;
35b58537a1SDaniel Borkmann static int rto_alpha_max = 1000;
36b58537a1SDaniel Borkmann static int rto_beta_max = 1000;
37aef587beSXin Long static int pf_expose_max = SCTP_PF_EXPOSE_MAX;
3834515e94SXin Long static int ps_retrans_max = SCTP_PS_RETRANS_MAX;
39e8a3001cSXin Long static int udp_port_max = 65535;
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,
4732927393SChristoph Hellwig 				 void *buffer, size_t *lenp, loff_t *ppos);
484f3fdf3bSwangweidong static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
4932927393SChristoph Hellwig 				void *buffer, size_t *lenp, loff_t *ppos);
5032927393SChristoph Hellwig static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, void *buffer,
5132927393SChristoph Hellwig 				size_t *lenp, loff_t *ppos);
52046c052bSXin Long static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write, void *buffer,
53046c052bSXin Long 				 size_t *lenp, loff_t *ppos);
54b58537a1SDaniel Borkmann static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
5532927393SChristoph Hellwig 				   void *buffer, size_t *lenp, loff_t *ppos);
56b14878ccSVlad Yasevich static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
5732927393SChristoph Hellwig 			     void *buffer, size_t *lenp, loff_t *ppos);
58d1e462a7SXin Long static int proc_sctp_do_probe_interval(struct ctl_table *ctl, int write,
59d1e462a7SXin Long 				       void *buffer, size_t *lenp, loff_t *ppos);
604f3fdf3bSwangweidong 
61fe2c6338SJoe Perches static struct ctl_table sctp_table[] = {
621da177e4SLinus Torvalds 	{
634d93df0aSNeil Horman 		.procname	= "sctp_mem",
644d93df0aSNeil Horman 		.data		= &sysctl_sctp_mem,
654d93df0aSNeil Horman 		.maxlen		= sizeof(sysctl_sctp_mem),
664d93df0aSNeil Horman 		.mode		= 0644,
678d987e5cSEric Dumazet 		.proc_handler	= proc_doulongvec_minmax
684d93df0aSNeil Horman 	},
694d93df0aSNeil Horman 	{
704d93df0aSNeil Horman 		.procname	= "sctp_rmem",
714d93df0aSNeil Horman 		.data		= &sysctl_sctp_rmem,
724d93df0aSNeil Horman 		.maxlen		= sizeof(sysctl_sctp_rmem),
734d93df0aSNeil Horman 		.mode		= 0644,
746d9f239aSAlexey Dobriyan 		.proc_handler	= proc_dointvec,
754d93df0aSNeil Horman 	},
764d93df0aSNeil Horman 	{
774d93df0aSNeil Horman 		.procname	= "sctp_wmem",
784d93df0aSNeil Horman 		.data		= &sysctl_sctp_wmem,
794d93df0aSNeil Horman 		.maxlen		= sizeof(sysctl_sctp_wmem),
804d93df0aSNeil Horman 		.mode		= 0644,
816d9f239aSAlexey Dobriyan 		.proc_handler	= proc_dointvec,
824d93df0aSNeil Horman 	},
83e1fc3b14SEric W. Biederman 
84e1fc3b14SEric W. Biederman 	{ /* sentinel */ }
85e1fc3b14SEric W. Biederman };
86e1fc3b14SEric W. Biederman 
87da05ceccSFiro Yang /* The following index defines are used in sctp_sysctl_net_register().
88da05ceccSFiro Yang  * If you add new items to the sctp_net_table, please ensure that
89da05ceccSFiro Yang  * the index values of these defines hold the same meaning indicated by
90da05ceccSFiro Yang  * their macro names when they appear in sctp_net_table.
91da05ceccSFiro Yang  */
92da05ceccSFiro Yang #define SCTP_RTO_MIN_IDX       0
93da05ceccSFiro Yang #define SCTP_RTO_MAX_IDX       1
94da05ceccSFiro Yang #define SCTP_PF_RETRANS_IDX    2
95da05ceccSFiro Yang #define SCTP_PS_RETRANS_IDX    3
96da05ceccSFiro Yang 
97fe2c6338SJoe Perches static struct ctl_table sctp_net_table[] = {
98da05ceccSFiro Yang 	[SCTP_RTO_MIN_IDX] = {
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,
104eec4844fSMatteo Croce 		.extra1         = SYSCTL_ONE,
1054f3fdf3bSwangweidong 		.extra2         = &init_net.sctp.rto_max
106e1fc3b14SEric W. Biederman 	},
107da05ceccSFiro Yang 	[SCTP_RTO_MAX_IDX] =  {
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 	},
116da05ceccSFiro Yang 	[SCTP_PF_RETRANS_IDX] = {
117da05ceccSFiro Yang 		.procname	= "pf_retrans",
118da05ceccSFiro Yang 		.data		= &init_net.sctp.pf_retrans,
119da05ceccSFiro Yang 		.maxlen		= sizeof(int),
120da05ceccSFiro Yang 		.mode		= 0644,
121da05ceccSFiro Yang 		.proc_handler	= proc_dointvec_minmax,
122da05ceccSFiro Yang 		.extra1		= SYSCTL_ZERO,
123da05ceccSFiro Yang 		.extra2		= &init_net.sctp.ps_retrans,
124da05ceccSFiro Yang 	},
125da05ceccSFiro Yang 	[SCTP_PS_RETRANS_IDX] = {
126da05ceccSFiro Yang 		.procname	= "ps_retrans",
127da05ceccSFiro Yang 		.data		= &init_net.sctp.ps_retrans,
128da05ceccSFiro Yang 		.maxlen		= sizeof(int),
129da05ceccSFiro Yang 		.mode		= 0644,
130da05ceccSFiro Yang 		.proc_handler	= proc_dointvec_minmax,
131da05ceccSFiro Yang 		.extra1		= &init_net.sctp.pf_retrans,
132da05ceccSFiro Yang 		.extra2		= &ps_retrans_max,
133da05ceccSFiro Yang 	},
134da05ceccSFiro Yang 	{
135da05ceccSFiro Yang 		.procname	= "rto_initial",
136da05ceccSFiro Yang 		.data		= &init_net.sctp.rto_initial,
137da05ceccSFiro Yang 		.maxlen		= sizeof(unsigned int),
138da05ceccSFiro Yang 		.mode		= 0644,
139da05ceccSFiro Yang 		.proc_handler	= proc_dointvec_minmax,
140da05ceccSFiro Yang 		.extra1         = SYSCTL_ONE,
141da05ceccSFiro Yang 		.extra2         = &timer_max
142da05ceccSFiro Yang 	},
143e1fc3b14SEric W. Biederman 	{
144e1fc3b14SEric W. Biederman 		.procname	= "rto_alpha_exp_divisor",
145e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.rto_alpha,
146e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
147b58537a1SDaniel Borkmann 		.mode		= 0644,
148b58537a1SDaniel Borkmann 		.proc_handler	= proc_sctp_do_alpha_beta,
149b58537a1SDaniel Borkmann 		.extra1		= &rto_alpha_min,
150b58537a1SDaniel Borkmann 		.extra2		= &rto_alpha_max,
151e1fc3b14SEric W. Biederman 	},
152e1fc3b14SEric W. Biederman 	{
153e1fc3b14SEric W. Biederman 		.procname	= "rto_beta_exp_divisor",
154e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.rto_beta,
155e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
156b58537a1SDaniel Borkmann 		.mode		= 0644,
157b58537a1SDaniel Borkmann 		.proc_handler	= proc_sctp_do_alpha_beta,
158b58537a1SDaniel Borkmann 		.extra1		= &rto_beta_min,
159b58537a1SDaniel Borkmann 		.extra2		= &rto_beta_max,
160e1fc3b14SEric W. Biederman 	},
161e1fc3b14SEric W. Biederman 	{
162e1fc3b14SEric W. Biederman 		.procname	= "max_burst",
163e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.max_burst,
164e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
165e1fc3b14SEric W. Biederman 		.mode		= 0644,
166e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec_minmax,
167eec4844fSMatteo Croce 		.extra1		= SYSCTL_ZERO,
168eec4844fSMatteo Croce 		.extra2		= SYSCTL_INT_MAX,
169e1fc3b14SEric W. Biederman 	},
170e1fc3b14SEric W. Biederman 	{
171e1fc3b14SEric W. Biederman 		.procname	= "cookie_preserve_enable",
172e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.cookie_preserve_enable,
173e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
174e1fc3b14SEric W. Biederman 		.mode		= 0644,
175e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec,
176e1fc3b14SEric W. Biederman 	},
177e1fc3b14SEric W. Biederman 	{
1783c68198eSNeil Horman 		.procname	= "cookie_hmac_alg",
17922a1f514Swangweidong 		.data		= &init_net.sctp.sctp_hmac_alg,
1803c68198eSNeil Horman 		.maxlen		= 8,
1813c68198eSNeil Horman 		.mode		= 0644,
1823c68198eSNeil Horman 		.proc_handler	= proc_sctp_do_hmac_alg,
1833c68198eSNeil Horman 	},
1843c68198eSNeil Horman 	{
185e1fc3b14SEric W. Biederman 		.procname	= "valid_cookie_life",
186e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.valid_cookie_life,
187e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(unsigned int),
188e1fc3b14SEric W. Biederman 		.mode		= 0644,
189e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec_minmax,
190eec4844fSMatteo Croce 		.extra1         = SYSCTL_ONE,
191e1fc3b14SEric W. Biederman 		.extra2         = &timer_max
192e1fc3b14SEric W. Biederman 	},
193e1fc3b14SEric W. Biederman 	{
194e1fc3b14SEric W. Biederman 		.procname	= "sack_timeout",
195e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.sack_timeout,
196e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
197e1fc3b14SEric W. Biederman 		.mode		= 0644,
198e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec_minmax,
199e1fc3b14SEric W. Biederman 		.extra1         = &sack_timer_min,
200e1fc3b14SEric W. Biederman 		.extra2         = &sack_timer_max,
201e1fc3b14SEric W. Biederman 	},
202e1fc3b14SEric W. Biederman 	{
203e1fc3b14SEric W. Biederman 		.procname	= "hb_interval",
204e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.hb_interval,
205e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(unsigned int),
206e1fc3b14SEric W. Biederman 		.mode		= 0644,
207e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec_minmax,
208eec4844fSMatteo Croce 		.extra1         = SYSCTL_ONE,
209e1fc3b14SEric W. Biederman 		.extra2         = &timer_max
210e1fc3b14SEric W. Biederman 	},
211e1fc3b14SEric W. Biederman 	{
212e1fc3b14SEric W. Biederman 		.procname	= "association_max_retrans",
213e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.max_retrans_association,
214e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
215e1fc3b14SEric W. Biederman 		.mode		= 0644,
216e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec_minmax,
217eec4844fSMatteo Croce 		.extra1		= SYSCTL_ONE,
218eec4844fSMatteo Croce 		.extra2		= SYSCTL_INT_MAX,
219e1fc3b14SEric W. Biederman 	},
220e1fc3b14SEric W. Biederman 	{
221e1fc3b14SEric W. Biederman 		.procname	= "path_max_retrans",
222e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.max_retrans_path,
223e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
224e1fc3b14SEric W. Biederman 		.mode		= 0644,
225e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec_minmax,
226eec4844fSMatteo Croce 		.extra1		= SYSCTL_ONE,
227eec4844fSMatteo Croce 		.extra2		= SYSCTL_INT_MAX,
228e1fc3b14SEric W. Biederman 	},
229e1fc3b14SEric W. Biederman 	{
230e1fc3b14SEric W. Biederman 		.procname	= "max_init_retransmits",
231e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.max_retrans_init,
232e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
233e1fc3b14SEric W. Biederman 		.mode		= 0644,
234e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec_minmax,
235eec4844fSMatteo Croce 		.extra1		= SYSCTL_ONE,
236eec4844fSMatteo Croce 		.extra2		= SYSCTL_INT_MAX,
237e1fc3b14SEric W. Biederman 	},
238e1fc3b14SEric W. Biederman 	{
239e1fc3b14SEric W. Biederman 		.procname	= "sndbuf_policy",
240e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.sndbuf_policy,
241e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
242e1fc3b14SEric W. Biederman 		.mode		= 0644,
243e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec,
244e1fc3b14SEric W. Biederman 	},
245e1fc3b14SEric W. Biederman 	{
246e1fc3b14SEric W. Biederman 		.procname	= "rcvbuf_policy",
247e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.rcvbuf_policy,
248e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
249e1fc3b14SEric W. Biederman 		.mode		= 0644,
250e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec,
251e1fc3b14SEric W. Biederman 	},
252e1fc3b14SEric W. Biederman 	{
253e1fc3b14SEric W. Biederman 		.procname	= "default_auto_asconf",
254e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.default_auto_asconf,
255e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
256e1fc3b14SEric W. Biederman 		.mode		= 0644,
257e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec,
258e1fc3b14SEric W. Biederman 	},
259e1fc3b14SEric W. Biederman 	{
260e1fc3b14SEric W. Biederman 		.procname	= "addip_enable",
261e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.addip_enable,
262a29a5bd4SVlad Yasevich 		.maxlen		= sizeof(int),
263a29a5bd4SVlad Yasevich 		.mode		= 0644,
2646d9f239aSAlexey Dobriyan 		.proc_handler	= proc_dointvec,
265a29a5bd4SVlad Yasevich 	},
26673d9c4fdSVlad Yasevich 	{
26773d9c4fdSVlad Yasevich 		.procname	= "addip_noauth_enable",
268e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.addip_noauth,
269e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
270e1fc3b14SEric W. Biederman 		.mode		= 0644,
271e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec,
272e1fc3b14SEric W. Biederman 	},
273e1fc3b14SEric W. Biederman 	{
274e1fc3b14SEric W. Biederman 		.procname	= "prsctp_enable",
275e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.prsctp_enable,
276e1fc3b14SEric W. Biederman 		.maxlen		= sizeof(int),
277e1fc3b14SEric W. Biederman 		.mode		= 0644,
278e1fc3b14SEric W. Biederman 		.proc_handler	= proc_dointvec,
279e1fc3b14SEric W. Biederman 	},
280e1fc3b14SEric W. Biederman 	{
281c0d8bab6SXin Long 		.procname	= "reconf_enable",
282c0d8bab6SXin Long 		.data		= &init_net.sctp.reconf_enable,
283c0d8bab6SXin Long 		.maxlen		= sizeof(int),
284c0d8bab6SXin Long 		.mode		= 0644,
285c0d8bab6SXin Long 		.proc_handler	= proc_dointvec,
286c0d8bab6SXin Long 	},
287c0d8bab6SXin Long 	{
288e1fc3b14SEric W. Biederman 		.procname	= "auth_enable",
289e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.auth_enable,
29073d9c4fdSVlad Yasevich 		.maxlen		= sizeof(int),
29173d9c4fdSVlad Yasevich 		.mode		= 0644,
292b14878ccSVlad Yasevich 		.proc_handler	= proc_sctp_do_auth,
29373d9c4fdSVlad Yasevich 	},
29472388433SBhaskar Dutta 	{
295463118c3SXin Long 		.procname	= "intl_enable",
296463118c3SXin Long 		.data		= &init_net.sctp.intl_enable,
297463118c3SXin Long 		.maxlen		= sizeof(int),
298463118c3SXin Long 		.mode		= 0644,
299463118c3SXin Long 		.proc_handler	= proc_dointvec,
300463118c3SXin Long 	},
301463118c3SXin Long 	{
3022f5268a9SXin Long 		.procname	= "ecn_enable",
3032f5268a9SXin Long 		.data		= &init_net.sctp.ecn_enable,
3042f5268a9SXin Long 		.maxlen		= sizeof(int),
3052f5268a9SXin Long 		.mode		= 0644,
3062f5268a9SXin Long 		.proc_handler	= proc_dointvec,
3072f5268a9SXin Long 	},
3082f5268a9SXin Long 	{
309d1e462a7SXin Long 		.procname	= "plpmtud_probe_interval",
310d1e462a7SXin Long 		.data		= &init_net.sctp.probe_interval,
311d1e462a7SXin Long 		.maxlen		= sizeof(int),
312d1e462a7SXin Long 		.mode		= 0644,
313d1e462a7SXin Long 		.proc_handler	= proc_sctp_do_probe_interval,
314d1e462a7SXin Long 	},
315d1e462a7SXin Long 	{
316046c052bSXin Long 		.procname	= "udp_port",
317046c052bSXin Long 		.data		= &init_net.sctp.udp_port,
318046c052bSXin Long 		.maxlen		= sizeof(int),
319046c052bSXin Long 		.mode		= 0644,
320046c052bSXin Long 		.proc_handler	= proc_sctp_do_udp_port,
321046c052bSXin Long 		.extra1		= SYSCTL_ZERO,
322046c052bSXin Long 		.extra2		= &udp_port_max,
323046c052bSXin Long 	},
324046c052bSXin Long 	{
325e8a3001cSXin Long 		.procname	= "encap_port",
326e8a3001cSXin Long 		.data		= &init_net.sctp.encap_port,
327e8a3001cSXin Long 		.maxlen		= sizeof(int),
328e8a3001cSXin Long 		.mode		= 0644,
329b2540cdcSXin Long 		.proc_handler	= proc_dointvec_minmax,
330e8a3001cSXin Long 		.extra1		= SYSCTL_ZERO,
331e8a3001cSXin Long 		.extra2		= &udp_port_max,
332e8a3001cSXin Long 	},
333e8a3001cSXin Long 	{
33472388433SBhaskar Dutta 		.procname	= "addr_scope_policy",
335e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.scope_policy,
33672388433SBhaskar Dutta 		.maxlen		= sizeof(int),
33772388433SBhaskar Dutta 		.mode		= 0644,
3386d456111SEric W. Biederman 		.proc_handler	= proc_dointvec_minmax,
339eec4844fSMatteo Croce 		.extra1		= SYSCTL_ZERO,
34072388433SBhaskar Dutta 		.extra2		= &addr_scope_max,
34172388433SBhaskar Dutta 	},
34290f2f531SVlad Yasevich 	{
34390f2f531SVlad Yasevich 		.procname	= "rwnd_update_shift",
344e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.rwnd_upd_shift,
34590f2f531SVlad Yasevich 		.maxlen		= sizeof(int),
34690f2f531SVlad Yasevich 		.mode		= 0644,
34790f2f531SVlad Yasevich 		.proc_handler	= &proc_dointvec_minmax,
348eec4844fSMatteo Croce 		.extra1		= SYSCTL_ONE,
34990f2f531SVlad Yasevich 		.extra2		= &rwnd_scale_max,
35090f2f531SVlad Yasevich 	},
3512692ba61SXi Wang 	{
3522692ba61SXi Wang 		.procname	= "max_autoclose",
353e1fc3b14SEric W. Biederman 		.data		= &init_net.sctp.max_autoclose,
3542692ba61SXi Wang 		.maxlen		= sizeof(unsigned long),
3552692ba61SXi Wang 		.mode		= 0644,
3562692ba61SXi Wang 		.proc_handler	= &proc_doulongvec_minmax,
3572692ba61SXi Wang 		.extra1		= &max_autoclose_min,
3582692ba61SXi Wang 		.extra2		= &max_autoclose_max,
3592692ba61SXi Wang 	},
360b712d032SXin Long #ifdef CONFIG_NET_L3_MASTER_DEV
361b712d032SXin Long 	{
362b712d032SXin Long 		.procname	= "l3mdev_accept",
363b712d032SXin Long 		.data		= &init_net.sctp.l3mdev_accept,
364b712d032SXin Long 		.maxlen		= sizeof(int),
365b712d032SXin Long 		.mode		= 0644,
366b712d032SXin Long 		.proc_handler	= proc_dointvec_minmax,
367b712d032SXin Long 		.extra1		= SYSCTL_ZERO,
368b712d032SXin Long 		.extra2		= SYSCTL_ONE,
369b712d032SXin Long 	},
370b712d032SXin Long #endif
371566178f8SZhu Yanjun 	{
372566178f8SZhu Yanjun 		.procname	= "pf_enable",
373566178f8SZhu Yanjun 		.data		= &init_net.sctp.pf_enable,
374566178f8SZhu Yanjun 		.maxlen		= sizeof(int),
375566178f8SZhu Yanjun 		.mode		= 0644,
376566178f8SZhu Yanjun 		.proc_handler	= proc_dointvec,
377566178f8SZhu Yanjun 	},
378aef587beSXin Long 	{
379aef587beSXin Long 		.procname	= "pf_expose",
380aef587beSXin Long 		.data		= &init_net.sctp.pf_expose,
381aef587beSXin Long 		.maxlen		= sizeof(int),
382aef587beSXin Long 		.mode		= 0644,
383aef587beSXin Long 		.proc_handler	= proc_dointvec_minmax,
384aef587beSXin Long 		.extra1		= SYSCTL_ZERO,
385aef587beSXin Long 		.extra2		= &pf_expose_max,
386aef587beSXin Long 	},
38771acc0ddSDavid S. Miller 
388d7fc02c7SLinus Torvalds 	{ /* sentinel */ }
3891da177e4SLinus Torvalds };
3901da177e4SLinus Torvalds 
proc_sctp_do_hmac_alg(struct ctl_table * ctl,int write,void * buffer,size_t * lenp,loff_t * ppos)391b486b228Swangweidong static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
39232927393SChristoph Hellwig 				 void *buffer, size_t *lenp, loff_t *ppos)
3933c68198eSNeil Horman {
3943c68198eSNeil Horman 	struct net *net = current->nsproxy->net_ns;
395fe2c6338SJoe Perches 	struct ctl_table tbl;
396ff5e92c1SDaniel Borkmann 	bool changed = false;
3973c68198eSNeil Horman 	char *none = "none";
398320f1a4aSSasha Levin 	char tmp[8] = {0};
399ff5e92c1SDaniel Borkmann 	int ret;
4003c68198eSNeil Horman 
4013c68198eSNeil Horman 	memset(&tbl, 0, sizeof(struct ctl_table));
4023c68198eSNeil Horman 
4033c68198eSNeil Horman 	if (write) {
4043c68198eSNeil Horman 		tbl.data = tmp;
405ff5e92c1SDaniel Borkmann 		tbl.maxlen = sizeof(tmp);
4063c68198eSNeil Horman 	} else {
4073c68198eSNeil Horman 		tbl.data = net->sctp.sctp_hmac_alg ? : none;
4083c68198eSNeil Horman 		tbl.maxlen = strlen(tbl.data);
4093c68198eSNeil Horman 	}
4103c68198eSNeil Horman 
411ff5e92c1SDaniel Borkmann 	ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
412ff5e92c1SDaniel Borkmann 	if (write && ret == 0) {
4133c68198eSNeil Horman #ifdef CONFIG_CRYPTO_MD5
4143c68198eSNeil Horman 		if (!strncmp(tmp, "md5", 3)) {
4153c68198eSNeil Horman 			net->sctp.sctp_hmac_alg = "md5";
416ff5e92c1SDaniel Borkmann 			changed = true;
4173c68198eSNeil Horman 		}
4183c68198eSNeil Horman #endif
4193c68198eSNeil Horman #ifdef CONFIG_CRYPTO_SHA1
4203c68198eSNeil Horman 		if (!strncmp(tmp, "sha1", 4)) {
4213c68198eSNeil Horman 			net->sctp.sctp_hmac_alg = "sha1";
422ff5e92c1SDaniel Borkmann 			changed = true;
4233c68198eSNeil Horman 		}
4243c68198eSNeil Horman #endif
4253c68198eSNeil Horman 		if (!strncmp(tmp, "none", 4)) {
4263c68198eSNeil Horman 			net->sctp.sctp_hmac_alg = NULL;
427ff5e92c1SDaniel Borkmann 			changed = true;
4283c68198eSNeil Horman 		}
4293c68198eSNeil Horman 		if (!changed)
4303c68198eSNeil Horman 			ret = -EINVAL;
4313c68198eSNeil Horman 	}
4323c68198eSNeil Horman 
4333c68198eSNeil Horman 	return ret;
4343c68198eSNeil Horman }
4353c68198eSNeil Horman 
proc_sctp_do_rto_min(struct ctl_table * ctl,int write,void * buffer,size_t * lenp,loff_t * ppos)4364f3fdf3bSwangweidong static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
43732927393SChristoph Hellwig 				void *buffer, size_t *lenp, loff_t *ppos)
4384f3fdf3bSwangweidong {
4394f3fdf3bSwangweidong 	struct net *net = current->nsproxy->net_ns;
4404f3fdf3bSwangweidong 	unsigned int min = *(unsigned int *) ctl->extra1;
4414f3fdf3bSwangweidong 	unsigned int max = *(unsigned int *) ctl->extra2;
442ff5e92c1SDaniel Borkmann 	struct ctl_table tbl;
443ff5e92c1SDaniel Borkmann 	int ret, new_value;
4444f3fdf3bSwangweidong 
4454f3fdf3bSwangweidong 	memset(&tbl, 0, sizeof(struct ctl_table));
4464f3fdf3bSwangweidong 	tbl.maxlen = sizeof(unsigned int);
4474f3fdf3bSwangweidong 
4484f3fdf3bSwangweidong 	if (write)
4494f3fdf3bSwangweidong 		tbl.data = &new_value;
4504f3fdf3bSwangweidong 	else
4514f3fdf3bSwangweidong 		tbl.data = &net->sctp.rto_min;
452ff5e92c1SDaniel Borkmann 
4534f3fdf3bSwangweidong 	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
454ff5e92c1SDaniel Borkmann 	if (write && ret == 0) {
455ff5e92c1SDaniel Borkmann 		if (new_value > max || new_value < min)
4564f3fdf3bSwangweidong 			return -EINVAL;
457ff5e92c1SDaniel Borkmann 
4584f3fdf3bSwangweidong 		net->sctp.rto_min = new_value;
4594f3fdf3bSwangweidong 	}
460ff5e92c1SDaniel Borkmann 
4614f3fdf3bSwangweidong 	return ret;
4624f3fdf3bSwangweidong }
4634f3fdf3bSwangweidong 
proc_sctp_do_rto_max(struct ctl_table * ctl,int write,void * buffer,size_t * lenp,loff_t * ppos)4644f3fdf3bSwangweidong static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
46532927393SChristoph Hellwig 				void *buffer, size_t *lenp, loff_t *ppos)
4664f3fdf3bSwangweidong {
4674f3fdf3bSwangweidong 	struct net *net = current->nsproxy->net_ns;
4684f3fdf3bSwangweidong 	unsigned int min = *(unsigned int *) ctl->extra1;
4694f3fdf3bSwangweidong 	unsigned int max = *(unsigned int *) ctl->extra2;
470ff5e92c1SDaniel Borkmann 	struct ctl_table tbl;
471ff5e92c1SDaniel Borkmann 	int ret, new_value;
4724f3fdf3bSwangweidong 
4734f3fdf3bSwangweidong 	memset(&tbl, 0, sizeof(struct ctl_table));
4744f3fdf3bSwangweidong 	tbl.maxlen = sizeof(unsigned int);
4754f3fdf3bSwangweidong 
4764f3fdf3bSwangweidong 	if (write)
4774f3fdf3bSwangweidong 		tbl.data = &new_value;
4784f3fdf3bSwangweidong 	else
4794f3fdf3bSwangweidong 		tbl.data = &net->sctp.rto_max;
480ff5e92c1SDaniel Borkmann 
4814f3fdf3bSwangweidong 	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
482ff5e92c1SDaniel Borkmann 	if (write && ret == 0) {
483ff5e92c1SDaniel Borkmann 		if (new_value > max || new_value < min)
4844f3fdf3bSwangweidong 			return -EINVAL;
485ff5e92c1SDaniel Borkmann 
4864f3fdf3bSwangweidong 		net->sctp.rto_max = new_value;
4874f3fdf3bSwangweidong 	}
488ff5e92c1SDaniel Borkmann 
4894f3fdf3bSwangweidong 	return ret;
4904f3fdf3bSwangweidong }
4914f3fdf3bSwangweidong 
proc_sctp_do_alpha_beta(struct ctl_table * ctl,int write,void * buffer,size_t * lenp,loff_t * ppos)492b58537a1SDaniel Borkmann static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
49332927393SChristoph Hellwig 				   void *buffer, size_t *lenp, loff_t *ppos)
494b58537a1SDaniel Borkmann {
495eaea2da7SDaniel Borkmann 	if (write)
496b58537a1SDaniel Borkmann 		pr_warn_once("Changing rto_alpha or rto_beta may lead to "
497b58537a1SDaniel Borkmann 			     "suboptimal rtt/srtt estimations!\n");
498b58537a1SDaniel Borkmann 
499b58537a1SDaniel Borkmann 	return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos);
500b58537a1SDaniel Borkmann }
501b58537a1SDaniel Borkmann 
proc_sctp_do_auth(struct ctl_table * ctl,int write,void * buffer,size_t * lenp,loff_t * ppos)502b14878ccSVlad Yasevich static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
50332927393SChristoph Hellwig 			     void *buffer, size_t *lenp, loff_t *ppos)
504b14878ccSVlad Yasevich {
505b14878ccSVlad Yasevich 	struct net *net = current->nsproxy->net_ns;
506b14878ccSVlad Yasevich 	struct ctl_table tbl;
507b14878ccSVlad Yasevich 	int new_value, ret;
508b14878ccSVlad Yasevich 
509b14878ccSVlad Yasevich 	memset(&tbl, 0, sizeof(struct ctl_table));
510b14878ccSVlad Yasevich 	tbl.maxlen = sizeof(unsigned int);
511b14878ccSVlad Yasevich 
512b14878ccSVlad Yasevich 	if (write)
513b14878ccSVlad Yasevich 		tbl.data = &new_value;
514b14878ccSVlad Yasevich 	else
515b14878ccSVlad Yasevich 		tbl.data = &net->sctp.auth_enable;
516b14878ccSVlad Yasevich 
517b14878ccSVlad Yasevich 	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
51824599e61SDaniel Borkmann 	if (write && ret == 0) {
519b14878ccSVlad Yasevich 		struct sock *sk = net->sctp.ctl_sock;
520b14878ccSVlad Yasevich 
521b14878ccSVlad Yasevich 		net->sctp.auth_enable = new_value;
522b14878ccSVlad Yasevich 		/* Update the value in the control socket */
523b14878ccSVlad Yasevich 		lock_sock(sk);
524b14878ccSVlad Yasevich 		sctp_sk(sk)->ep->auth_enable = new_value;
525b14878ccSVlad Yasevich 		release_sock(sk);
526b14878ccSVlad Yasevich 	}
527b14878ccSVlad Yasevich 
528b14878ccSVlad Yasevich 	return ret;
529b14878ccSVlad Yasevich }
530b14878ccSVlad Yasevich 
proc_sctp_do_udp_port(struct ctl_table * ctl,int write,void * buffer,size_t * lenp,loff_t * ppos)531046c052bSXin Long static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write,
532046c052bSXin Long 				 void *buffer, size_t *lenp, loff_t *ppos)
533046c052bSXin Long {
534046c052bSXin Long 	struct net *net = current->nsproxy->net_ns;
535046c052bSXin Long 	unsigned int min = *(unsigned int *)ctl->extra1;
536046c052bSXin Long 	unsigned int max = *(unsigned int *)ctl->extra2;
537046c052bSXin Long 	struct ctl_table tbl;
538046c052bSXin Long 	int ret, new_value;
539046c052bSXin Long 
540046c052bSXin Long 	memset(&tbl, 0, sizeof(struct ctl_table));
541046c052bSXin Long 	tbl.maxlen = sizeof(unsigned int);
542046c052bSXin Long 
543046c052bSXin Long 	if (write)
544046c052bSXin Long 		tbl.data = &new_value;
545046c052bSXin Long 	else
546046c052bSXin Long 		tbl.data = &net->sctp.udp_port;
547046c052bSXin Long 
548046c052bSXin Long 	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
549046c052bSXin Long 	if (write && ret == 0) {
550046c052bSXin Long 		struct sock *sk = net->sctp.ctl_sock;
551046c052bSXin Long 
552046c052bSXin Long 		if (new_value > max || new_value < min)
553046c052bSXin Long 			return -EINVAL;
554046c052bSXin Long 
555046c052bSXin Long 		net->sctp.udp_port = new_value;
556046c052bSXin Long 		sctp_udp_sock_stop(net);
557046c052bSXin Long 		if (new_value) {
558046c052bSXin Long 			ret = sctp_udp_sock_start(net);
559046c052bSXin Long 			if (ret)
560046c052bSXin Long 				net->sctp.udp_port = 0;
561046c052bSXin Long 		}
562046c052bSXin Long 
563046c052bSXin Long 		/* Update the value in the control socket */
564046c052bSXin Long 		lock_sock(sk);
565046c052bSXin Long 		sctp_sk(sk)->udp_port = htons(net->sctp.udp_port);
566046c052bSXin Long 		release_sock(sk);
567046c052bSXin Long 	}
568046c052bSXin Long 
569046c052bSXin Long 	return ret;
570046c052bSXin Long }
571046c052bSXin Long 
proc_sctp_do_probe_interval(struct ctl_table * ctl,int write,void * buffer,size_t * lenp,loff_t * ppos)572d1e462a7SXin Long static int proc_sctp_do_probe_interval(struct ctl_table *ctl, int write,
573d1e462a7SXin Long 				       void *buffer, size_t *lenp, loff_t *ppos)
574d1e462a7SXin Long {
575d1e462a7SXin Long 	struct net *net = current->nsproxy->net_ns;
576d1e462a7SXin Long 	struct ctl_table tbl;
577d1e462a7SXin Long 	int ret, new_value;
578d1e462a7SXin Long 
579d1e462a7SXin Long 	memset(&tbl, 0, sizeof(struct ctl_table));
580d1e462a7SXin Long 	tbl.maxlen = sizeof(unsigned int);
581d1e462a7SXin Long 
582d1e462a7SXin Long 	if (write)
583d1e462a7SXin Long 		tbl.data = &new_value;
584d1e462a7SXin Long 	else
585d1e462a7SXin Long 		tbl.data = &net->sctp.probe_interval;
586d1e462a7SXin Long 
587d1e462a7SXin Long 	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
588d1e462a7SXin Long 	if (write && ret == 0) {
589d1e462a7SXin Long 		if (new_value && new_value < SCTP_PROBE_TIMER_MIN)
590d1e462a7SXin Long 			return -EINVAL;
591d1e462a7SXin Long 
592d1e462a7SXin Long 		net->sctp.probe_interval = new_value;
593d1e462a7SXin Long 	}
594d1e462a7SXin Long 
595d1e462a7SXin Long 	return ret;
596d1e462a7SXin Long }
597d1e462a7SXin Long 
sctp_sysctl_net_register(struct net * net)598ebb7e95dSEric W. Biederman int sctp_sysctl_net_register(struct net *net)
599ebb7e95dSEric W. Biederman {
600eb9f3705Swangweidong 	struct ctl_table *table;
601e1fc3b14SEric W. Biederman 	int i;
602ebb7e95dSEric W. Biederman 
603ebb7e95dSEric W. Biederman 	table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL);
604ebb7e95dSEric W. Biederman 	if (!table)
605ebb7e95dSEric W. Biederman 		return -ENOMEM;
606ebb7e95dSEric W. Biederman 
607e1fc3b14SEric W. Biederman 	for (i = 0; table[i].data; i++)
608e1fc3b14SEric W. Biederman 		table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp;
609e1fc3b14SEric W. Biederman 
610da05ceccSFiro Yang 	table[SCTP_RTO_MIN_IDX].extra2 = &net->sctp.rto_max;
611da05ceccSFiro Yang 	table[SCTP_RTO_MAX_IDX].extra1 = &net->sctp.rto_min;
612da05ceccSFiro Yang 	table[SCTP_PF_RETRANS_IDX].extra2 = &net->sctp.ps_retrans;
613da05ceccSFiro Yang 	table[SCTP_PS_RETRANS_IDX].extra1 = &net->sctp.pf_retrans;
614da05ceccSFiro Yang 
615*c899710fSJoel Granados 	net->sctp.sysctl_header = register_net_sysctl_sz(net, "net/sctp",
616*c899710fSJoel Granados 							 table,
617*c899710fSJoel Granados 							 ARRAY_SIZE(sctp_net_table));
618f66138c8Swangweidong 	if (net->sctp.sysctl_header == NULL) {
619f66138c8Swangweidong 		kfree(table);
620f66138c8Swangweidong 		return -ENOMEM;
621f66138c8Swangweidong 	}
622ebb7e95dSEric W. Biederman 	return 0;
623ebb7e95dSEric W. Biederman }
624ebb7e95dSEric W. Biederman 
sctp_sysctl_net_unregister(struct net * net)625ebb7e95dSEric W. Biederman void sctp_sysctl_net_unregister(struct net *net)
626ebb7e95dSEric W. Biederman {
6275f19d121SVlad Yasevich 	struct ctl_table *table;
6285f19d121SVlad Yasevich 
6295f19d121SVlad Yasevich 	table = net->sctp.sysctl_header->ctl_table_arg;
630ebb7e95dSEric W. Biederman 	unregister_net_sysctl_table(net->sctp.sysctl_header);
6315f19d121SVlad Yasevich 	kfree(table);
632ebb7e95dSEric W. Biederman }
633ebb7e95dSEric W. Biederman 
6341da177e4SLinus Torvalds static struct ctl_table_header *sctp_sysctl_header;
6351da177e4SLinus Torvalds 
6361da177e4SLinus Torvalds /* Sysctl registration.  */
sctp_sysctl_register(void)6371da177e4SLinus Torvalds void sctp_sysctl_register(void)
6381da177e4SLinus Torvalds {
639ec8f23ceSEric W. Biederman 	sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table);
6401da177e4SLinus Torvalds }
6411da177e4SLinus Torvalds 
6421da177e4SLinus Torvalds /* Sysctl deregistration.  */
sctp_sysctl_unregister(void)6431da177e4SLinus Torvalds void sctp_sysctl_unregister(void)
6441da177e4SLinus Torvalds {
6455dd3df10SEric W. Biederman 	unregister_net_sysctl_table(sctp_sysctl_header);
6461da177e4SLinus Torvalds }
647