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;
  39static int udp_port_max = 65535;
  40
  41static unsigned long max_autoclose_min = 0;
  42static unsigned long max_autoclose_max =
  43        (MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX)
  44        ? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ;
  45
  46static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
  47                                 void *buffer, size_t *lenp, loff_t *ppos);
  48static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
  49                                void *buffer, size_t *lenp, loff_t *ppos);
  50static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, void *buffer,
  51                                size_t *lenp, loff_t *ppos);
  52static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write, void *buffer,
  53                                 size_t *lenp, loff_t *ppos);
  54static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
  55                                   void *buffer, size_t *lenp, loff_t *ppos);
  56static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
  57                             void *buffer, size_t *lenp, loff_t *ppos);
  58static int proc_sctp_do_probe_interval(struct ctl_table *ctl, int write,
  59                                       void *buffer, size_t *lenp, 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       = "plpmtud_probe_interval",
 300                .data           = &init_net.sctp.probe_interval,
 301                .maxlen         = sizeof(int),
 302                .mode           = 0644,
 303                .proc_handler   = proc_sctp_do_probe_interval,
 304        },
 305        {
 306                .procname       = "udp_port",
 307                .data           = &init_net.sctp.udp_port,
 308                .maxlen         = sizeof(int),
 309                .mode           = 0644,
 310                .proc_handler   = proc_sctp_do_udp_port,
 311                .extra1         = SYSCTL_ZERO,
 312                .extra2         = &udp_port_max,
 313        },
 314        {
 315                .procname       = "encap_port",
 316                .data           = &init_net.sctp.encap_port,
 317                .maxlen         = sizeof(int),
 318                .mode           = 0644,
 319                .proc_handler   = proc_dointvec_minmax,
 320                .extra1         = SYSCTL_ZERO,
 321                .extra2         = &udp_port_max,
 322        },
 323        {
 324                .procname       = "addr_scope_policy",
 325                .data           = &init_net.sctp.scope_policy,
 326                .maxlen         = sizeof(int),
 327                .mode           = 0644,
 328                .proc_handler   = proc_dointvec_minmax,
 329                .extra1         = SYSCTL_ZERO,
 330                .extra2         = &addr_scope_max,
 331        },
 332        {
 333                .procname       = "rwnd_update_shift",
 334                .data           = &init_net.sctp.rwnd_upd_shift,
 335                .maxlen         = sizeof(int),
 336                .mode           = 0644,
 337                .proc_handler   = &proc_dointvec_minmax,
 338                .extra1         = SYSCTL_ONE,
 339                .extra2         = &rwnd_scale_max,
 340        },
 341        {
 342                .procname       = "max_autoclose",
 343                .data           = &init_net.sctp.max_autoclose,
 344                .maxlen         = sizeof(unsigned long),
 345                .mode           = 0644,
 346                .proc_handler   = &proc_doulongvec_minmax,
 347                .extra1         = &max_autoclose_min,
 348                .extra2         = &max_autoclose_max,
 349        },
 350        {
 351                .procname       = "pf_enable",
 352                .data           = &init_net.sctp.pf_enable,
 353                .maxlen         = sizeof(int),
 354                .mode           = 0644,
 355                .proc_handler   = proc_dointvec,
 356        },
 357        {
 358                .procname       = "pf_expose",
 359                .data           = &init_net.sctp.pf_expose,
 360                .maxlen         = sizeof(int),
 361                .mode           = 0644,
 362                .proc_handler   = proc_dointvec_minmax,
 363                .extra1         = SYSCTL_ZERO,
 364                .extra2         = &pf_expose_max,
 365        },
 366
 367        { /* sentinel */ }
 368};
 369
 370static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
 371                                 void *buffer, size_t *lenp, loff_t *ppos)
 372{
 373        struct net *net = current->nsproxy->net_ns;
 374        struct ctl_table tbl;
 375        bool changed = false;
 376        char *none = "none";
 377        char tmp[8] = {0};
 378        int ret;
 379
 380        memset(&tbl, 0, sizeof(struct ctl_table));
 381
 382        if (write) {
 383                tbl.data = tmp;
 384                tbl.maxlen = sizeof(tmp);
 385        } else {
 386                tbl.data = net->sctp.sctp_hmac_alg ? : none;
 387                tbl.maxlen = strlen(tbl.data);
 388        }
 389
 390        ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
 391        if (write && ret == 0) {
 392#ifdef CONFIG_CRYPTO_MD5
 393                if (!strncmp(tmp, "md5", 3)) {
 394                        net->sctp.sctp_hmac_alg = "md5";
 395                        changed = true;
 396                }
 397#endif
 398#ifdef CONFIG_CRYPTO_SHA1
 399                if (!strncmp(tmp, "sha1", 4)) {
 400                        net->sctp.sctp_hmac_alg = "sha1";
 401                        changed = true;
 402                }
 403#endif
 404                if (!strncmp(tmp, "none", 4)) {
 405                        net->sctp.sctp_hmac_alg = NULL;
 406                        changed = true;
 407                }
 408                if (!changed)
 409                        ret = -EINVAL;
 410        }
 411
 412        return ret;
 413}
 414
 415static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
 416                                void *buffer, size_t *lenp, loff_t *ppos)
 417{
 418        struct net *net = current->nsproxy->net_ns;
 419        unsigned int min = *(unsigned int *) ctl->extra1;
 420        unsigned int max = *(unsigned int *) ctl->extra2;
 421        struct ctl_table tbl;
 422        int ret, new_value;
 423
 424        memset(&tbl, 0, sizeof(struct ctl_table));
 425        tbl.maxlen = sizeof(unsigned int);
 426
 427        if (write)
 428                tbl.data = &new_value;
 429        else
 430                tbl.data = &net->sctp.rto_min;
 431
 432        ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
 433        if (write && ret == 0) {
 434                if (new_value > max || new_value < min)
 435                        return -EINVAL;
 436
 437                net->sctp.rto_min = new_value;
 438        }
 439
 440        return ret;
 441}
 442
 443static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
 444                                void *buffer, size_t *lenp, loff_t *ppos)
 445{
 446        struct net *net = current->nsproxy->net_ns;
 447        unsigned int min = *(unsigned int *) ctl->extra1;
 448        unsigned int max = *(unsigned int *) ctl->extra2;
 449        struct ctl_table tbl;
 450        int ret, new_value;
 451
 452        memset(&tbl, 0, sizeof(struct ctl_table));
 453        tbl.maxlen = sizeof(unsigned int);
 454
 455        if (write)
 456                tbl.data = &new_value;
 457        else
 458                tbl.data = &net->sctp.rto_max;
 459
 460        ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
 461        if (write && ret == 0) {
 462                if (new_value > max || new_value < min)
 463                        return -EINVAL;
 464
 465                net->sctp.rto_max = new_value;
 466        }
 467
 468        return ret;
 469}
 470
 471static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
 472                                   void *buffer, size_t *lenp, loff_t *ppos)
 473{
 474        if (write)
 475                pr_warn_once("Changing rto_alpha or rto_beta may lead to "
 476                             "suboptimal rtt/srtt estimations!\n");
 477
 478        return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos);
 479}
 480
 481static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
 482                             void *buffer, size_t *lenp, loff_t *ppos)
 483{
 484        struct net *net = current->nsproxy->net_ns;
 485        struct ctl_table tbl;
 486        int new_value, ret;
 487
 488        memset(&tbl, 0, sizeof(struct ctl_table));
 489        tbl.maxlen = sizeof(unsigned int);
 490
 491        if (write)
 492                tbl.data = &new_value;
 493        else
 494                tbl.data = &net->sctp.auth_enable;
 495
 496        ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
 497        if (write && ret == 0) {
 498                struct sock *sk = net->sctp.ctl_sock;
 499
 500                net->sctp.auth_enable = new_value;
 501                /* Update the value in the control socket */
 502                lock_sock(sk);
 503                sctp_sk(sk)->ep->auth_enable = new_value;
 504                release_sock(sk);
 505        }
 506
 507        return ret;
 508}
 509
 510static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write,
 511                                 void *buffer, size_t *lenp, loff_t *ppos)
 512{
 513        struct net *net = current->nsproxy->net_ns;
 514        unsigned int min = *(unsigned int *)ctl->extra1;
 515        unsigned int max = *(unsigned int *)ctl->extra2;
 516        struct ctl_table tbl;
 517        int ret, new_value;
 518
 519        memset(&tbl, 0, sizeof(struct ctl_table));
 520        tbl.maxlen = sizeof(unsigned int);
 521
 522        if (write)
 523                tbl.data = &new_value;
 524        else
 525                tbl.data = &net->sctp.udp_port;
 526
 527        ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
 528        if (write && ret == 0) {
 529                struct sock *sk = net->sctp.ctl_sock;
 530
 531                if (new_value > max || new_value < min)
 532                        return -EINVAL;
 533
 534                net->sctp.udp_port = new_value;
 535                sctp_udp_sock_stop(net);
 536                if (new_value) {
 537                        ret = sctp_udp_sock_start(net);
 538                        if (ret)
 539                                net->sctp.udp_port = 0;
 540                }
 541
 542                /* Update the value in the control socket */
 543                lock_sock(sk);
 544                sctp_sk(sk)->udp_port = htons(net->sctp.udp_port);
 545                release_sock(sk);
 546        }
 547
 548        return ret;
 549}
 550
 551static int proc_sctp_do_probe_interval(struct ctl_table *ctl, int write,
 552                                       void *buffer, size_t *lenp, loff_t *ppos)
 553{
 554        struct net *net = current->nsproxy->net_ns;
 555        struct ctl_table tbl;
 556        int ret, new_value;
 557
 558        memset(&tbl, 0, sizeof(struct ctl_table));
 559        tbl.maxlen = sizeof(unsigned int);
 560
 561        if (write)
 562                tbl.data = &new_value;
 563        else
 564                tbl.data = &net->sctp.probe_interval;
 565
 566        ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
 567        if (write && ret == 0) {
 568                if (new_value && new_value < SCTP_PROBE_TIMER_MIN)
 569                        return -EINVAL;
 570
 571                net->sctp.probe_interval = new_value;
 572        }
 573
 574        return ret;
 575}
 576
 577int sctp_sysctl_net_register(struct net *net)
 578{
 579        struct ctl_table *table;
 580        int i;
 581
 582        table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL);
 583        if (!table)
 584                return -ENOMEM;
 585
 586        for (i = 0; table[i].data; i++)
 587                table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp;
 588
 589        net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table);
 590        if (net->sctp.sysctl_header == NULL) {
 591                kfree(table);
 592                return -ENOMEM;
 593        }
 594        return 0;
 595}
 596
 597void sctp_sysctl_net_unregister(struct net *net)
 598{
 599        struct ctl_table *table;
 600
 601        table = net->sctp.sysctl_header->ctl_table_arg;
 602        unregister_net_sysctl_table(net->sctp.sysctl_header);
 603        kfree(table);
 604}
 605
 606static struct ctl_table_header *sctp_sysctl_header;
 607
 608/* Sysctl registration.  */
 609void sctp_sysctl_register(void)
 610{
 611        sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table);
 612}
 613
 614/* Sysctl deregistration.  */
 615void sctp_sysctl_unregister(void)
 616{
 617        unregister_net_sysctl_table(sctp_sysctl_header);
 618}
 619