18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/* SCTP kernel implementation
38c2ecf20Sopenharmony_ci * (C) Copyright IBM Corp. 2002, 2004
48c2ecf20Sopenharmony_ci * Copyright (c) 2002 Intel Corp.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * This file is part of the SCTP kernel implementation
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * Sysctl related interfaces for SCTP.
98c2ecf20Sopenharmony_ci *
108c2ecf20Sopenharmony_ci * Please send any bug reports or fixes you make to the
118c2ecf20Sopenharmony_ci * email address(es):
128c2ecf20Sopenharmony_ci *    lksctp developers <linux-sctp@vger.kernel.org>
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci * Written or modified by:
158c2ecf20Sopenharmony_ci *    Mingqin Liu           <liuming@us.ibm.com>
168c2ecf20Sopenharmony_ci *    Jon Grimm             <jgrimm@us.ibm.com>
178c2ecf20Sopenharmony_ci *    Ardelle Fan           <ardelle.fan@intel.com>
188c2ecf20Sopenharmony_ci *    Ryan Layer            <rmlayer@us.ibm.com>
198c2ecf20Sopenharmony_ci *    Sridhar Samudrala     <sri@us.ibm.com>
208c2ecf20Sopenharmony_ci */
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci#include <net/sctp/structs.h>
258c2ecf20Sopenharmony_ci#include <net/sctp/sctp.h>
268c2ecf20Sopenharmony_ci#include <linux/sysctl.h>
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_cistatic int timer_max = 86400000; /* ms in one day */
298c2ecf20Sopenharmony_cistatic int sack_timer_min = 1;
308c2ecf20Sopenharmony_cistatic int sack_timer_max = 500;
318c2ecf20Sopenharmony_cistatic int addr_scope_max = SCTP_SCOPE_POLICY_MAX;
328c2ecf20Sopenharmony_cistatic int rwnd_scale_max = 16;
338c2ecf20Sopenharmony_cistatic int rto_alpha_min = 0;
348c2ecf20Sopenharmony_cistatic int rto_beta_min = 0;
358c2ecf20Sopenharmony_cistatic int rto_alpha_max = 1000;
368c2ecf20Sopenharmony_cistatic int rto_beta_max = 1000;
378c2ecf20Sopenharmony_cistatic int pf_expose_max = SCTP_PF_EXPOSE_MAX;
388c2ecf20Sopenharmony_cistatic int ps_retrans_max = SCTP_PS_RETRANS_MAX;
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_cistatic unsigned long max_autoclose_min = 0;
418c2ecf20Sopenharmony_cistatic unsigned long max_autoclose_max =
428c2ecf20Sopenharmony_ci	(MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX)
438c2ecf20Sopenharmony_ci	? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ;
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_cistatic int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
468c2ecf20Sopenharmony_ci				 void *buffer, size_t *lenp, loff_t *ppos);
478c2ecf20Sopenharmony_cistatic int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
488c2ecf20Sopenharmony_ci				void *buffer, size_t *lenp, loff_t *ppos);
498c2ecf20Sopenharmony_cistatic int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, void *buffer,
508c2ecf20Sopenharmony_ci				size_t *lenp, loff_t *ppos);
518c2ecf20Sopenharmony_cistatic int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
528c2ecf20Sopenharmony_ci				   void *buffer, size_t *lenp, loff_t *ppos);
538c2ecf20Sopenharmony_cistatic int proc_sctp_do_auth(struct ctl_table *ctl, int write,
548c2ecf20Sopenharmony_ci			     void *buffer, size_t *lenp, loff_t *ppos);
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_cistatic struct ctl_table sctp_table[] = {
578c2ecf20Sopenharmony_ci	{
588c2ecf20Sopenharmony_ci		.procname	= "sctp_mem",
598c2ecf20Sopenharmony_ci		.data		= &sysctl_sctp_mem,
608c2ecf20Sopenharmony_ci		.maxlen		= sizeof(sysctl_sctp_mem),
618c2ecf20Sopenharmony_ci		.mode		= 0644,
628c2ecf20Sopenharmony_ci		.proc_handler	= proc_doulongvec_minmax
638c2ecf20Sopenharmony_ci	},
648c2ecf20Sopenharmony_ci	{
658c2ecf20Sopenharmony_ci		.procname	= "sctp_rmem",
668c2ecf20Sopenharmony_ci		.data		= &sysctl_sctp_rmem,
678c2ecf20Sopenharmony_ci		.maxlen		= sizeof(sysctl_sctp_rmem),
688c2ecf20Sopenharmony_ci		.mode		= 0644,
698c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec,
708c2ecf20Sopenharmony_ci	},
718c2ecf20Sopenharmony_ci	{
728c2ecf20Sopenharmony_ci		.procname	= "sctp_wmem",
738c2ecf20Sopenharmony_ci		.data		= &sysctl_sctp_wmem,
748c2ecf20Sopenharmony_ci		.maxlen		= sizeof(sysctl_sctp_wmem),
758c2ecf20Sopenharmony_ci		.mode		= 0644,
768c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec,
778c2ecf20Sopenharmony_ci	},
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ci	{ /* sentinel */ }
808c2ecf20Sopenharmony_ci};
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci/* The following index defines are used in sctp_sysctl_net_register().
838c2ecf20Sopenharmony_ci * If you add new items to the sctp_net_table, please ensure that
848c2ecf20Sopenharmony_ci * the index values of these defines hold the same meaning indicated by
858c2ecf20Sopenharmony_ci * their macro names when they appear in sctp_net_table.
868c2ecf20Sopenharmony_ci */
878c2ecf20Sopenharmony_ci#define SCTP_RTO_MIN_IDX       0
888c2ecf20Sopenharmony_ci#define SCTP_RTO_MAX_IDX       1
898c2ecf20Sopenharmony_ci#define SCTP_PF_RETRANS_IDX    2
908c2ecf20Sopenharmony_ci#define SCTP_PS_RETRANS_IDX    3
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_cistatic struct ctl_table sctp_net_table[] = {
938c2ecf20Sopenharmony_ci	[SCTP_RTO_MIN_IDX] = {
948c2ecf20Sopenharmony_ci		.procname	= "rto_min",
958c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.rto_min,
968c2ecf20Sopenharmony_ci		.maxlen		= sizeof(unsigned int),
978c2ecf20Sopenharmony_ci		.mode		= 0644,
988c2ecf20Sopenharmony_ci		.proc_handler	= proc_sctp_do_rto_min,
998c2ecf20Sopenharmony_ci		.extra1         = SYSCTL_ONE,
1008c2ecf20Sopenharmony_ci		.extra2         = &init_net.sctp.rto_max
1018c2ecf20Sopenharmony_ci	},
1028c2ecf20Sopenharmony_ci	[SCTP_RTO_MAX_IDX] =  {
1038c2ecf20Sopenharmony_ci		.procname	= "rto_max",
1048c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.rto_max,
1058c2ecf20Sopenharmony_ci		.maxlen		= sizeof(unsigned int),
1068c2ecf20Sopenharmony_ci		.mode		= 0644,
1078c2ecf20Sopenharmony_ci		.proc_handler	= proc_sctp_do_rto_max,
1088c2ecf20Sopenharmony_ci		.extra1         = &init_net.sctp.rto_min,
1098c2ecf20Sopenharmony_ci		.extra2         = &timer_max
1108c2ecf20Sopenharmony_ci	},
1118c2ecf20Sopenharmony_ci	[SCTP_PF_RETRANS_IDX] = {
1128c2ecf20Sopenharmony_ci		.procname	= "pf_retrans",
1138c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.pf_retrans,
1148c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
1158c2ecf20Sopenharmony_ci		.mode		= 0644,
1168c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
1178c2ecf20Sopenharmony_ci		.extra1		= SYSCTL_ZERO,
1188c2ecf20Sopenharmony_ci		.extra2		= &init_net.sctp.ps_retrans,
1198c2ecf20Sopenharmony_ci	},
1208c2ecf20Sopenharmony_ci	[SCTP_PS_RETRANS_IDX] = {
1218c2ecf20Sopenharmony_ci		.procname	= "ps_retrans",
1228c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.ps_retrans,
1238c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
1248c2ecf20Sopenharmony_ci		.mode		= 0644,
1258c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
1268c2ecf20Sopenharmony_ci		.extra1		= &init_net.sctp.pf_retrans,
1278c2ecf20Sopenharmony_ci		.extra2		= &ps_retrans_max,
1288c2ecf20Sopenharmony_ci	},
1298c2ecf20Sopenharmony_ci	{
1308c2ecf20Sopenharmony_ci		.procname	= "rto_initial",
1318c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.rto_initial,
1328c2ecf20Sopenharmony_ci		.maxlen		= sizeof(unsigned int),
1338c2ecf20Sopenharmony_ci		.mode		= 0644,
1348c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
1358c2ecf20Sopenharmony_ci		.extra1         = SYSCTL_ONE,
1368c2ecf20Sopenharmony_ci		.extra2         = &timer_max
1378c2ecf20Sopenharmony_ci	},
1388c2ecf20Sopenharmony_ci	{
1398c2ecf20Sopenharmony_ci		.procname	= "rto_alpha_exp_divisor",
1408c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.rto_alpha,
1418c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
1428c2ecf20Sopenharmony_ci		.mode		= 0644,
1438c2ecf20Sopenharmony_ci		.proc_handler	= proc_sctp_do_alpha_beta,
1448c2ecf20Sopenharmony_ci		.extra1		= &rto_alpha_min,
1458c2ecf20Sopenharmony_ci		.extra2		= &rto_alpha_max,
1468c2ecf20Sopenharmony_ci	},
1478c2ecf20Sopenharmony_ci	{
1488c2ecf20Sopenharmony_ci		.procname	= "rto_beta_exp_divisor",
1498c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.rto_beta,
1508c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
1518c2ecf20Sopenharmony_ci		.mode		= 0644,
1528c2ecf20Sopenharmony_ci		.proc_handler	= proc_sctp_do_alpha_beta,
1538c2ecf20Sopenharmony_ci		.extra1		= &rto_beta_min,
1548c2ecf20Sopenharmony_ci		.extra2		= &rto_beta_max,
1558c2ecf20Sopenharmony_ci	},
1568c2ecf20Sopenharmony_ci	{
1578c2ecf20Sopenharmony_ci		.procname	= "max_burst",
1588c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.max_burst,
1598c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
1608c2ecf20Sopenharmony_ci		.mode		= 0644,
1618c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
1628c2ecf20Sopenharmony_ci		.extra1		= SYSCTL_ZERO,
1638c2ecf20Sopenharmony_ci		.extra2		= SYSCTL_INT_MAX,
1648c2ecf20Sopenharmony_ci	},
1658c2ecf20Sopenharmony_ci	{
1668c2ecf20Sopenharmony_ci		.procname	= "cookie_preserve_enable",
1678c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.cookie_preserve_enable,
1688c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
1698c2ecf20Sopenharmony_ci		.mode		= 0644,
1708c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec,
1718c2ecf20Sopenharmony_ci	},
1728c2ecf20Sopenharmony_ci	{
1738c2ecf20Sopenharmony_ci		.procname	= "cookie_hmac_alg",
1748c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.sctp_hmac_alg,
1758c2ecf20Sopenharmony_ci		.maxlen		= 8,
1768c2ecf20Sopenharmony_ci		.mode		= 0644,
1778c2ecf20Sopenharmony_ci		.proc_handler	= proc_sctp_do_hmac_alg,
1788c2ecf20Sopenharmony_ci	},
1798c2ecf20Sopenharmony_ci	{
1808c2ecf20Sopenharmony_ci		.procname	= "valid_cookie_life",
1818c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.valid_cookie_life,
1828c2ecf20Sopenharmony_ci		.maxlen		= sizeof(unsigned int),
1838c2ecf20Sopenharmony_ci		.mode		= 0644,
1848c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
1858c2ecf20Sopenharmony_ci		.extra1         = SYSCTL_ONE,
1868c2ecf20Sopenharmony_ci		.extra2         = &timer_max
1878c2ecf20Sopenharmony_ci	},
1888c2ecf20Sopenharmony_ci	{
1898c2ecf20Sopenharmony_ci		.procname	= "sack_timeout",
1908c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.sack_timeout,
1918c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
1928c2ecf20Sopenharmony_ci		.mode		= 0644,
1938c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
1948c2ecf20Sopenharmony_ci		.extra1         = &sack_timer_min,
1958c2ecf20Sopenharmony_ci		.extra2         = &sack_timer_max,
1968c2ecf20Sopenharmony_ci	},
1978c2ecf20Sopenharmony_ci	{
1988c2ecf20Sopenharmony_ci		.procname	= "hb_interval",
1998c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.hb_interval,
2008c2ecf20Sopenharmony_ci		.maxlen		= sizeof(unsigned int),
2018c2ecf20Sopenharmony_ci		.mode		= 0644,
2028c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
2038c2ecf20Sopenharmony_ci		.extra1         = SYSCTL_ONE,
2048c2ecf20Sopenharmony_ci		.extra2         = &timer_max
2058c2ecf20Sopenharmony_ci	},
2068c2ecf20Sopenharmony_ci	{
2078c2ecf20Sopenharmony_ci		.procname	= "association_max_retrans",
2088c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.max_retrans_association,
2098c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
2108c2ecf20Sopenharmony_ci		.mode		= 0644,
2118c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
2128c2ecf20Sopenharmony_ci		.extra1		= SYSCTL_ONE,
2138c2ecf20Sopenharmony_ci		.extra2		= SYSCTL_INT_MAX,
2148c2ecf20Sopenharmony_ci	},
2158c2ecf20Sopenharmony_ci	{
2168c2ecf20Sopenharmony_ci		.procname	= "path_max_retrans",
2178c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.max_retrans_path,
2188c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
2198c2ecf20Sopenharmony_ci		.mode		= 0644,
2208c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
2218c2ecf20Sopenharmony_ci		.extra1		= SYSCTL_ONE,
2228c2ecf20Sopenharmony_ci		.extra2		= SYSCTL_INT_MAX,
2238c2ecf20Sopenharmony_ci	},
2248c2ecf20Sopenharmony_ci	{
2258c2ecf20Sopenharmony_ci		.procname	= "max_init_retransmits",
2268c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.max_retrans_init,
2278c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
2288c2ecf20Sopenharmony_ci		.mode		= 0644,
2298c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
2308c2ecf20Sopenharmony_ci		.extra1		= SYSCTL_ONE,
2318c2ecf20Sopenharmony_ci		.extra2		= SYSCTL_INT_MAX,
2328c2ecf20Sopenharmony_ci	},
2338c2ecf20Sopenharmony_ci	{
2348c2ecf20Sopenharmony_ci		.procname	= "sndbuf_policy",
2358c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.sndbuf_policy,
2368c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
2378c2ecf20Sopenharmony_ci		.mode		= 0644,
2388c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec,
2398c2ecf20Sopenharmony_ci	},
2408c2ecf20Sopenharmony_ci	{
2418c2ecf20Sopenharmony_ci		.procname	= "rcvbuf_policy",
2428c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.rcvbuf_policy,
2438c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
2448c2ecf20Sopenharmony_ci		.mode		= 0644,
2458c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec,
2468c2ecf20Sopenharmony_ci	},
2478c2ecf20Sopenharmony_ci	{
2488c2ecf20Sopenharmony_ci		.procname	= "default_auto_asconf",
2498c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.default_auto_asconf,
2508c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
2518c2ecf20Sopenharmony_ci		.mode		= 0644,
2528c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec,
2538c2ecf20Sopenharmony_ci	},
2548c2ecf20Sopenharmony_ci	{
2558c2ecf20Sopenharmony_ci		.procname	= "addip_enable",
2568c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.addip_enable,
2578c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
2588c2ecf20Sopenharmony_ci		.mode		= 0644,
2598c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec,
2608c2ecf20Sopenharmony_ci	},
2618c2ecf20Sopenharmony_ci	{
2628c2ecf20Sopenharmony_ci		.procname	= "addip_noauth_enable",
2638c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.addip_noauth,
2648c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
2658c2ecf20Sopenharmony_ci		.mode		= 0644,
2668c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec,
2678c2ecf20Sopenharmony_ci	},
2688c2ecf20Sopenharmony_ci	{
2698c2ecf20Sopenharmony_ci		.procname	= "prsctp_enable",
2708c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.prsctp_enable,
2718c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
2728c2ecf20Sopenharmony_ci		.mode		= 0644,
2738c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec,
2748c2ecf20Sopenharmony_ci	},
2758c2ecf20Sopenharmony_ci	{
2768c2ecf20Sopenharmony_ci		.procname	= "reconf_enable",
2778c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.reconf_enable,
2788c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
2798c2ecf20Sopenharmony_ci		.mode		= 0644,
2808c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec,
2818c2ecf20Sopenharmony_ci	},
2828c2ecf20Sopenharmony_ci	{
2838c2ecf20Sopenharmony_ci		.procname	= "auth_enable",
2848c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.auth_enable,
2858c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
2868c2ecf20Sopenharmony_ci		.mode		= 0644,
2878c2ecf20Sopenharmony_ci		.proc_handler	= proc_sctp_do_auth,
2888c2ecf20Sopenharmony_ci	},
2898c2ecf20Sopenharmony_ci	{
2908c2ecf20Sopenharmony_ci		.procname	= "intl_enable",
2918c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.intl_enable,
2928c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
2938c2ecf20Sopenharmony_ci		.mode		= 0644,
2948c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec,
2958c2ecf20Sopenharmony_ci	},
2968c2ecf20Sopenharmony_ci	{
2978c2ecf20Sopenharmony_ci		.procname	= "ecn_enable",
2988c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.ecn_enable,
2998c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
3008c2ecf20Sopenharmony_ci		.mode		= 0644,
3018c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec,
3028c2ecf20Sopenharmony_ci	},
3038c2ecf20Sopenharmony_ci	{
3048c2ecf20Sopenharmony_ci		.procname	= "addr_scope_policy",
3058c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.scope_policy,
3068c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
3078c2ecf20Sopenharmony_ci		.mode		= 0644,
3088c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
3098c2ecf20Sopenharmony_ci		.extra1		= SYSCTL_ZERO,
3108c2ecf20Sopenharmony_ci		.extra2		= &addr_scope_max,
3118c2ecf20Sopenharmony_ci	},
3128c2ecf20Sopenharmony_ci	{
3138c2ecf20Sopenharmony_ci		.procname	= "rwnd_update_shift",
3148c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.rwnd_upd_shift,
3158c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
3168c2ecf20Sopenharmony_ci		.mode		= 0644,
3178c2ecf20Sopenharmony_ci		.proc_handler	= &proc_dointvec_minmax,
3188c2ecf20Sopenharmony_ci		.extra1		= SYSCTL_ONE,
3198c2ecf20Sopenharmony_ci		.extra2		= &rwnd_scale_max,
3208c2ecf20Sopenharmony_ci	},
3218c2ecf20Sopenharmony_ci	{
3228c2ecf20Sopenharmony_ci		.procname	= "max_autoclose",
3238c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.max_autoclose,
3248c2ecf20Sopenharmony_ci		.maxlen		= sizeof(unsigned long),
3258c2ecf20Sopenharmony_ci		.mode		= 0644,
3268c2ecf20Sopenharmony_ci		.proc_handler	= &proc_doulongvec_minmax,
3278c2ecf20Sopenharmony_ci		.extra1		= &max_autoclose_min,
3288c2ecf20Sopenharmony_ci		.extra2		= &max_autoclose_max,
3298c2ecf20Sopenharmony_ci	},
3308c2ecf20Sopenharmony_ci	{
3318c2ecf20Sopenharmony_ci		.procname	= "pf_enable",
3328c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.pf_enable,
3338c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
3348c2ecf20Sopenharmony_ci		.mode		= 0644,
3358c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec,
3368c2ecf20Sopenharmony_ci	},
3378c2ecf20Sopenharmony_ci	{
3388c2ecf20Sopenharmony_ci		.procname	= "pf_expose",
3398c2ecf20Sopenharmony_ci		.data		= &init_net.sctp.pf_expose,
3408c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
3418c2ecf20Sopenharmony_ci		.mode		= 0644,
3428c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
3438c2ecf20Sopenharmony_ci		.extra1		= SYSCTL_ZERO,
3448c2ecf20Sopenharmony_ci		.extra2		= &pf_expose_max,
3458c2ecf20Sopenharmony_ci	},
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ci	{ /* sentinel */ }
3488c2ecf20Sopenharmony_ci};
3498c2ecf20Sopenharmony_ci
3508c2ecf20Sopenharmony_cistatic int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
3518c2ecf20Sopenharmony_ci				 void *buffer, size_t *lenp, loff_t *ppos)
3528c2ecf20Sopenharmony_ci{
3538c2ecf20Sopenharmony_ci	struct net *net = current->nsproxy->net_ns;
3548c2ecf20Sopenharmony_ci	struct ctl_table tbl;
3558c2ecf20Sopenharmony_ci	bool changed = false;
3568c2ecf20Sopenharmony_ci	char *none = "none";
3578c2ecf20Sopenharmony_ci	char tmp[8] = {0};
3588c2ecf20Sopenharmony_ci	int ret;
3598c2ecf20Sopenharmony_ci
3608c2ecf20Sopenharmony_ci	memset(&tbl, 0, sizeof(struct ctl_table));
3618c2ecf20Sopenharmony_ci
3628c2ecf20Sopenharmony_ci	if (write) {
3638c2ecf20Sopenharmony_ci		tbl.data = tmp;
3648c2ecf20Sopenharmony_ci		tbl.maxlen = sizeof(tmp);
3658c2ecf20Sopenharmony_ci	} else {
3668c2ecf20Sopenharmony_ci		tbl.data = net->sctp.sctp_hmac_alg ? : none;
3678c2ecf20Sopenharmony_ci		tbl.maxlen = strlen(tbl.data);
3688c2ecf20Sopenharmony_ci	}
3698c2ecf20Sopenharmony_ci
3708c2ecf20Sopenharmony_ci	ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
3718c2ecf20Sopenharmony_ci	if (write && ret == 0) {
3728c2ecf20Sopenharmony_ci#ifdef CONFIG_CRYPTO_MD5
3738c2ecf20Sopenharmony_ci		if (!strncmp(tmp, "md5", 3)) {
3748c2ecf20Sopenharmony_ci			net->sctp.sctp_hmac_alg = "md5";
3758c2ecf20Sopenharmony_ci			changed = true;
3768c2ecf20Sopenharmony_ci		}
3778c2ecf20Sopenharmony_ci#endif
3788c2ecf20Sopenharmony_ci#ifdef CONFIG_CRYPTO_SHA1
3798c2ecf20Sopenharmony_ci		if (!strncmp(tmp, "sha1", 4)) {
3808c2ecf20Sopenharmony_ci			net->sctp.sctp_hmac_alg = "sha1";
3818c2ecf20Sopenharmony_ci			changed = true;
3828c2ecf20Sopenharmony_ci		}
3838c2ecf20Sopenharmony_ci#endif
3848c2ecf20Sopenharmony_ci		if (!strncmp(tmp, "none", 4)) {
3858c2ecf20Sopenharmony_ci			net->sctp.sctp_hmac_alg = NULL;
3868c2ecf20Sopenharmony_ci			changed = true;
3878c2ecf20Sopenharmony_ci		}
3888c2ecf20Sopenharmony_ci		if (!changed)
3898c2ecf20Sopenharmony_ci			ret = -EINVAL;
3908c2ecf20Sopenharmony_ci	}
3918c2ecf20Sopenharmony_ci
3928c2ecf20Sopenharmony_ci	return ret;
3938c2ecf20Sopenharmony_ci}
3948c2ecf20Sopenharmony_ci
3958c2ecf20Sopenharmony_cistatic int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
3968c2ecf20Sopenharmony_ci				void *buffer, size_t *lenp, loff_t *ppos)
3978c2ecf20Sopenharmony_ci{
3988c2ecf20Sopenharmony_ci	struct net *net = current->nsproxy->net_ns;
3998c2ecf20Sopenharmony_ci	unsigned int min = *(unsigned int *) ctl->extra1;
4008c2ecf20Sopenharmony_ci	unsigned int max = *(unsigned int *) ctl->extra2;
4018c2ecf20Sopenharmony_ci	struct ctl_table tbl;
4028c2ecf20Sopenharmony_ci	int ret, new_value;
4038c2ecf20Sopenharmony_ci
4048c2ecf20Sopenharmony_ci	memset(&tbl, 0, sizeof(struct ctl_table));
4058c2ecf20Sopenharmony_ci	tbl.maxlen = sizeof(unsigned int);
4068c2ecf20Sopenharmony_ci
4078c2ecf20Sopenharmony_ci	if (write)
4088c2ecf20Sopenharmony_ci		tbl.data = &new_value;
4098c2ecf20Sopenharmony_ci	else
4108c2ecf20Sopenharmony_ci		tbl.data = &net->sctp.rto_min;
4118c2ecf20Sopenharmony_ci
4128c2ecf20Sopenharmony_ci	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
4138c2ecf20Sopenharmony_ci	if (write && ret == 0) {
4148c2ecf20Sopenharmony_ci		if (new_value > max || new_value < min)
4158c2ecf20Sopenharmony_ci			return -EINVAL;
4168c2ecf20Sopenharmony_ci
4178c2ecf20Sopenharmony_ci		net->sctp.rto_min = new_value;
4188c2ecf20Sopenharmony_ci	}
4198c2ecf20Sopenharmony_ci
4208c2ecf20Sopenharmony_ci	return ret;
4218c2ecf20Sopenharmony_ci}
4228c2ecf20Sopenharmony_ci
4238c2ecf20Sopenharmony_cistatic int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
4248c2ecf20Sopenharmony_ci				void *buffer, size_t *lenp, loff_t *ppos)
4258c2ecf20Sopenharmony_ci{
4268c2ecf20Sopenharmony_ci	struct net *net = current->nsproxy->net_ns;
4278c2ecf20Sopenharmony_ci	unsigned int min = *(unsigned int *) ctl->extra1;
4288c2ecf20Sopenharmony_ci	unsigned int max = *(unsigned int *) ctl->extra2;
4298c2ecf20Sopenharmony_ci	struct ctl_table tbl;
4308c2ecf20Sopenharmony_ci	int ret, new_value;
4318c2ecf20Sopenharmony_ci
4328c2ecf20Sopenharmony_ci	memset(&tbl, 0, sizeof(struct ctl_table));
4338c2ecf20Sopenharmony_ci	tbl.maxlen = sizeof(unsigned int);
4348c2ecf20Sopenharmony_ci
4358c2ecf20Sopenharmony_ci	if (write)
4368c2ecf20Sopenharmony_ci		tbl.data = &new_value;
4378c2ecf20Sopenharmony_ci	else
4388c2ecf20Sopenharmony_ci		tbl.data = &net->sctp.rto_max;
4398c2ecf20Sopenharmony_ci
4408c2ecf20Sopenharmony_ci	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
4418c2ecf20Sopenharmony_ci	if (write && ret == 0) {
4428c2ecf20Sopenharmony_ci		if (new_value > max || new_value < min)
4438c2ecf20Sopenharmony_ci			return -EINVAL;
4448c2ecf20Sopenharmony_ci
4458c2ecf20Sopenharmony_ci		net->sctp.rto_max = new_value;
4468c2ecf20Sopenharmony_ci	}
4478c2ecf20Sopenharmony_ci
4488c2ecf20Sopenharmony_ci	return ret;
4498c2ecf20Sopenharmony_ci}
4508c2ecf20Sopenharmony_ci
4518c2ecf20Sopenharmony_cistatic int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
4528c2ecf20Sopenharmony_ci				   void *buffer, size_t *lenp, loff_t *ppos)
4538c2ecf20Sopenharmony_ci{
4548c2ecf20Sopenharmony_ci	if (write)
4558c2ecf20Sopenharmony_ci		pr_warn_once("Changing rto_alpha or rto_beta may lead to "
4568c2ecf20Sopenharmony_ci			     "suboptimal rtt/srtt estimations!\n");
4578c2ecf20Sopenharmony_ci
4588c2ecf20Sopenharmony_ci	return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos);
4598c2ecf20Sopenharmony_ci}
4608c2ecf20Sopenharmony_ci
4618c2ecf20Sopenharmony_cistatic int proc_sctp_do_auth(struct ctl_table *ctl, int write,
4628c2ecf20Sopenharmony_ci			     void *buffer, size_t *lenp, loff_t *ppos)
4638c2ecf20Sopenharmony_ci{
4648c2ecf20Sopenharmony_ci	struct net *net = current->nsproxy->net_ns;
4658c2ecf20Sopenharmony_ci	struct ctl_table tbl;
4668c2ecf20Sopenharmony_ci	int new_value, ret;
4678c2ecf20Sopenharmony_ci
4688c2ecf20Sopenharmony_ci	memset(&tbl, 0, sizeof(struct ctl_table));
4698c2ecf20Sopenharmony_ci	tbl.maxlen = sizeof(unsigned int);
4708c2ecf20Sopenharmony_ci
4718c2ecf20Sopenharmony_ci	if (write)
4728c2ecf20Sopenharmony_ci		tbl.data = &new_value;
4738c2ecf20Sopenharmony_ci	else
4748c2ecf20Sopenharmony_ci		tbl.data = &net->sctp.auth_enable;
4758c2ecf20Sopenharmony_ci
4768c2ecf20Sopenharmony_ci	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
4778c2ecf20Sopenharmony_ci	if (write && ret == 0) {
4788c2ecf20Sopenharmony_ci		struct sock *sk = net->sctp.ctl_sock;
4798c2ecf20Sopenharmony_ci
4808c2ecf20Sopenharmony_ci		net->sctp.auth_enable = new_value;
4818c2ecf20Sopenharmony_ci		/* Update the value in the control socket */
4828c2ecf20Sopenharmony_ci		lock_sock(sk);
4838c2ecf20Sopenharmony_ci		sctp_sk(sk)->ep->auth_enable = new_value;
4848c2ecf20Sopenharmony_ci		release_sock(sk);
4858c2ecf20Sopenharmony_ci	}
4868c2ecf20Sopenharmony_ci
4878c2ecf20Sopenharmony_ci	return ret;
4888c2ecf20Sopenharmony_ci}
4898c2ecf20Sopenharmony_ci
4908c2ecf20Sopenharmony_ciint sctp_sysctl_net_register(struct net *net)
4918c2ecf20Sopenharmony_ci{
4928c2ecf20Sopenharmony_ci	struct ctl_table *table;
4938c2ecf20Sopenharmony_ci	int i;
4948c2ecf20Sopenharmony_ci
4958c2ecf20Sopenharmony_ci	table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL);
4968c2ecf20Sopenharmony_ci	if (!table)
4978c2ecf20Sopenharmony_ci		return -ENOMEM;
4988c2ecf20Sopenharmony_ci
4998c2ecf20Sopenharmony_ci	for (i = 0; table[i].data; i++)
5008c2ecf20Sopenharmony_ci		table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp;
5018c2ecf20Sopenharmony_ci
5028c2ecf20Sopenharmony_ci	table[SCTP_RTO_MIN_IDX].extra2 = &net->sctp.rto_max;
5038c2ecf20Sopenharmony_ci	table[SCTP_RTO_MAX_IDX].extra1 = &net->sctp.rto_min;
5048c2ecf20Sopenharmony_ci	table[SCTP_PF_RETRANS_IDX].extra2 = &net->sctp.ps_retrans;
5058c2ecf20Sopenharmony_ci	table[SCTP_PS_RETRANS_IDX].extra1 = &net->sctp.pf_retrans;
5068c2ecf20Sopenharmony_ci
5078c2ecf20Sopenharmony_ci	net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table);
5088c2ecf20Sopenharmony_ci	if (net->sctp.sysctl_header == NULL) {
5098c2ecf20Sopenharmony_ci		kfree(table);
5108c2ecf20Sopenharmony_ci		return -ENOMEM;
5118c2ecf20Sopenharmony_ci	}
5128c2ecf20Sopenharmony_ci	return 0;
5138c2ecf20Sopenharmony_ci}
5148c2ecf20Sopenharmony_ci
5158c2ecf20Sopenharmony_civoid sctp_sysctl_net_unregister(struct net *net)
5168c2ecf20Sopenharmony_ci{
5178c2ecf20Sopenharmony_ci	struct ctl_table *table;
5188c2ecf20Sopenharmony_ci
5198c2ecf20Sopenharmony_ci	table = net->sctp.sysctl_header->ctl_table_arg;
5208c2ecf20Sopenharmony_ci	unregister_net_sysctl_table(net->sctp.sysctl_header);
5218c2ecf20Sopenharmony_ci	kfree(table);
5228c2ecf20Sopenharmony_ci}
5238c2ecf20Sopenharmony_ci
5248c2ecf20Sopenharmony_cistatic struct ctl_table_header *sctp_sysctl_header;
5258c2ecf20Sopenharmony_ci
5268c2ecf20Sopenharmony_ci/* Sysctl registration.  */
5278c2ecf20Sopenharmony_civoid sctp_sysctl_register(void)
5288c2ecf20Sopenharmony_ci{
5298c2ecf20Sopenharmony_ci	sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table);
5308c2ecf20Sopenharmony_ci}
5318c2ecf20Sopenharmony_ci
5328c2ecf20Sopenharmony_ci/* Sysctl deregistration.  */
5338c2ecf20Sopenharmony_civoid sctp_sysctl_unregister(void)
5348c2ecf20Sopenharmony_ci{
5358c2ecf20Sopenharmony_ci	unregister_net_sysctl_table(sctp_sysctl_header);
5368c2ecf20Sopenharmony_ci}
537