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