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