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