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