147505b8bSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 260c778b2SVlad Yasevich /* SCTP kernel implementation 31da177e4SLinus Torvalds * (C) Copyright IBM Corp. 2002, 2004 41da177e4SLinus Torvalds * Copyright (c) 2002 Intel Corp. 51da177e4SLinus Torvalds * 660c778b2SVlad Yasevich * This file is part of the SCTP kernel implementation 71da177e4SLinus Torvalds * 81da177e4SLinus Torvalds * Sysctl related interfaces for SCTP. 91da177e4SLinus Torvalds * 101da177e4SLinus Torvalds * Please send any bug reports or fixes you make to the 111da177e4SLinus Torvalds * email address(es): 1291705c61SDaniel Borkmann * lksctp developers <linux-sctp@vger.kernel.org> 131da177e4SLinus Torvalds * 141da177e4SLinus Torvalds * Written or modified by: 151da177e4SLinus Torvalds * Mingqin Liu <liuming@us.ibm.com> 161da177e4SLinus Torvalds * Jon Grimm <jgrimm@us.ibm.com> 171da177e4SLinus Torvalds * Ardelle Fan <ardelle.fan@intel.com> 181da177e4SLinus Torvalds * Ryan Layer <rmlayer@us.ibm.com> 191da177e4SLinus Torvalds * Sridhar Samudrala <sri@us.ibm.com> 201da177e4SLinus Torvalds */ 211da177e4SLinus Torvalds 22b58537a1SDaniel Borkmann #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 23b58537a1SDaniel Borkmann 241da177e4SLinus Torvalds #include <net/sctp/structs.h> 258c5955d8SAdrian Bunk #include <net/sctp/sctp.h> 261da177e4SLinus Torvalds #include <linux/sysctl.h> 271da177e4SLinus Torvalds 283fd091e7SVladislav Yasevich static int zero = 0; 293fd091e7SVladislav Yasevich static int one = 1; 303fd091e7SVladislav Yasevich static int timer_max = 86400000; /* ms in one day */ 313fd091e7SVladislav Yasevich static int int_max = INT_MAX; 32d48e074dSJean-Mickael Guerin static int sack_timer_min = 1; 33d48e074dSJean-Mickael Guerin static int sack_timer_max = 500; 34701ef3e6SXin Long static int addr_scope_max = SCTP_SCOPE_POLICY_MAX; 3590f2f531SVlad Yasevich static int rwnd_scale_max = 16; 36b58537a1SDaniel Borkmann static int rto_alpha_min = 0; 37b58537a1SDaniel Borkmann static int rto_beta_min = 0; 38b58537a1SDaniel Borkmann static int rto_alpha_max = 1000; 39b58537a1SDaniel Borkmann static int rto_beta_max = 1000; 40b58537a1SDaniel Borkmann 412692ba61SXi Wang static unsigned long max_autoclose_min = 0; 422692ba61SXi Wang static unsigned long max_autoclose_max = 432692ba61SXi Wang (MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX) 442692ba61SXi Wang ? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ; 451da177e4SLinus Torvalds 46b486b228Swangweidong static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, 473c68198eSNeil Horman void __user *buffer, size_t *lenp, 483c68198eSNeil Horman loff_t *ppos); 494f3fdf3bSwangweidong static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, 504f3fdf3bSwangweidong void __user *buffer, size_t *lenp, 514f3fdf3bSwangweidong loff_t *ppos); 524f3fdf3bSwangweidong static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, 534f3fdf3bSwangweidong void __user *buffer, size_t *lenp, 544f3fdf3bSwangweidong loff_t *ppos); 55b58537a1SDaniel Borkmann static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write, 56b58537a1SDaniel Borkmann void __user *buffer, size_t *lenp, 57b58537a1SDaniel Borkmann loff_t *ppos); 58b14878ccSVlad Yasevich static int proc_sctp_do_auth(struct ctl_table *ctl, int write, 59b14878ccSVlad Yasevich void __user *buffer, size_t *lenp, 60b14878ccSVlad Yasevich loff_t *ppos); 614f3fdf3bSwangweidong 62fe2c6338SJoe Perches static struct ctl_table sctp_table[] = { 631da177e4SLinus Torvalds { 644d93df0aSNeil Horman .procname = "sctp_mem", 654d93df0aSNeil Horman .data = &sysctl_sctp_mem, 664d93df0aSNeil Horman .maxlen = sizeof(sysctl_sctp_mem), 674d93df0aSNeil Horman .mode = 0644, 688d987e5cSEric Dumazet .proc_handler = proc_doulongvec_minmax 694d93df0aSNeil Horman }, 704d93df0aSNeil Horman { 714d93df0aSNeil Horman .procname = "sctp_rmem", 724d93df0aSNeil Horman .data = &sysctl_sctp_rmem, 734d93df0aSNeil Horman .maxlen = sizeof(sysctl_sctp_rmem), 744d93df0aSNeil Horman .mode = 0644, 756d9f239aSAlexey Dobriyan .proc_handler = proc_dointvec, 764d93df0aSNeil Horman }, 774d93df0aSNeil Horman { 784d93df0aSNeil Horman .procname = "sctp_wmem", 794d93df0aSNeil Horman .data = &sysctl_sctp_wmem, 804d93df0aSNeil Horman .maxlen = sizeof(sysctl_sctp_wmem), 814d93df0aSNeil Horman .mode = 0644, 826d9f239aSAlexey Dobriyan .proc_handler = proc_dointvec, 834d93df0aSNeil Horman }, 84e1fc3b14SEric W. Biederman 85e1fc3b14SEric W. Biederman { /* sentinel */ } 86e1fc3b14SEric W. Biederman }; 87e1fc3b14SEric W. Biederman 88fe2c6338SJoe Perches static struct ctl_table sctp_net_table[] = { 89a29a5bd4SVlad Yasevich { 90e1fc3b14SEric W. Biederman .procname = "rto_initial", 91e1fc3b14SEric W. Biederman .data = &init_net.sctp.rto_initial, 92e1fc3b14SEric W. Biederman .maxlen = sizeof(unsigned int), 93e1fc3b14SEric W. Biederman .mode = 0644, 94e1fc3b14SEric W. Biederman .proc_handler = proc_dointvec_minmax, 95e1fc3b14SEric W. Biederman .extra1 = &one, 96e1fc3b14SEric W. Biederman .extra2 = &timer_max 97e1fc3b14SEric W. Biederman }, 98e1fc3b14SEric W. Biederman { 99e1fc3b14SEric W. Biederman .procname = "rto_min", 100e1fc3b14SEric W. Biederman .data = &init_net.sctp.rto_min, 101e1fc3b14SEric W. Biederman .maxlen = sizeof(unsigned int), 102e1fc3b14SEric W. Biederman .mode = 0644, 1034f3fdf3bSwangweidong .proc_handler = proc_sctp_do_rto_min, 104e1fc3b14SEric W. Biederman .extra1 = &one, 1054f3fdf3bSwangweidong .extra2 = &init_net.sctp.rto_max 106e1fc3b14SEric W. Biederman }, 107e1fc3b14SEric W. Biederman { 108e1fc3b14SEric W. Biederman .procname = "rto_max", 109e1fc3b14SEric W. Biederman .data = &init_net.sctp.rto_max, 110e1fc3b14SEric W. Biederman .maxlen = sizeof(unsigned int), 111e1fc3b14SEric W. Biederman .mode = 0644, 1124f3fdf3bSwangweidong .proc_handler = proc_sctp_do_rto_max, 1134f3fdf3bSwangweidong .extra1 = &init_net.sctp.rto_min, 114e1fc3b14SEric W. Biederman .extra2 = &timer_max 115e1fc3b14SEric W. Biederman }, 116e1fc3b14SEric W. Biederman { 117e1fc3b14SEric W. Biederman .procname = "rto_alpha_exp_divisor", 118e1fc3b14SEric W. Biederman .data = &init_net.sctp.rto_alpha, 119e1fc3b14SEric W. Biederman .maxlen = sizeof(int), 120b58537a1SDaniel Borkmann .mode = 0644, 121b58537a1SDaniel Borkmann .proc_handler = proc_sctp_do_alpha_beta, 122b58537a1SDaniel Borkmann .extra1 = &rto_alpha_min, 123b58537a1SDaniel Borkmann .extra2 = &rto_alpha_max, 124e1fc3b14SEric W. Biederman }, 125e1fc3b14SEric W. Biederman { 126e1fc3b14SEric W. Biederman .procname = "rto_beta_exp_divisor", 127e1fc3b14SEric W. Biederman .data = &init_net.sctp.rto_beta, 128e1fc3b14SEric W. Biederman .maxlen = sizeof(int), 129b58537a1SDaniel Borkmann .mode = 0644, 130b58537a1SDaniel Borkmann .proc_handler = proc_sctp_do_alpha_beta, 131b58537a1SDaniel Borkmann .extra1 = &rto_beta_min, 132b58537a1SDaniel Borkmann .extra2 = &rto_beta_max, 133e1fc3b14SEric W. Biederman }, 134e1fc3b14SEric W. Biederman { 135e1fc3b14SEric W. Biederman .procname = "max_burst", 136e1fc3b14SEric W. Biederman .data = &init_net.sctp.max_burst, 137e1fc3b14SEric W. Biederman .maxlen = sizeof(int), 138e1fc3b14SEric W. Biederman .mode = 0644, 139e1fc3b14SEric W. Biederman .proc_handler = proc_dointvec_minmax, 140e1fc3b14SEric W. Biederman .extra1 = &zero, 141e1fc3b14SEric W. Biederman .extra2 = &int_max 142e1fc3b14SEric W. Biederman }, 143e1fc3b14SEric W. Biederman { 144e1fc3b14SEric W. Biederman .procname = "cookie_preserve_enable", 145e1fc3b14SEric W. Biederman .data = &init_net.sctp.cookie_preserve_enable, 146e1fc3b14SEric W. Biederman .maxlen = sizeof(int), 147e1fc3b14SEric W. Biederman .mode = 0644, 148e1fc3b14SEric W. Biederman .proc_handler = proc_dointvec, 149e1fc3b14SEric W. Biederman }, 150e1fc3b14SEric W. Biederman { 1513c68198eSNeil Horman .procname = "cookie_hmac_alg", 15222a1f514Swangweidong .data = &init_net.sctp.sctp_hmac_alg, 1533c68198eSNeil Horman .maxlen = 8, 1543c68198eSNeil Horman .mode = 0644, 1553c68198eSNeil Horman .proc_handler = proc_sctp_do_hmac_alg, 1563c68198eSNeil Horman }, 1573c68198eSNeil Horman { 158e1fc3b14SEric W. Biederman .procname = "valid_cookie_life", 159e1fc3b14SEric W. Biederman .data = &init_net.sctp.valid_cookie_life, 160e1fc3b14SEric W. Biederman .maxlen = sizeof(unsigned int), 161e1fc3b14SEric W. Biederman .mode = 0644, 162e1fc3b14SEric W. Biederman .proc_handler = proc_dointvec_minmax, 163e1fc3b14SEric W. Biederman .extra1 = &one, 164e1fc3b14SEric W. Biederman .extra2 = &timer_max 165e1fc3b14SEric W. Biederman }, 166e1fc3b14SEric W. Biederman { 167e1fc3b14SEric W. Biederman .procname = "sack_timeout", 168e1fc3b14SEric W. Biederman .data = &init_net.sctp.sack_timeout, 169e1fc3b14SEric W. Biederman .maxlen = sizeof(int), 170e1fc3b14SEric W. Biederman .mode = 0644, 171e1fc3b14SEric W. Biederman .proc_handler = proc_dointvec_minmax, 172e1fc3b14SEric W. Biederman .extra1 = &sack_timer_min, 173e1fc3b14SEric W. Biederman .extra2 = &sack_timer_max, 174e1fc3b14SEric W. Biederman }, 175e1fc3b14SEric W. Biederman { 176e1fc3b14SEric W. Biederman .procname = "hb_interval", 177e1fc3b14SEric W. Biederman .data = &init_net.sctp.hb_interval, 178e1fc3b14SEric W. Biederman .maxlen = sizeof(unsigned int), 179e1fc3b14SEric W. Biederman .mode = 0644, 180e1fc3b14SEric W. Biederman .proc_handler = proc_dointvec_minmax, 181e1fc3b14SEric W. Biederman .extra1 = &one, 182e1fc3b14SEric W. Biederman .extra2 = &timer_max 183e1fc3b14SEric W. Biederman }, 184e1fc3b14SEric W. Biederman { 185e1fc3b14SEric W. Biederman .procname = "association_max_retrans", 186e1fc3b14SEric W. Biederman .data = &init_net.sctp.max_retrans_association, 187e1fc3b14SEric W. Biederman .maxlen = sizeof(int), 188e1fc3b14SEric W. Biederman .mode = 0644, 189e1fc3b14SEric W. Biederman .proc_handler = proc_dointvec_minmax, 190e1fc3b14SEric W. Biederman .extra1 = &one, 191e1fc3b14SEric W. Biederman .extra2 = &int_max 192e1fc3b14SEric W. Biederman }, 193e1fc3b14SEric W. Biederman { 194e1fc3b14SEric W. Biederman .procname = "path_max_retrans", 195e1fc3b14SEric W. Biederman .data = &init_net.sctp.max_retrans_path, 196e1fc3b14SEric W. Biederman .maxlen = sizeof(int), 197e1fc3b14SEric W. Biederman .mode = 0644, 198e1fc3b14SEric W. Biederman .proc_handler = proc_dointvec_minmax, 199e1fc3b14SEric W. Biederman .extra1 = &one, 200e1fc3b14SEric W. Biederman .extra2 = &int_max 201e1fc3b14SEric W. Biederman }, 202e1fc3b14SEric W. Biederman { 203e1fc3b14SEric W. Biederman .procname = "max_init_retransmits", 204e1fc3b14SEric W. Biederman .data = &init_net.sctp.max_retrans_init, 205e1fc3b14SEric W. Biederman .maxlen = sizeof(int), 206e1fc3b14SEric W. Biederman .mode = 0644, 207e1fc3b14SEric W. Biederman .proc_handler = proc_dointvec_minmax, 208e1fc3b14SEric W. Biederman .extra1 = &one, 209e1fc3b14SEric W. Biederman .extra2 = &int_max 210e1fc3b14SEric W. Biederman }, 211e1fc3b14SEric W. Biederman { 212e1fc3b14SEric W. Biederman .procname = "pf_retrans", 213e1fc3b14SEric W. Biederman .data = &init_net.sctp.pf_retrans, 214e1fc3b14SEric W. Biederman .maxlen = sizeof(int), 215e1fc3b14SEric W. Biederman .mode = 0644, 216e1fc3b14SEric W. Biederman .proc_handler = proc_dointvec_minmax, 217e1fc3b14SEric W. Biederman .extra1 = &zero, 218e1fc3b14SEric W. Biederman .extra2 = &int_max 219e1fc3b14SEric W. Biederman }, 220e1fc3b14SEric W. Biederman { 221e1fc3b14SEric W. Biederman .procname = "sndbuf_policy", 222e1fc3b14SEric W. Biederman .data = &init_net.sctp.sndbuf_policy, 223e1fc3b14SEric W. Biederman .maxlen = sizeof(int), 224e1fc3b14SEric W. Biederman .mode = 0644, 225e1fc3b14SEric W. Biederman .proc_handler = proc_dointvec, 226e1fc3b14SEric W. Biederman }, 227e1fc3b14SEric W. Biederman { 228e1fc3b14SEric W. Biederman .procname = "rcvbuf_policy", 229e1fc3b14SEric W. Biederman .data = &init_net.sctp.rcvbuf_policy, 230e1fc3b14SEric W. Biederman .maxlen = sizeof(int), 231e1fc3b14SEric W. Biederman .mode = 0644, 232e1fc3b14SEric W. Biederman .proc_handler = proc_dointvec, 233e1fc3b14SEric W. Biederman }, 234e1fc3b14SEric W. Biederman { 235e1fc3b14SEric W. Biederman .procname = "default_auto_asconf", 236e1fc3b14SEric W. Biederman .data = &init_net.sctp.default_auto_asconf, 237e1fc3b14SEric W. Biederman .maxlen = sizeof(int), 238e1fc3b14SEric W. Biederman .mode = 0644, 239e1fc3b14SEric W. Biederman .proc_handler = proc_dointvec, 240e1fc3b14SEric W. Biederman }, 241e1fc3b14SEric W. Biederman { 242e1fc3b14SEric W. Biederman .procname = "addip_enable", 243e1fc3b14SEric W. Biederman .data = &init_net.sctp.addip_enable, 244a29a5bd4SVlad Yasevich .maxlen = sizeof(int), 245a29a5bd4SVlad Yasevich .mode = 0644, 2466d9f239aSAlexey Dobriyan .proc_handler = proc_dointvec, 247a29a5bd4SVlad Yasevich }, 24873d9c4fdSVlad Yasevich { 24973d9c4fdSVlad Yasevich .procname = "addip_noauth_enable", 250e1fc3b14SEric W. Biederman .data = &init_net.sctp.addip_noauth, 251e1fc3b14SEric W. Biederman .maxlen = sizeof(int), 252e1fc3b14SEric W. Biederman .mode = 0644, 253e1fc3b14SEric W. Biederman .proc_handler = proc_dointvec, 254e1fc3b14SEric W. Biederman }, 255e1fc3b14SEric W. Biederman { 256e1fc3b14SEric W. Biederman .procname = "prsctp_enable", 257e1fc3b14SEric W. Biederman .data = &init_net.sctp.prsctp_enable, 258e1fc3b14SEric W. Biederman .maxlen = sizeof(int), 259e1fc3b14SEric W. Biederman .mode = 0644, 260e1fc3b14SEric W. Biederman .proc_handler = proc_dointvec, 261e1fc3b14SEric W. Biederman }, 262e1fc3b14SEric W. Biederman { 263c0d8bab6SXin Long .procname = "reconf_enable", 264c0d8bab6SXin Long .data = &init_net.sctp.reconf_enable, 265c0d8bab6SXin Long .maxlen = sizeof(int), 266c0d8bab6SXin Long .mode = 0644, 267c0d8bab6SXin Long .proc_handler = proc_dointvec, 268c0d8bab6SXin Long }, 269c0d8bab6SXin Long { 270e1fc3b14SEric W. Biederman .procname = "auth_enable", 271e1fc3b14SEric W. Biederman .data = &init_net.sctp.auth_enable, 27273d9c4fdSVlad Yasevich .maxlen = sizeof(int), 27373d9c4fdSVlad Yasevich .mode = 0644, 274b14878ccSVlad Yasevich .proc_handler = proc_sctp_do_auth, 27573d9c4fdSVlad Yasevich }, 27672388433SBhaskar Dutta { 277463118c3SXin Long .procname = "intl_enable", 278463118c3SXin Long .data = &init_net.sctp.intl_enable, 279463118c3SXin Long .maxlen = sizeof(int), 280463118c3SXin Long .mode = 0644, 281463118c3SXin Long .proc_handler = proc_dointvec, 282463118c3SXin Long }, 283463118c3SXin Long { 28472388433SBhaskar Dutta .procname = "addr_scope_policy", 285e1fc3b14SEric W. Biederman .data = &init_net.sctp.scope_policy, 28672388433SBhaskar Dutta .maxlen = sizeof(int), 28772388433SBhaskar Dutta .mode = 0644, 2886d456111SEric W. Biederman .proc_handler = proc_dointvec_minmax, 28972388433SBhaskar Dutta .extra1 = &zero, 29072388433SBhaskar Dutta .extra2 = &addr_scope_max, 29172388433SBhaskar Dutta }, 29290f2f531SVlad Yasevich { 29390f2f531SVlad Yasevich .procname = "rwnd_update_shift", 294e1fc3b14SEric W. Biederman .data = &init_net.sctp.rwnd_upd_shift, 29590f2f531SVlad Yasevich .maxlen = sizeof(int), 29690f2f531SVlad Yasevich .mode = 0644, 29790f2f531SVlad Yasevich .proc_handler = &proc_dointvec_minmax, 29890f2f531SVlad Yasevich .extra1 = &one, 29990f2f531SVlad Yasevich .extra2 = &rwnd_scale_max, 30090f2f531SVlad Yasevich }, 3012692ba61SXi Wang { 3022692ba61SXi Wang .procname = "max_autoclose", 303e1fc3b14SEric W. Biederman .data = &init_net.sctp.max_autoclose, 3042692ba61SXi Wang .maxlen = sizeof(unsigned long), 3052692ba61SXi Wang .mode = 0644, 3062692ba61SXi Wang .proc_handler = &proc_doulongvec_minmax, 3072692ba61SXi Wang .extra1 = &max_autoclose_min, 3082692ba61SXi Wang .extra2 = &max_autoclose_max, 3092692ba61SXi Wang }, 310566178f8SZhu Yanjun { 311566178f8SZhu Yanjun .procname = "pf_enable", 312566178f8SZhu Yanjun .data = &init_net.sctp.pf_enable, 313566178f8SZhu Yanjun .maxlen = sizeof(int), 314566178f8SZhu Yanjun .mode = 0644, 315566178f8SZhu Yanjun .proc_handler = proc_dointvec, 316566178f8SZhu Yanjun }, 31771acc0ddSDavid S. Miller 318d7fc02c7SLinus Torvalds { /* sentinel */ } 3191da177e4SLinus Torvalds }; 3201da177e4SLinus Torvalds 321b486b228Swangweidong static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, 3223c68198eSNeil Horman void __user *buffer, size_t *lenp, 3233c68198eSNeil Horman loff_t *ppos) 3243c68198eSNeil Horman { 3253c68198eSNeil Horman struct net *net = current->nsproxy->net_ns; 326fe2c6338SJoe Perches struct ctl_table tbl; 327ff5e92c1SDaniel Borkmann bool changed = false; 3283c68198eSNeil Horman char *none = "none"; 329320f1a4aSSasha Levin char tmp[8] = {0}; 330ff5e92c1SDaniel Borkmann int ret; 3313c68198eSNeil Horman 3323c68198eSNeil Horman memset(&tbl, 0, sizeof(struct ctl_table)); 3333c68198eSNeil Horman 3343c68198eSNeil Horman if (write) { 3353c68198eSNeil Horman tbl.data = tmp; 336ff5e92c1SDaniel Borkmann tbl.maxlen = sizeof(tmp); 3373c68198eSNeil Horman } else { 3383c68198eSNeil Horman tbl.data = net->sctp.sctp_hmac_alg ? : none; 3393c68198eSNeil Horman tbl.maxlen = strlen(tbl.data); 3403c68198eSNeil Horman } 3413c68198eSNeil Horman 342ff5e92c1SDaniel Borkmann ret = proc_dostring(&tbl, write, buffer, lenp, ppos); 343ff5e92c1SDaniel Borkmann if (write && ret == 0) { 3443c68198eSNeil Horman #ifdef CONFIG_CRYPTO_MD5 3453c68198eSNeil Horman if (!strncmp(tmp, "md5", 3)) { 3463c68198eSNeil Horman net->sctp.sctp_hmac_alg = "md5"; 347ff5e92c1SDaniel Borkmann changed = true; 3483c68198eSNeil Horman } 3493c68198eSNeil Horman #endif 3503c68198eSNeil Horman #ifdef CONFIG_CRYPTO_SHA1 3513c68198eSNeil Horman if (!strncmp(tmp, "sha1", 4)) { 3523c68198eSNeil Horman net->sctp.sctp_hmac_alg = "sha1"; 353ff5e92c1SDaniel Borkmann changed = true; 3543c68198eSNeil Horman } 3553c68198eSNeil Horman #endif 3563c68198eSNeil Horman if (!strncmp(tmp, "none", 4)) { 3573c68198eSNeil Horman net->sctp.sctp_hmac_alg = NULL; 358ff5e92c1SDaniel Borkmann changed = true; 3593c68198eSNeil Horman } 3603c68198eSNeil Horman if (!changed) 3613c68198eSNeil Horman ret = -EINVAL; 3623c68198eSNeil Horman } 3633c68198eSNeil Horman 3643c68198eSNeil Horman return ret; 3653c68198eSNeil Horman } 3663c68198eSNeil Horman 3674f3fdf3bSwangweidong static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, 3684f3fdf3bSwangweidong void __user *buffer, size_t *lenp, 3694f3fdf3bSwangweidong loff_t *ppos) 3704f3fdf3bSwangweidong { 3714f3fdf3bSwangweidong struct net *net = current->nsproxy->net_ns; 3724f3fdf3bSwangweidong unsigned int min = *(unsigned int *) ctl->extra1; 3734f3fdf3bSwangweidong unsigned int max = *(unsigned int *) ctl->extra2; 374ff5e92c1SDaniel Borkmann struct ctl_table tbl; 375ff5e92c1SDaniel Borkmann int ret, new_value; 3764f3fdf3bSwangweidong 3774f3fdf3bSwangweidong memset(&tbl, 0, sizeof(struct ctl_table)); 3784f3fdf3bSwangweidong tbl.maxlen = sizeof(unsigned int); 3794f3fdf3bSwangweidong 3804f3fdf3bSwangweidong if (write) 3814f3fdf3bSwangweidong tbl.data = &new_value; 3824f3fdf3bSwangweidong else 3834f3fdf3bSwangweidong tbl.data = &net->sctp.rto_min; 384ff5e92c1SDaniel Borkmann 3854f3fdf3bSwangweidong ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 386ff5e92c1SDaniel Borkmann if (write && ret == 0) { 387ff5e92c1SDaniel Borkmann if (new_value > max || new_value < min) 3884f3fdf3bSwangweidong return -EINVAL; 389ff5e92c1SDaniel Borkmann 3904f3fdf3bSwangweidong net->sctp.rto_min = new_value; 3914f3fdf3bSwangweidong } 392ff5e92c1SDaniel Borkmann 3934f3fdf3bSwangweidong return ret; 3944f3fdf3bSwangweidong } 3954f3fdf3bSwangweidong 3964f3fdf3bSwangweidong static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, 3974f3fdf3bSwangweidong void __user *buffer, size_t *lenp, 3984f3fdf3bSwangweidong loff_t *ppos) 3994f3fdf3bSwangweidong { 4004f3fdf3bSwangweidong struct net *net = current->nsproxy->net_ns; 4014f3fdf3bSwangweidong unsigned int min = *(unsigned int *) ctl->extra1; 4024f3fdf3bSwangweidong unsigned int max = *(unsigned int *) ctl->extra2; 403ff5e92c1SDaniel Borkmann struct ctl_table tbl; 404ff5e92c1SDaniel Borkmann int ret, new_value; 4054f3fdf3bSwangweidong 4064f3fdf3bSwangweidong memset(&tbl, 0, sizeof(struct ctl_table)); 4074f3fdf3bSwangweidong tbl.maxlen = sizeof(unsigned int); 4084f3fdf3bSwangweidong 4094f3fdf3bSwangweidong if (write) 4104f3fdf3bSwangweidong tbl.data = &new_value; 4114f3fdf3bSwangweidong else 4124f3fdf3bSwangweidong tbl.data = &net->sctp.rto_max; 413ff5e92c1SDaniel Borkmann 4144f3fdf3bSwangweidong ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 415ff5e92c1SDaniel Borkmann if (write && ret == 0) { 416ff5e92c1SDaniel Borkmann if (new_value > max || new_value < min) 4174f3fdf3bSwangweidong return -EINVAL; 418ff5e92c1SDaniel Borkmann 4194f3fdf3bSwangweidong net->sctp.rto_max = new_value; 4204f3fdf3bSwangweidong } 421ff5e92c1SDaniel Borkmann 4224f3fdf3bSwangweidong return ret; 4234f3fdf3bSwangweidong } 4244f3fdf3bSwangweidong 425b58537a1SDaniel Borkmann static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write, 426b58537a1SDaniel Borkmann void __user *buffer, size_t *lenp, 427b58537a1SDaniel Borkmann loff_t *ppos) 428b58537a1SDaniel Borkmann { 429eaea2da7SDaniel Borkmann if (write) 430b58537a1SDaniel Borkmann pr_warn_once("Changing rto_alpha or rto_beta may lead to " 431b58537a1SDaniel Borkmann "suboptimal rtt/srtt estimations!\n"); 432b58537a1SDaniel Borkmann 433b58537a1SDaniel Borkmann return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos); 434b58537a1SDaniel Borkmann } 435b58537a1SDaniel Borkmann 436b14878ccSVlad Yasevich static int proc_sctp_do_auth(struct ctl_table *ctl, int write, 437b14878ccSVlad Yasevich void __user *buffer, size_t *lenp, 438b14878ccSVlad Yasevich loff_t *ppos) 439b14878ccSVlad Yasevich { 440b14878ccSVlad Yasevich struct net *net = current->nsproxy->net_ns; 441b14878ccSVlad Yasevich struct ctl_table tbl; 442b14878ccSVlad Yasevich int new_value, ret; 443b14878ccSVlad Yasevich 444b14878ccSVlad Yasevich memset(&tbl, 0, sizeof(struct ctl_table)); 445b14878ccSVlad Yasevich tbl.maxlen = sizeof(unsigned int); 446b14878ccSVlad Yasevich 447b14878ccSVlad Yasevich if (write) 448b14878ccSVlad Yasevich tbl.data = &new_value; 449b14878ccSVlad Yasevich else 450b14878ccSVlad Yasevich tbl.data = &net->sctp.auth_enable; 451b14878ccSVlad Yasevich 452b14878ccSVlad Yasevich ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); 45324599e61SDaniel Borkmann if (write && ret == 0) { 454b14878ccSVlad Yasevich struct sock *sk = net->sctp.ctl_sock; 455b14878ccSVlad Yasevich 456b14878ccSVlad Yasevich net->sctp.auth_enable = new_value; 457b14878ccSVlad Yasevich /* Update the value in the control socket */ 458b14878ccSVlad Yasevich lock_sock(sk); 459b14878ccSVlad Yasevich sctp_sk(sk)->ep->auth_enable = new_value; 460b14878ccSVlad Yasevich release_sock(sk); 461b14878ccSVlad Yasevich } 462b14878ccSVlad Yasevich 463b14878ccSVlad Yasevich return ret; 464b14878ccSVlad Yasevich } 465b14878ccSVlad Yasevich 466ebb7e95dSEric W. Biederman int sctp_sysctl_net_register(struct net *net) 467ebb7e95dSEric W. Biederman { 468eb9f3705Swangweidong struct ctl_table *table; 469e1fc3b14SEric W. Biederman int i; 470ebb7e95dSEric W. Biederman 471ebb7e95dSEric W. Biederman table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL); 472ebb7e95dSEric W. Biederman if (!table) 473ebb7e95dSEric W. Biederman return -ENOMEM; 474ebb7e95dSEric W. Biederman 475e1fc3b14SEric W. Biederman for (i = 0; table[i].data; i++) 476e1fc3b14SEric W. Biederman table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp; 477e1fc3b14SEric W. Biederman 478ebb7e95dSEric W. Biederman net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table); 479f66138c8Swangweidong if (net->sctp.sysctl_header == NULL) { 480f66138c8Swangweidong kfree(table); 481f66138c8Swangweidong return -ENOMEM; 482f66138c8Swangweidong } 483ebb7e95dSEric W. Biederman return 0; 484ebb7e95dSEric W. Biederman } 485ebb7e95dSEric W. Biederman 486ebb7e95dSEric W. Biederman void sctp_sysctl_net_unregister(struct net *net) 487ebb7e95dSEric W. Biederman { 4885f19d121SVlad Yasevich struct ctl_table *table; 4895f19d121SVlad Yasevich 4905f19d121SVlad Yasevich table = net->sctp.sysctl_header->ctl_table_arg; 491ebb7e95dSEric W. Biederman unregister_net_sysctl_table(net->sctp.sysctl_header); 4925f19d121SVlad Yasevich kfree(table); 493ebb7e95dSEric W. Biederman } 494ebb7e95dSEric W. Biederman 4951da177e4SLinus Torvalds static struct ctl_table_header *sctp_sysctl_header; 4961da177e4SLinus Torvalds 4971da177e4SLinus Torvalds /* Sysctl registration. */ 4981da177e4SLinus Torvalds void sctp_sysctl_register(void) 4991da177e4SLinus Torvalds { 500ec8f23ceSEric W. Biederman sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table); 5011da177e4SLinus Torvalds } 5021da177e4SLinus Torvalds 5031da177e4SLinus Torvalds /* Sysctl deregistration. */ 5041da177e4SLinus Torvalds void sctp_sysctl_unregister(void) 5051da177e4SLinus Torvalds { 5065dd3df10SEric W. Biederman unregister_net_sysctl_table(sctp_sysctl_header); 5071da177e4SLinus Torvalds } 508