162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/* SCTP kernel implementation
362306a36Sopenharmony_ci * (C) Copyright IBM Corp. 2002, 2004
462306a36Sopenharmony_ci * Copyright (c) 2002 Intel Corp.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * This file is part of the SCTP kernel implementation
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * Sysctl related interfaces for SCTP.
962306a36Sopenharmony_ci *
1062306a36Sopenharmony_ci * Please send any bug reports or fixes you make to the
1162306a36Sopenharmony_ci * email address(es):
1262306a36Sopenharmony_ci *    lksctp developers <linux-sctp@vger.kernel.org>
1362306a36Sopenharmony_ci *
1462306a36Sopenharmony_ci * Written or modified by:
1562306a36Sopenharmony_ci *    Mingqin Liu           <liuming@us.ibm.com>
1662306a36Sopenharmony_ci *    Jon Grimm             <jgrimm@us.ibm.com>
1762306a36Sopenharmony_ci *    Ardelle Fan           <ardelle.fan@intel.com>
1862306a36Sopenharmony_ci *    Ryan Layer            <rmlayer@us.ibm.com>
1962306a36Sopenharmony_ci *    Sridhar Samudrala     <sri@us.ibm.com>
2062306a36Sopenharmony_ci */
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#include <net/sctp/structs.h>
2562306a36Sopenharmony_ci#include <net/sctp/sctp.h>
2662306a36Sopenharmony_ci#include <linux/sysctl.h>
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_cistatic int timer_max = 86400000; /* ms in one day */
2962306a36Sopenharmony_cistatic int sack_timer_min = 1;
3062306a36Sopenharmony_cistatic int sack_timer_max = 500;
3162306a36Sopenharmony_cistatic int addr_scope_max = SCTP_SCOPE_POLICY_MAX;
3262306a36Sopenharmony_cistatic int rwnd_scale_max = 16;
3362306a36Sopenharmony_cistatic int rto_alpha_min = 0;
3462306a36Sopenharmony_cistatic int rto_beta_min = 0;
3562306a36Sopenharmony_cistatic int rto_alpha_max = 1000;
3662306a36Sopenharmony_cistatic int rto_beta_max = 1000;
3762306a36Sopenharmony_cistatic int pf_expose_max = SCTP_PF_EXPOSE_MAX;
3862306a36Sopenharmony_cistatic int ps_retrans_max = SCTP_PS_RETRANS_MAX;
3962306a36Sopenharmony_cistatic int udp_port_max = 65535;
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_cistatic unsigned long max_autoclose_min = 0;
4262306a36Sopenharmony_cistatic unsigned long max_autoclose_max =
4362306a36Sopenharmony_ci	(MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX)
4462306a36Sopenharmony_ci	? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ;
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_cistatic int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
4762306a36Sopenharmony_ci				 void *buffer, size_t *lenp, loff_t *ppos);
4862306a36Sopenharmony_cistatic int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
4962306a36Sopenharmony_ci				void *buffer, size_t *lenp, loff_t *ppos);
5062306a36Sopenharmony_cistatic int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, void *buffer,
5162306a36Sopenharmony_ci				size_t *lenp, loff_t *ppos);
5262306a36Sopenharmony_cistatic int proc_sctp_do_udp_port(struct ctl_table *ctl, int write, void *buffer,
5362306a36Sopenharmony_ci				 size_t *lenp, loff_t *ppos);
5462306a36Sopenharmony_cistatic int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
5562306a36Sopenharmony_ci				   void *buffer, size_t *lenp, loff_t *ppos);
5662306a36Sopenharmony_cistatic int proc_sctp_do_auth(struct ctl_table *ctl, int write,
5762306a36Sopenharmony_ci			     void *buffer, size_t *lenp, loff_t *ppos);
5862306a36Sopenharmony_cistatic int proc_sctp_do_probe_interval(struct ctl_table *ctl, int write,
5962306a36Sopenharmony_ci				       void *buffer, size_t *lenp, loff_t *ppos);
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_cistatic struct ctl_table sctp_table[] = {
6262306a36Sopenharmony_ci	{
6362306a36Sopenharmony_ci		.procname	= "sctp_mem",
6462306a36Sopenharmony_ci		.data		= &sysctl_sctp_mem,
6562306a36Sopenharmony_ci		.maxlen		= sizeof(sysctl_sctp_mem),
6662306a36Sopenharmony_ci		.mode		= 0644,
6762306a36Sopenharmony_ci		.proc_handler	= proc_doulongvec_minmax
6862306a36Sopenharmony_ci	},
6962306a36Sopenharmony_ci	{
7062306a36Sopenharmony_ci		.procname	= "sctp_rmem",
7162306a36Sopenharmony_ci		.data		= &sysctl_sctp_rmem,
7262306a36Sopenharmony_ci		.maxlen		= sizeof(sysctl_sctp_rmem),
7362306a36Sopenharmony_ci		.mode		= 0644,
7462306a36Sopenharmony_ci		.proc_handler	= proc_dointvec,
7562306a36Sopenharmony_ci	},
7662306a36Sopenharmony_ci	{
7762306a36Sopenharmony_ci		.procname	= "sctp_wmem",
7862306a36Sopenharmony_ci		.data		= &sysctl_sctp_wmem,
7962306a36Sopenharmony_ci		.maxlen		= sizeof(sysctl_sctp_wmem),
8062306a36Sopenharmony_ci		.mode		= 0644,
8162306a36Sopenharmony_ci		.proc_handler	= proc_dointvec,
8262306a36Sopenharmony_ci	},
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	{ /* sentinel */ }
8562306a36Sopenharmony_ci};
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci/* The following index defines are used in sctp_sysctl_net_register().
8862306a36Sopenharmony_ci * If you add new items to the sctp_net_table, please ensure that
8962306a36Sopenharmony_ci * the index values of these defines hold the same meaning indicated by
9062306a36Sopenharmony_ci * their macro names when they appear in sctp_net_table.
9162306a36Sopenharmony_ci */
9262306a36Sopenharmony_ci#define SCTP_RTO_MIN_IDX       0
9362306a36Sopenharmony_ci#define SCTP_RTO_MAX_IDX       1
9462306a36Sopenharmony_ci#define SCTP_PF_RETRANS_IDX    2
9562306a36Sopenharmony_ci#define SCTP_PS_RETRANS_IDX    3
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_cistatic struct ctl_table sctp_net_table[] = {
9862306a36Sopenharmony_ci	[SCTP_RTO_MIN_IDX] = {
9962306a36Sopenharmony_ci		.procname	= "rto_min",
10062306a36Sopenharmony_ci		.data		= &init_net.sctp.rto_min,
10162306a36Sopenharmony_ci		.maxlen		= sizeof(unsigned int),
10262306a36Sopenharmony_ci		.mode		= 0644,
10362306a36Sopenharmony_ci		.proc_handler	= proc_sctp_do_rto_min,
10462306a36Sopenharmony_ci		.extra1         = SYSCTL_ONE,
10562306a36Sopenharmony_ci		.extra2         = &init_net.sctp.rto_max
10662306a36Sopenharmony_ci	},
10762306a36Sopenharmony_ci	[SCTP_RTO_MAX_IDX] =  {
10862306a36Sopenharmony_ci		.procname	= "rto_max",
10962306a36Sopenharmony_ci		.data		= &init_net.sctp.rto_max,
11062306a36Sopenharmony_ci		.maxlen		= sizeof(unsigned int),
11162306a36Sopenharmony_ci		.mode		= 0644,
11262306a36Sopenharmony_ci		.proc_handler	= proc_sctp_do_rto_max,
11362306a36Sopenharmony_ci		.extra1         = &init_net.sctp.rto_min,
11462306a36Sopenharmony_ci		.extra2         = &timer_max
11562306a36Sopenharmony_ci	},
11662306a36Sopenharmony_ci	[SCTP_PF_RETRANS_IDX] = {
11762306a36Sopenharmony_ci		.procname	= "pf_retrans",
11862306a36Sopenharmony_ci		.data		= &init_net.sctp.pf_retrans,
11962306a36Sopenharmony_ci		.maxlen		= sizeof(int),
12062306a36Sopenharmony_ci		.mode		= 0644,
12162306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
12262306a36Sopenharmony_ci		.extra1		= SYSCTL_ZERO,
12362306a36Sopenharmony_ci		.extra2		= &init_net.sctp.ps_retrans,
12462306a36Sopenharmony_ci	},
12562306a36Sopenharmony_ci	[SCTP_PS_RETRANS_IDX] = {
12662306a36Sopenharmony_ci		.procname	= "ps_retrans",
12762306a36Sopenharmony_ci		.data		= &init_net.sctp.ps_retrans,
12862306a36Sopenharmony_ci		.maxlen		= sizeof(int),
12962306a36Sopenharmony_ci		.mode		= 0644,
13062306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
13162306a36Sopenharmony_ci		.extra1		= &init_net.sctp.pf_retrans,
13262306a36Sopenharmony_ci		.extra2		= &ps_retrans_max,
13362306a36Sopenharmony_ci	},
13462306a36Sopenharmony_ci	{
13562306a36Sopenharmony_ci		.procname	= "rto_initial",
13662306a36Sopenharmony_ci		.data		= &init_net.sctp.rto_initial,
13762306a36Sopenharmony_ci		.maxlen		= sizeof(unsigned int),
13862306a36Sopenharmony_ci		.mode		= 0644,
13962306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
14062306a36Sopenharmony_ci		.extra1         = SYSCTL_ONE,
14162306a36Sopenharmony_ci		.extra2         = &timer_max
14262306a36Sopenharmony_ci	},
14362306a36Sopenharmony_ci	{
14462306a36Sopenharmony_ci		.procname	= "rto_alpha_exp_divisor",
14562306a36Sopenharmony_ci		.data		= &init_net.sctp.rto_alpha,
14662306a36Sopenharmony_ci		.maxlen		= sizeof(int),
14762306a36Sopenharmony_ci		.mode		= 0644,
14862306a36Sopenharmony_ci		.proc_handler	= proc_sctp_do_alpha_beta,
14962306a36Sopenharmony_ci		.extra1		= &rto_alpha_min,
15062306a36Sopenharmony_ci		.extra2		= &rto_alpha_max,
15162306a36Sopenharmony_ci	},
15262306a36Sopenharmony_ci	{
15362306a36Sopenharmony_ci		.procname	= "rto_beta_exp_divisor",
15462306a36Sopenharmony_ci		.data		= &init_net.sctp.rto_beta,
15562306a36Sopenharmony_ci		.maxlen		= sizeof(int),
15662306a36Sopenharmony_ci		.mode		= 0644,
15762306a36Sopenharmony_ci		.proc_handler	= proc_sctp_do_alpha_beta,
15862306a36Sopenharmony_ci		.extra1		= &rto_beta_min,
15962306a36Sopenharmony_ci		.extra2		= &rto_beta_max,
16062306a36Sopenharmony_ci	},
16162306a36Sopenharmony_ci	{
16262306a36Sopenharmony_ci		.procname	= "max_burst",
16362306a36Sopenharmony_ci		.data		= &init_net.sctp.max_burst,
16462306a36Sopenharmony_ci		.maxlen		= sizeof(int),
16562306a36Sopenharmony_ci		.mode		= 0644,
16662306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
16762306a36Sopenharmony_ci		.extra1		= SYSCTL_ZERO,
16862306a36Sopenharmony_ci		.extra2		= SYSCTL_INT_MAX,
16962306a36Sopenharmony_ci	},
17062306a36Sopenharmony_ci	{
17162306a36Sopenharmony_ci		.procname	= "cookie_preserve_enable",
17262306a36Sopenharmony_ci		.data		= &init_net.sctp.cookie_preserve_enable,
17362306a36Sopenharmony_ci		.maxlen		= sizeof(int),
17462306a36Sopenharmony_ci		.mode		= 0644,
17562306a36Sopenharmony_ci		.proc_handler	= proc_dointvec,
17662306a36Sopenharmony_ci	},
17762306a36Sopenharmony_ci	{
17862306a36Sopenharmony_ci		.procname	= "cookie_hmac_alg",
17962306a36Sopenharmony_ci		.data		= &init_net.sctp.sctp_hmac_alg,
18062306a36Sopenharmony_ci		.maxlen		= 8,
18162306a36Sopenharmony_ci		.mode		= 0644,
18262306a36Sopenharmony_ci		.proc_handler	= proc_sctp_do_hmac_alg,
18362306a36Sopenharmony_ci	},
18462306a36Sopenharmony_ci	{
18562306a36Sopenharmony_ci		.procname	= "valid_cookie_life",
18662306a36Sopenharmony_ci		.data		= &init_net.sctp.valid_cookie_life,
18762306a36Sopenharmony_ci		.maxlen		= sizeof(unsigned int),
18862306a36Sopenharmony_ci		.mode		= 0644,
18962306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
19062306a36Sopenharmony_ci		.extra1         = SYSCTL_ONE,
19162306a36Sopenharmony_ci		.extra2         = &timer_max
19262306a36Sopenharmony_ci	},
19362306a36Sopenharmony_ci	{
19462306a36Sopenharmony_ci		.procname	= "sack_timeout",
19562306a36Sopenharmony_ci		.data		= &init_net.sctp.sack_timeout,
19662306a36Sopenharmony_ci		.maxlen		= sizeof(int),
19762306a36Sopenharmony_ci		.mode		= 0644,
19862306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
19962306a36Sopenharmony_ci		.extra1         = &sack_timer_min,
20062306a36Sopenharmony_ci		.extra2         = &sack_timer_max,
20162306a36Sopenharmony_ci	},
20262306a36Sopenharmony_ci	{
20362306a36Sopenharmony_ci		.procname	= "hb_interval",
20462306a36Sopenharmony_ci		.data		= &init_net.sctp.hb_interval,
20562306a36Sopenharmony_ci		.maxlen		= sizeof(unsigned int),
20662306a36Sopenharmony_ci		.mode		= 0644,
20762306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
20862306a36Sopenharmony_ci		.extra1         = SYSCTL_ONE,
20962306a36Sopenharmony_ci		.extra2         = &timer_max
21062306a36Sopenharmony_ci	},
21162306a36Sopenharmony_ci	{
21262306a36Sopenharmony_ci		.procname	= "association_max_retrans",
21362306a36Sopenharmony_ci		.data		= &init_net.sctp.max_retrans_association,
21462306a36Sopenharmony_ci		.maxlen		= sizeof(int),
21562306a36Sopenharmony_ci		.mode		= 0644,
21662306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
21762306a36Sopenharmony_ci		.extra1		= SYSCTL_ONE,
21862306a36Sopenharmony_ci		.extra2		= SYSCTL_INT_MAX,
21962306a36Sopenharmony_ci	},
22062306a36Sopenharmony_ci	{
22162306a36Sopenharmony_ci		.procname	= "path_max_retrans",
22262306a36Sopenharmony_ci		.data		= &init_net.sctp.max_retrans_path,
22362306a36Sopenharmony_ci		.maxlen		= sizeof(int),
22462306a36Sopenharmony_ci		.mode		= 0644,
22562306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
22662306a36Sopenharmony_ci		.extra1		= SYSCTL_ONE,
22762306a36Sopenharmony_ci		.extra2		= SYSCTL_INT_MAX,
22862306a36Sopenharmony_ci	},
22962306a36Sopenharmony_ci	{
23062306a36Sopenharmony_ci		.procname	= "max_init_retransmits",
23162306a36Sopenharmony_ci		.data		= &init_net.sctp.max_retrans_init,
23262306a36Sopenharmony_ci		.maxlen		= sizeof(int),
23362306a36Sopenharmony_ci		.mode		= 0644,
23462306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
23562306a36Sopenharmony_ci		.extra1		= SYSCTL_ONE,
23662306a36Sopenharmony_ci		.extra2		= SYSCTL_INT_MAX,
23762306a36Sopenharmony_ci	},
23862306a36Sopenharmony_ci	{
23962306a36Sopenharmony_ci		.procname	= "sndbuf_policy",
24062306a36Sopenharmony_ci		.data		= &init_net.sctp.sndbuf_policy,
24162306a36Sopenharmony_ci		.maxlen		= sizeof(int),
24262306a36Sopenharmony_ci		.mode		= 0644,
24362306a36Sopenharmony_ci		.proc_handler	= proc_dointvec,
24462306a36Sopenharmony_ci	},
24562306a36Sopenharmony_ci	{
24662306a36Sopenharmony_ci		.procname	= "rcvbuf_policy",
24762306a36Sopenharmony_ci		.data		= &init_net.sctp.rcvbuf_policy,
24862306a36Sopenharmony_ci		.maxlen		= sizeof(int),
24962306a36Sopenharmony_ci		.mode		= 0644,
25062306a36Sopenharmony_ci		.proc_handler	= proc_dointvec,
25162306a36Sopenharmony_ci	},
25262306a36Sopenharmony_ci	{
25362306a36Sopenharmony_ci		.procname	= "default_auto_asconf",
25462306a36Sopenharmony_ci		.data		= &init_net.sctp.default_auto_asconf,
25562306a36Sopenharmony_ci		.maxlen		= sizeof(int),
25662306a36Sopenharmony_ci		.mode		= 0644,
25762306a36Sopenharmony_ci		.proc_handler	= proc_dointvec,
25862306a36Sopenharmony_ci	},
25962306a36Sopenharmony_ci	{
26062306a36Sopenharmony_ci		.procname	= "addip_enable",
26162306a36Sopenharmony_ci		.data		= &init_net.sctp.addip_enable,
26262306a36Sopenharmony_ci		.maxlen		= sizeof(int),
26362306a36Sopenharmony_ci		.mode		= 0644,
26462306a36Sopenharmony_ci		.proc_handler	= proc_dointvec,
26562306a36Sopenharmony_ci	},
26662306a36Sopenharmony_ci	{
26762306a36Sopenharmony_ci		.procname	= "addip_noauth_enable",
26862306a36Sopenharmony_ci		.data		= &init_net.sctp.addip_noauth,
26962306a36Sopenharmony_ci		.maxlen		= sizeof(int),
27062306a36Sopenharmony_ci		.mode		= 0644,
27162306a36Sopenharmony_ci		.proc_handler	= proc_dointvec,
27262306a36Sopenharmony_ci	},
27362306a36Sopenharmony_ci	{
27462306a36Sopenharmony_ci		.procname	= "prsctp_enable",
27562306a36Sopenharmony_ci		.data		= &init_net.sctp.prsctp_enable,
27662306a36Sopenharmony_ci		.maxlen		= sizeof(int),
27762306a36Sopenharmony_ci		.mode		= 0644,
27862306a36Sopenharmony_ci		.proc_handler	= proc_dointvec,
27962306a36Sopenharmony_ci	},
28062306a36Sopenharmony_ci	{
28162306a36Sopenharmony_ci		.procname	= "reconf_enable",
28262306a36Sopenharmony_ci		.data		= &init_net.sctp.reconf_enable,
28362306a36Sopenharmony_ci		.maxlen		= sizeof(int),
28462306a36Sopenharmony_ci		.mode		= 0644,
28562306a36Sopenharmony_ci		.proc_handler	= proc_dointvec,
28662306a36Sopenharmony_ci	},
28762306a36Sopenharmony_ci	{
28862306a36Sopenharmony_ci		.procname	= "auth_enable",
28962306a36Sopenharmony_ci		.data		= &init_net.sctp.auth_enable,
29062306a36Sopenharmony_ci		.maxlen		= sizeof(int),
29162306a36Sopenharmony_ci		.mode		= 0644,
29262306a36Sopenharmony_ci		.proc_handler	= proc_sctp_do_auth,
29362306a36Sopenharmony_ci	},
29462306a36Sopenharmony_ci	{
29562306a36Sopenharmony_ci		.procname	= "intl_enable",
29662306a36Sopenharmony_ci		.data		= &init_net.sctp.intl_enable,
29762306a36Sopenharmony_ci		.maxlen		= sizeof(int),
29862306a36Sopenharmony_ci		.mode		= 0644,
29962306a36Sopenharmony_ci		.proc_handler	= proc_dointvec,
30062306a36Sopenharmony_ci	},
30162306a36Sopenharmony_ci	{
30262306a36Sopenharmony_ci		.procname	= "ecn_enable",
30362306a36Sopenharmony_ci		.data		= &init_net.sctp.ecn_enable,
30462306a36Sopenharmony_ci		.maxlen		= sizeof(int),
30562306a36Sopenharmony_ci		.mode		= 0644,
30662306a36Sopenharmony_ci		.proc_handler	= proc_dointvec,
30762306a36Sopenharmony_ci	},
30862306a36Sopenharmony_ci	{
30962306a36Sopenharmony_ci		.procname	= "plpmtud_probe_interval",
31062306a36Sopenharmony_ci		.data		= &init_net.sctp.probe_interval,
31162306a36Sopenharmony_ci		.maxlen		= sizeof(int),
31262306a36Sopenharmony_ci		.mode		= 0644,
31362306a36Sopenharmony_ci		.proc_handler	= proc_sctp_do_probe_interval,
31462306a36Sopenharmony_ci	},
31562306a36Sopenharmony_ci	{
31662306a36Sopenharmony_ci		.procname	= "udp_port",
31762306a36Sopenharmony_ci		.data		= &init_net.sctp.udp_port,
31862306a36Sopenharmony_ci		.maxlen		= sizeof(int),
31962306a36Sopenharmony_ci		.mode		= 0644,
32062306a36Sopenharmony_ci		.proc_handler	= proc_sctp_do_udp_port,
32162306a36Sopenharmony_ci		.extra1		= SYSCTL_ZERO,
32262306a36Sopenharmony_ci		.extra2		= &udp_port_max,
32362306a36Sopenharmony_ci	},
32462306a36Sopenharmony_ci	{
32562306a36Sopenharmony_ci		.procname	= "encap_port",
32662306a36Sopenharmony_ci		.data		= &init_net.sctp.encap_port,
32762306a36Sopenharmony_ci		.maxlen		= sizeof(int),
32862306a36Sopenharmony_ci		.mode		= 0644,
32962306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
33062306a36Sopenharmony_ci		.extra1		= SYSCTL_ZERO,
33162306a36Sopenharmony_ci		.extra2		= &udp_port_max,
33262306a36Sopenharmony_ci	},
33362306a36Sopenharmony_ci	{
33462306a36Sopenharmony_ci		.procname	= "addr_scope_policy",
33562306a36Sopenharmony_ci		.data		= &init_net.sctp.scope_policy,
33662306a36Sopenharmony_ci		.maxlen		= sizeof(int),
33762306a36Sopenharmony_ci		.mode		= 0644,
33862306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
33962306a36Sopenharmony_ci		.extra1		= SYSCTL_ZERO,
34062306a36Sopenharmony_ci		.extra2		= &addr_scope_max,
34162306a36Sopenharmony_ci	},
34262306a36Sopenharmony_ci	{
34362306a36Sopenharmony_ci		.procname	= "rwnd_update_shift",
34462306a36Sopenharmony_ci		.data		= &init_net.sctp.rwnd_upd_shift,
34562306a36Sopenharmony_ci		.maxlen		= sizeof(int),
34662306a36Sopenharmony_ci		.mode		= 0644,
34762306a36Sopenharmony_ci		.proc_handler	= &proc_dointvec_minmax,
34862306a36Sopenharmony_ci		.extra1		= SYSCTL_ONE,
34962306a36Sopenharmony_ci		.extra2		= &rwnd_scale_max,
35062306a36Sopenharmony_ci	},
35162306a36Sopenharmony_ci	{
35262306a36Sopenharmony_ci		.procname	= "max_autoclose",
35362306a36Sopenharmony_ci		.data		= &init_net.sctp.max_autoclose,
35462306a36Sopenharmony_ci		.maxlen		= sizeof(unsigned long),
35562306a36Sopenharmony_ci		.mode		= 0644,
35662306a36Sopenharmony_ci		.proc_handler	= &proc_doulongvec_minmax,
35762306a36Sopenharmony_ci		.extra1		= &max_autoclose_min,
35862306a36Sopenharmony_ci		.extra2		= &max_autoclose_max,
35962306a36Sopenharmony_ci	},
36062306a36Sopenharmony_ci#ifdef CONFIG_NET_L3_MASTER_DEV
36162306a36Sopenharmony_ci	{
36262306a36Sopenharmony_ci		.procname	= "l3mdev_accept",
36362306a36Sopenharmony_ci		.data		= &init_net.sctp.l3mdev_accept,
36462306a36Sopenharmony_ci		.maxlen		= sizeof(int),
36562306a36Sopenharmony_ci		.mode		= 0644,
36662306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
36762306a36Sopenharmony_ci		.extra1		= SYSCTL_ZERO,
36862306a36Sopenharmony_ci		.extra2		= SYSCTL_ONE,
36962306a36Sopenharmony_ci	},
37062306a36Sopenharmony_ci#endif
37162306a36Sopenharmony_ci	{
37262306a36Sopenharmony_ci		.procname	= "pf_enable",
37362306a36Sopenharmony_ci		.data		= &init_net.sctp.pf_enable,
37462306a36Sopenharmony_ci		.maxlen		= sizeof(int),
37562306a36Sopenharmony_ci		.mode		= 0644,
37662306a36Sopenharmony_ci		.proc_handler	= proc_dointvec,
37762306a36Sopenharmony_ci	},
37862306a36Sopenharmony_ci	{
37962306a36Sopenharmony_ci		.procname	= "pf_expose",
38062306a36Sopenharmony_ci		.data		= &init_net.sctp.pf_expose,
38162306a36Sopenharmony_ci		.maxlen		= sizeof(int),
38262306a36Sopenharmony_ci		.mode		= 0644,
38362306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
38462306a36Sopenharmony_ci		.extra1		= SYSCTL_ZERO,
38562306a36Sopenharmony_ci		.extra2		= &pf_expose_max,
38662306a36Sopenharmony_ci	},
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_ci	{ /* sentinel */ }
38962306a36Sopenharmony_ci};
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_cistatic int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
39262306a36Sopenharmony_ci				 void *buffer, size_t *lenp, loff_t *ppos)
39362306a36Sopenharmony_ci{
39462306a36Sopenharmony_ci	struct net *net = current->nsproxy->net_ns;
39562306a36Sopenharmony_ci	struct ctl_table tbl;
39662306a36Sopenharmony_ci	bool changed = false;
39762306a36Sopenharmony_ci	char *none = "none";
39862306a36Sopenharmony_ci	char tmp[8] = {0};
39962306a36Sopenharmony_ci	int ret;
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci	memset(&tbl, 0, sizeof(struct ctl_table));
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_ci	if (write) {
40462306a36Sopenharmony_ci		tbl.data = tmp;
40562306a36Sopenharmony_ci		tbl.maxlen = sizeof(tmp);
40662306a36Sopenharmony_ci	} else {
40762306a36Sopenharmony_ci		tbl.data = net->sctp.sctp_hmac_alg ? : none;
40862306a36Sopenharmony_ci		tbl.maxlen = strlen(tbl.data);
40962306a36Sopenharmony_ci	}
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_ci	ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
41262306a36Sopenharmony_ci	if (write && ret == 0) {
41362306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_MD5
41462306a36Sopenharmony_ci		if (!strncmp(tmp, "md5", 3)) {
41562306a36Sopenharmony_ci			net->sctp.sctp_hmac_alg = "md5";
41662306a36Sopenharmony_ci			changed = true;
41762306a36Sopenharmony_ci		}
41862306a36Sopenharmony_ci#endif
41962306a36Sopenharmony_ci#ifdef CONFIG_CRYPTO_SHA1
42062306a36Sopenharmony_ci		if (!strncmp(tmp, "sha1", 4)) {
42162306a36Sopenharmony_ci			net->sctp.sctp_hmac_alg = "sha1";
42262306a36Sopenharmony_ci			changed = true;
42362306a36Sopenharmony_ci		}
42462306a36Sopenharmony_ci#endif
42562306a36Sopenharmony_ci		if (!strncmp(tmp, "none", 4)) {
42662306a36Sopenharmony_ci			net->sctp.sctp_hmac_alg = NULL;
42762306a36Sopenharmony_ci			changed = true;
42862306a36Sopenharmony_ci		}
42962306a36Sopenharmony_ci		if (!changed)
43062306a36Sopenharmony_ci			ret = -EINVAL;
43162306a36Sopenharmony_ci	}
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_ci	return ret;
43462306a36Sopenharmony_ci}
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_cistatic int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
43762306a36Sopenharmony_ci				void *buffer, size_t *lenp, loff_t *ppos)
43862306a36Sopenharmony_ci{
43962306a36Sopenharmony_ci	struct net *net = current->nsproxy->net_ns;
44062306a36Sopenharmony_ci	unsigned int min = *(unsigned int *) ctl->extra1;
44162306a36Sopenharmony_ci	unsigned int max = *(unsigned int *) ctl->extra2;
44262306a36Sopenharmony_ci	struct ctl_table tbl;
44362306a36Sopenharmony_ci	int ret, new_value;
44462306a36Sopenharmony_ci
44562306a36Sopenharmony_ci	memset(&tbl, 0, sizeof(struct ctl_table));
44662306a36Sopenharmony_ci	tbl.maxlen = sizeof(unsigned int);
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_ci	if (write)
44962306a36Sopenharmony_ci		tbl.data = &new_value;
45062306a36Sopenharmony_ci	else
45162306a36Sopenharmony_ci		tbl.data = &net->sctp.rto_min;
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_ci	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
45462306a36Sopenharmony_ci	if (write && ret == 0) {
45562306a36Sopenharmony_ci		if (new_value > max || new_value < min)
45662306a36Sopenharmony_ci			return -EINVAL;
45762306a36Sopenharmony_ci
45862306a36Sopenharmony_ci		net->sctp.rto_min = new_value;
45962306a36Sopenharmony_ci	}
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_ci	return ret;
46262306a36Sopenharmony_ci}
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_cistatic int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
46562306a36Sopenharmony_ci				void *buffer, size_t *lenp, loff_t *ppos)
46662306a36Sopenharmony_ci{
46762306a36Sopenharmony_ci	struct net *net = current->nsproxy->net_ns;
46862306a36Sopenharmony_ci	unsigned int min = *(unsigned int *) ctl->extra1;
46962306a36Sopenharmony_ci	unsigned int max = *(unsigned int *) ctl->extra2;
47062306a36Sopenharmony_ci	struct ctl_table tbl;
47162306a36Sopenharmony_ci	int ret, new_value;
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_ci	memset(&tbl, 0, sizeof(struct ctl_table));
47462306a36Sopenharmony_ci	tbl.maxlen = sizeof(unsigned int);
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_ci	if (write)
47762306a36Sopenharmony_ci		tbl.data = &new_value;
47862306a36Sopenharmony_ci	else
47962306a36Sopenharmony_ci		tbl.data = &net->sctp.rto_max;
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_ci	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
48262306a36Sopenharmony_ci	if (write && ret == 0) {
48362306a36Sopenharmony_ci		if (new_value > max || new_value < min)
48462306a36Sopenharmony_ci			return -EINVAL;
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci		net->sctp.rto_max = new_value;
48762306a36Sopenharmony_ci	}
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_ci	return ret;
49062306a36Sopenharmony_ci}
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_cistatic int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
49362306a36Sopenharmony_ci				   void *buffer, size_t *lenp, loff_t *ppos)
49462306a36Sopenharmony_ci{
49562306a36Sopenharmony_ci	if (write)
49662306a36Sopenharmony_ci		pr_warn_once("Changing rto_alpha or rto_beta may lead to "
49762306a36Sopenharmony_ci			     "suboptimal rtt/srtt estimations!\n");
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci	return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos);
50062306a36Sopenharmony_ci}
50162306a36Sopenharmony_ci
50262306a36Sopenharmony_cistatic int proc_sctp_do_auth(struct ctl_table *ctl, int write,
50362306a36Sopenharmony_ci			     void *buffer, size_t *lenp, loff_t *ppos)
50462306a36Sopenharmony_ci{
50562306a36Sopenharmony_ci	struct net *net = current->nsproxy->net_ns;
50662306a36Sopenharmony_ci	struct ctl_table tbl;
50762306a36Sopenharmony_ci	int new_value, ret;
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ci	memset(&tbl, 0, sizeof(struct ctl_table));
51062306a36Sopenharmony_ci	tbl.maxlen = sizeof(unsigned int);
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_ci	if (write)
51362306a36Sopenharmony_ci		tbl.data = &new_value;
51462306a36Sopenharmony_ci	else
51562306a36Sopenharmony_ci		tbl.data = &net->sctp.auth_enable;
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ci	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
51862306a36Sopenharmony_ci	if (write && ret == 0) {
51962306a36Sopenharmony_ci		struct sock *sk = net->sctp.ctl_sock;
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_ci		net->sctp.auth_enable = new_value;
52262306a36Sopenharmony_ci		/* Update the value in the control socket */
52362306a36Sopenharmony_ci		lock_sock(sk);
52462306a36Sopenharmony_ci		sctp_sk(sk)->ep->auth_enable = new_value;
52562306a36Sopenharmony_ci		release_sock(sk);
52662306a36Sopenharmony_ci	}
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci	return ret;
52962306a36Sopenharmony_ci}
53062306a36Sopenharmony_ci
53162306a36Sopenharmony_cistatic int proc_sctp_do_udp_port(struct ctl_table *ctl, int write,
53262306a36Sopenharmony_ci				 void *buffer, size_t *lenp, loff_t *ppos)
53362306a36Sopenharmony_ci{
53462306a36Sopenharmony_ci	struct net *net = current->nsproxy->net_ns;
53562306a36Sopenharmony_ci	unsigned int min = *(unsigned int *)ctl->extra1;
53662306a36Sopenharmony_ci	unsigned int max = *(unsigned int *)ctl->extra2;
53762306a36Sopenharmony_ci	struct ctl_table tbl;
53862306a36Sopenharmony_ci	int ret, new_value;
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci	memset(&tbl, 0, sizeof(struct ctl_table));
54162306a36Sopenharmony_ci	tbl.maxlen = sizeof(unsigned int);
54262306a36Sopenharmony_ci
54362306a36Sopenharmony_ci	if (write)
54462306a36Sopenharmony_ci		tbl.data = &new_value;
54562306a36Sopenharmony_ci	else
54662306a36Sopenharmony_ci		tbl.data = &net->sctp.udp_port;
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
54962306a36Sopenharmony_ci	if (write && ret == 0) {
55062306a36Sopenharmony_ci		struct sock *sk = net->sctp.ctl_sock;
55162306a36Sopenharmony_ci
55262306a36Sopenharmony_ci		if (new_value > max || new_value < min)
55362306a36Sopenharmony_ci			return -EINVAL;
55462306a36Sopenharmony_ci
55562306a36Sopenharmony_ci		net->sctp.udp_port = new_value;
55662306a36Sopenharmony_ci		sctp_udp_sock_stop(net);
55762306a36Sopenharmony_ci		if (new_value) {
55862306a36Sopenharmony_ci			ret = sctp_udp_sock_start(net);
55962306a36Sopenharmony_ci			if (ret)
56062306a36Sopenharmony_ci				net->sctp.udp_port = 0;
56162306a36Sopenharmony_ci		}
56262306a36Sopenharmony_ci
56362306a36Sopenharmony_ci		/* Update the value in the control socket */
56462306a36Sopenharmony_ci		lock_sock(sk);
56562306a36Sopenharmony_ci		sctp_sk(sk)->udp_port = htons(net->sctp.udp_port);
56662306a36Sopenharmony_ci		release_sock(sk);
56762306a36Sopenharmony_ci	}
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_ci	return ret;
57062306a36Sopenharmony_ci}
57162306a36Sopenharmony_ci
57262306a36Sopenharmony_cistatic int proc_sctp_do_probe_interval(struct ctl_table *ctl, int write,
57362306a36Sopenharmony_ci				       void *buffer, size_t *lenp, loff_t *ppos)
57462306a36Sopenharmony_ci{
57562306a36Sopenharmony_ci	struct net *net = current->nsproxy->net_ns;
57662306a36Sopenharmony_ci	struct ctl_table tbl;
57762306a36Sopenharmony_ci	int ret, new_value;
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_ci	memset(&tbl, 0, sizeof(struct ctl_table));
58062306a36Sopenharmony_ci	tbl.maxlen = sizeof(unsigned int);
58162306a36Sopenharmony_ci
58262306a36Sopenharmony_ci	if (write)
58362306a36Sopenharmony_ci		tbl.data = &new_value;
58462306a36Sopenharmony_ci	else
58562306a36Sopenharmony_ci		tbl.data = &net->sctp.probe_interval;
58662306a36Sopenharmony_ci
58762306a36Sopenharmony_ci	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
58862306a36Sopenharmony_ci	if (write && ret == 0) {
58962306a36Sopenharmony_ci		if (new_value && new_value < SCTP_PROBE_TIMER_MIN)
59062306a36Sopenharmony_ci			return -EINVAL;
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci		net->sctp.probe_interval = new_value;
59362306a36Sopenharmony_ci	}
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ci	return ret;
59662306a36Sopenharmony_ci}
59762306a36Sopenharmony_ci
59862306a36Sopenharmony_ciint sctp_sysctl_net_register(struct net *net)
59962306a36Sopenharmony_ci{
60062306a36Sopenharmony_ci	struct ctl_table *table;
60162306a36Sopenharmony_ci	int i;
60262306a36Sopenharmony_ci
60362306a36Sopenharmony_ci	table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL);
60462306a36Sopenharmony_ci	if (!table)
60562306a36Sopenharmony_ci		return -ENOMEM;
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_ci	for (i = 0; table[i].data; i++)
60862306a36Sopenharmony_ci		table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp;
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_ci	table[SCTP_RTO_MIN_IDX].extra2 = &net->sctp.rto_max;
61162306a36Sopenharmony_ci	table[SCTP_RTO_MAX_IDX].extra1 = &net->sctp.rto_min;
61262306a36Sopenharmony_ci	table[SCTP_PF_RETRANS_IDX].extra2 = &net->sctp.ps_retrans;
61362306a36Sopenharmony_ci	table[SCTP_PS_RETRANS_IDX].extra1 = &net->sctp.pf_retrans;
61462306a36Sopenharmony_ci
61562306a36Sopenharmony_ci	net->sctp.sysctl_header = register_net_sysctl_sz(net, "net/sctp",
61662306a36Sopenharmony_ci							 table,
61762306a36Sopenharmony_ci							 ARRAY_SIZE(sctp_net_table));
61862306a36Sopenharmony_ci	if (net->sctp.sysctl_header == NULL) {
61962306a36Sopenharmony_ci		kfree(table);
62062306a36Sopenharmony_ci		return -ENOMEM;
62162306a36Sopenharmony_ci	}
62262306a36Sopenharmony_ci	return 0;
62362306a36Sopenharmony_ci}
62462306a36Sopenharmony_ci
62562306a36Sopenharmony_civoid sctp_sysctl_net_unregister(struct net *net)
62662306a36Sopenharmony_ci{
62762306a36Sopenharmony_ci	struct ctl_table *table;
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_ci	table = net->sctp.sysctl_header->ctl_table_arg;
63062306a36Sopenharmony_ci	unregister_net_sysctl_table(net->sctp.sysctl_header);
63162306a36Sopenharmony_ci	kfree(table);
63262306a36Sopenharmony_ci}
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_cistatic struct ctl_table_header *sctp_sysctl_header;
63562306a36Sopenharmony_ci
63662306a36Sopenharmony_ci/* Sysctl registration.  */
63762306a36Sopenharmony_civoid sctp_sysctl_register(void)
63862306a36Sopenharmony_ci{
63962306a36Sopenharmony_ci	sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table);
64062306a36Sopenharmony_ci}
64162306a36Sopenharmony_ci
64262306a36Sopenharmony_ci/* Sysctl deregistration.  */
64362306a36Sopenharmony_civoid sctp_sysctl_unregister(void)
64462306a36Sopenharmony_ci{
64562306a36Sopenharmony_ci	unregister_net_sysctl_table(sctp_sysctl_header);
64662306a36Sopenharmony_ci}
647