linux/net/sctp/sysctl.c
<<
>>
Prefs
   1/* SCTP kernel implementation
   2 * (C) Copyright IBM Corp. 2002, 2004
   3 * Copyright (c) 2002 Intel Corp.
   4 *
   5 * This file is part of the SCTP kernel implementation
   6 *
   7 * Sysctl related interfaces for SCTP.
   8 *
   9 * This SCTP implementation is free software;
  10 * you can redistribute it and/or modify it under the terms of
  11 * the GNU General Public License as published by
  12 * the Free Software Foundation; either version 2, or (at your option)
  13 * any later version.
  14 *
  15 * This SCTP implementation is distributed in the hope that it
  16 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
  17 *                 ************************
  18 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  19 * See the GNU General Public License for more details.
  20 *
  21 * You should have received a copy of the GNU General Public License
  22 * along with GNU CC; see the file COPYING.  If not, see
  23 * <http://www.gnu.org/licenses/>.
  24 *
  25 * Please send any bug reports or fixes you make to the
  26 * email address(es):
  27 *    lksctp developers <linux-sctp@vger.kernel.org>
  28 *
  29 * Written or modified by:
  30 *    Mingqin Liu           <liuming@us.ibm.com>
  31 *    Jon Grimm             <jgrimm@us.ibm.com>
  32 *    Ardelle Fan           <ardelle.fan@intel.com>
  33 *    Ryan Layer            <rmlayer@us.ibm.com>
  34 *    Sridhar Samudrala     <sri@us.ibm.com>
  35 */
  36
  37#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  38
  39#include <net/sctp/structs.h>
  40#include <net/sctp/sctp.h>
  41#include <linux/sysctl.h>
  42
  43static int timer_max = 86400000; /* ms in one day */
  44static int sack_timer_min = 1;
  45static int sack_timer_max = 500;
  46static int addr_scope_max = SCTP_SCOPE_POLICY_MAX;
  47static int rwnd_scale_max = 16;
  48static int rto_alpha_min = 0;
  49static int rto_beta_min = 0;
  50static int rto_alpha_max = 1000;
  51static int rto_beta_max = 1000;
  52static int pf_expose_max = SCTP_PF_EXPOSE_MAX;
  53static int ps_retrans_max = SCTP_PS_RETRANS_MAX;
  54static int udp_port_max = 65535;
  55
  56static unsigned long max_autoclose_min = 0;
  57static unsigned long max_autoclose_max =
  58        (MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX)
  59        ? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ;
  60
  61static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
  62                                void __user *buffer, size_t *lenp,
  63                                loff_t *ppos);
  64static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
  65                                void __user *buffer, size_t *lenp,
  66                                loff_t *ppos);
  67static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
  68                                void __user *buffer, size_t *lenp,
  69                                loff_t *ppos);
  70static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write,
  71                                 void __user *buffer, size_t *lenp,
  72                                 loff_t *ppos);
  73static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
  74                                   void __user *buffer, size_t *lenp,
  75                                   loff_t *ppos);
  76static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
  77                             void __user *buffer, size_t *lenp,
  78                             loff_t *ppos);
  79static int proc_sctp_do_probe_interval(struct ctl_table *ctl, int write,
  80                                       void __user *buffer, size_t *lenp, loff_t *ppos);
  81
  82static struct ctl_table sctp_table[] = {
  83        {
  84                .procname       = "sctp_mem",
  85                .data           = &sysctl_sctp_mem,
  86                .maxlen         = sizeof(sysctl_sctp_mem),
  87                .mode           = 0644,
  88                .proc_handler   = proc_doulongvec_minmax
  89        },
  90        {
  91                .procname       = "sctp_rmem",
  92                .data           = &sysctl_sctp_rmem,
  93                .maxlen         = sizeof(sysctl_sctp_rmem),
  94                .mode           = 0644,
  95                .proc_handler   = proc_dointvec,
  96        },
  97        {
  98                .procname       = "sctp_wmem",
  99                .data           = &sysctl_sctp_wmem,
 100                .maxlen         = sizeof(sysctl_sctp_wmem),
 101                .mode           = 0644,
 102                .proc_handler   = proc_dointvec,
 103        },
 104
 105        { /* sentinel */ }
 106};
 107
 108static struct ctl_table sctp_net_table[] = {
 109        {
 110                .procname       = "rto_initial",
 111                .data           = &init_net.sctp.rto_initial,
 112                .maxlen         = sizeof(unsigned int),
 113                .mode           = 0644,
 114                .proc_handler   = proc_dointvec_minmax,
 115                .extra1         = SYSCTL_ONE,
 116                .extra2         = &timer_max
 117        },
 118        {
 119                .procname       = "rto_min",
 120                .data           = &init_net.sctp.rto_min,
 121                .maxlen         = sizeof(unsigned int),
 122                .mode           = 0644,
 123                .proc_handler   = proc_sctp_do_rto_min,
 124                .extra1         = SYSCTL_ONE,
 125                .extra2         = &init_net.sctp.rto_max
 126        },
 127        {
 128                .procname       = "rto_max",
 129                .data           = &init_net.sctp.rto_max,
 130                .maxlen         = sizeof(unsigned int),
 131                .mode           = 0644,
 132                .proc_handler   = proc_sctp_do_rto_max,
 133                .extra1         = &init_net.sctp.rto_min,
 134                .extra2         = &timer_max
 135        },
 136        {
 137                .procname       = "rto_alpha_exp_divisor",
 138                .data           = &init_net.sctp.rto_alpha,
 139                .maxlen         = sizeof(int),
 140                .mode           = 0644,
 141                .proc_handler   = proc_sctp_do_alpha_beta,
 142                .extra1         = &rto_alpha_min,
 143                .extra2         = &rto_alpha_max,
 144        },
 145        {
 146                .procname       = "rto_beta_exp_divisor",
 147                .data           = &init_net.sctp.rto_beta,
 148                .maxlen         = sizeof(int),
 149                .mode           = 0644,
 150                .proc_handler   = proc_sctp_do_alpha_beta,
 151                .extra1         = &rto_beta_min,
 152                .extra2         = &rto_beta_max,
 153        },
 154        {
 155                .procname       = "max_burst",
 156                .data           = &init_net.sctp.max_burst,
 157                .maxlen         = sizeof(int),
 158                .mode           = 0644,
 159                .proc_handler   = proc_dointvec_minmax,
 160                .extra1         = SYSCTL_ZERO,
 161                .extra2         = SYSCTL_INT_MAX,
 162        },
 163        {
 164                .procname       = "cookie_preserve_enable",
 165                .data           = &init_net.sctp.cookie_preserve_enable,
 166                .maxlen         = sizeof(int),
 167                .mode           = 0644,
 168                .proc_handler   = proc_dointvec,
 169        },
 170        {
 171                .procname       = "cookie_hmac_alg",
 172                .data           = &init_net.sctp.sctp_hmac_alg,
 173                .maxlen         = 8,
 174                .mode           = 0644,
 175                .proc_handler   = proc_sctp_do_hmac_alg,
 176        },
 177        {
 178                .procname       = "valid_cookie_life",
 179                .data           = &init_net.sctp.valid_cookie_life,
 180                .maxlen         = sizeof(unsigned int),
 181                .mode           = 0644,
 182                .proc_handler   = proc_dointvec_minmax,
 183                .extra1         = SYSCTL_ONE,
 184                .extra2         = &timer_max
 185        },
 186        {
 187                .procname       = "sack_timeout",
 188                .data           = &init_net.sctp.sack_timeout,
 189                .maxlen         = sizeof(int),
 190                .mode           = 0644,
 191                .proc_handler   = proc_dointvec_minmax,
 192                .extra1         = &sack_timer_min,
 193                .extra2         = &sack_timer_max,
 194        },
 195        {
 196                .procname       = "hb_interval",
 197                .data           = &init_net.sctp.hb_interval,
 198                .maxlen         = sizeof(unsigned int),
 199                .mode           = 0644,
 200                .proc_handler   = proc_dointvec_minmax,
 201                .extra1         = SYSCTL_ONE,
 202                .extra2         = &timer_max
 203        },
 204        {
 205                .procname       = "association_max_retrans",
 206                .data           = &init_net.sctp.max_retrans_association,
 207                .maxlen         = sizeof(int),
 208                .mode           = 0644,
 209                .proc_handler   = proc_dointvec_minmax,
 210                .extra1         = SYSCTL_ONE,
 211                .extra2         = SYSCTL_INT_MAX,
 212        },
 213        {
 214                .procname       = "path_max_retrans",
 215                .data           = &init_net.sctp.max_retrans_path,
 216                .maxlen         = sizeof(int),
 217                .mode           = 0644,
 218                .proc_handler   = proc_dointvec_minmax,
 219                .extra1         = SYSCTL_ONE,
 220                .extra2         = SYSCTL_INT_MAX,
 221        },
 222        {
 223                .procname       = "max_init_retransmits",
 224                .data           = &init_net.sctp.max_retrans_init,
 225                .maxlen         = sizeof(int),
 226                .mode           = 0644,
 227                .proc_handler   = proc_dointvec_minmax,
 228                .extra1         = SYSCTL_ONE,
 229                .extra2         = SYSCTL_INT_MAX,
 230        },
 231        {
 232                .procname       = "pf_retrans",
 233                .data           = &init_net.sctp.pf_retrans,
 234                .maxlen         = sizeof(int),
 235                .mode           = 0644,
 236                .proc_handler   = proc_dointvec_minmax,
 237                .extra1         = SYSCTL_ZERO,
 238                .extra2         = &init_net.sctp_ps_retrans,
 239        },
 240        {
 241                .procname       = "ps_retrans",
 242                .data           = &init_net.sctp_ps_retrans,
 243                .maxlen         = sizeof(int),
 244                .mode           = 0644,
 245                .proc_handler   = proc_dointvec_minmax,
 246                .extra1         = &init_net.sctp.pf_retrans,
 247                .extra2         = &ps_retrans_max,
 248        },
 249        {
 250                .procname       = "sndbuf_policy",
 251                .data           = &init_net.sctp.sndbuf_policy,
 252                .maxlen         = sizeof(int),
 253                .mode           = 0644,
 254                .proc_handler   = proc_dointvec,
 255        },
 256        {
 257                .procname       = "rcvbuf_policy",
 258                .data           = &init_net.sctp.rcvbuf_policy,
 259                .maxlen         = sizeof(int),
 260                .mode           = 0644,
 261                .proc_handler   = proc_dointvec,
 262        },
 263        {
 264                .procname       = "default_auto_asconf",
 265                .data           = &init_net.sctp.default_auto_asconf,
 266                .maxlen         = sizeof(int),
 267                .mode           = 0644,
 268                .proc_handler   = proc_dointvec,
 269        },
 270        {
 271                .procname       = "addip_enable",
 272                .data           = &init_net.sctp.addip_enable,
 273                .maxlen         = sizeof(int),
 274                .mode           = 0644,
 275                .proc_handler   = proc_dointvec,
 276        },
 277        {
 278                .procname       = "addip_noauth_enable",
 279                .data           = &init_net.sctp.addip_noauth,
 280                .maxlen         = sizeof(int),
 281                .mode           = 0644,
 282                .proc_handler   = proc_dointvec,
 283        },
 284        {
 285                .procname       = "prsctp_enable",
 286                .data           = &init_net.sctp.prsctp_enable,
 287                .maxlen         = sizeof(int),
 288                .mode           = 0644,
 289                .proc_handler   = proc_dointvec,
 290        },
 291        {
 292                .procname       = "reconf_enable",
 293                .data           = &init_net.sctp.reconf_enable,
 294                .maxlen         = sizeof(int),
 295                .mode           = 0644,
 296                .proc_handler   = proc_dointvec,
 297        },
 298        {
 299                .procname       = "auth_enable",
 300                .data           = &init_net.sctp.auth_enable,
 301                .maxlen         = sizeof(int),
 302                .mode           = 0644,
 303                .proc_handler   = proc_sctp_do_auth,
 304        },
 305        {
 306                .procname       = "intl_enable",
 307                .data           = &init_net.sctp.intl_enable,
 308                .maxlen         = sizeof(int),
 309                .mode           = 0644,
 310                .proc_handler   = proc_dointvec,
 311        },
 312        {
 313                .procname       = "ecn_enable",
 314                .data           = &init_net.sctp_ecn_enable,
 315                .maxlen         = sizeof(int),
 316                .mode           = 0644,
 317                .proc_handler   = proc_dointvec,
 318        },
 319        {
 320                .procname       = "plpmtud_probe_interval",
 321                .data           = &init_net.sctp_probe_interval,
 322                .maxlen         = sizeof(int),
 323                .mode           = 0644,
 324                .proc_handler   = proc_sctp_do_probe_interval,
 325        },
 326        {
 327                .procname       = "udp_port",
 328                .data           = &init_net.sctp_udp_port,
 329                .maxlen         = sizeof(int),
 330                .mode           = 0644,
 331                .proc_handler   = proc_sctp_do_udp_port,
 332                .extra1         = SYSCTL_ZERO,
 333                .extra2         = &udp_port_max,
 334        },
 335        {
 336                .procname       = "encap_port",
 337                .data           = &init_net.sctp_encap_port,
 338                .maxlen         = sizeof(int),
 339                .mode           = 0644,
 340                .proc_handler   = proc_dointvec_minmax,
 341                .extra1         = SYSCTL_ZERO,
 342                .extra2         = &udp_port_max,
 343        },
 344        {
 345                .procname       = "addr_scope_policy",
 346                .data           = &init_net.sctp.scope_policy,
 347                .maxlen         = sizeof(int),
 348                .mode           = 0644,
 349                .proc_handler   = proc_dointvec_minmax,
 350                .extra1         = SYSCTL_ZERO,
 351                .extra2         = &addr_scope_max,
 352        },
 353        {
 354                .procname       = "rwnd_update_shift",
 355                .data           = &init_net.sctp.rwnd_upd_shift,
 356                .maxlen         = sizeof(int),
 357                .mode           = 0644,
 358                .proc_handler   = &proc_dointvec_minmax,
 359                .extra1         = SYSCTL_ONE,
 360                .extra2         = &rwnd_scale_max,
 361        },
 362        {
 363                .procname       = "max_autoclose",
 364                .data           = &init_net.sctp.max_autoclose,
 365                .maxlen         = sizeof(unsigned long),
 366                .mode           = 0644,
 367                .proc_handler   = &proc_doulongvec_minmax,
 368                .extra1         = &max_autoclose_min,
 369                .extra2         = &max_autoclose_max,
 370        },
 371        {
 372                .procname       = "pf_enable",
 373                .data           = &init_net.sctp.pf_enable,
 374                .maxlen         = sizeof(int),
 375                .mode           = 0644,
 376                .proc_handler   = proc_dointvec,
 377        },
 378        {
 379                .procname       = "pf_expose",
 380                .data           = &init_net.sctp_pf_expose,
 381                .maxlen         = sizeof(int),
 382                .mode           = 0644,
 383                .proc_handler   = proc_dointvec_minmax,
 384                .extra1         = SYSCTL_ZERO,
 385                .extra2         = &pf_expose_max,
 386        },
 387
 388        { /* sentinel */ }
 389};
 390
 391static int proc_sctp_do_hmac_alg(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        struct ctl_table tbl;
 397        bool changed = false;
 398        char *none = "none";
 399        char tmp[8] = {0};
 400        int ret;
 401
 402        memset(&tbl, 0, sizeof(struct ctl_table));
 403
 404        if (write) {
 405                tbl.data = tmp;
 406                tbl.maxlen = sizeof(tmp);
 407        } else {
 408                tbl.data = net->sctp.sctp_hmac_alg ? : none;
 409                tbl.maxlen = strlen(tbl.data);
 410        }
 411
 412        ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
 413        if (write && ret == 0) {
 414#ifdef CONFIG_CRYPTO_MD5
 415                if (!strncmp(tmp, "md5", 3)) {
 416                        net->sctp.sctp_hmac_alg = "md5";
 417                        changed = true;
 418                }
 419#endif
 420#ifdef CONFIG_CRYPTO_SHA1
 421                if (!strncmp(tmp, "sha1", 4)) {
 422                        net->sctp.sctp_hmac_alg = "sha1";
 423                        changed = true;
 424                }
 425#endif
 426                if (!strncmp(tmp, "none", 4)) {
 427                        net->sctp.sctp_hmac_alg = NULL;
 428                        changed = true;
 429                }
 430                if (!changed)
 431                        ret = -EINVAL;
 432        }
 433
 434        return ret;
 435}
 436
 437static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
 438                                void __user *buffer, size_t *lenp,
 439                                loff_t *ppos)
 440{
 441        struct net *net = current->nsproxy->net_ns;
 442        unsigned int min = *(unsigned int *) ctl->extra1;
 443        unsigned int max = *(unsigned int *) ctl->extra2;
 444        struct ctl_table tbl;
 445        int ret, new_value;
 446
 447        memset(&tbl, 0, sizeof(struct ctl_table));
 448        tbl.maxlen = sizeof(unsigned int);
 449
 450        if (write)
 451                tbl.data = &new_value;
 452        else
 453                tbl.data = &net->sctp.rto_min;
 454
 455        ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
 456        if (write && ret == 0) {
 457                if (new_value > max || new_value < min)
 458                        return -EINVAL;
 459
 460                net->sctp.rto_min = new_value;
 461        }
 462
 463        return ret;
 464}
 465
 466static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
 467                                void __user *buffer, size_t *lenp,
 468                                loff_t *ppos)
 469{
 470        struct net *net = current->nsproxy->net_ns;
 471        unsigned int min = *(unsigned int *) ctl->extra1;
 472        unsigned int max = *(unsigned int *) ctl->extra2;
 473        struct ctl_table tbl;
 474        int ret, new_value;
 475
 476        memset(&tbl, 0, sizeof(struct ctl_table));
 477        tbl.maxlen = sizeof(unsigned int);
 478
 479        if (write)
 480                tbl.data = &new_value;
 481        else
 482                tbl.data = &net->sctp.rto_max;
 483
 484        ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
 485        if (write && ret == 0) {
 486                if (new_value > max || new_value < min)
 487                        return -EINVAL;
 488
 489                net->sctp.rto_max = new_value;
 490        }
 491
 492        return ret;
 493}
 494
 495static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
 496                                   void __user *buffer, size_t *lenp,
 497                                   loff_t *ppos)
 498{
 499        if (write)
 500                pr_warn_once("Changing rto_alpha or rto_beta may lead to "
 501                             "suboptimal rtt/srtt estimations!\n");
 502
 503        return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos);
 504}
 505
 506static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
 507                             void __user *buffer, size_t *lenp,
 508                             loff_t *ppos)
 509{
 510        struct net *net = current->nsproxy->net_ns;
 511        struct ctl_table tbl;
 512        int new_value, ret;
 513
 514        memset(&tbl, 0, sizeof(struct ctl_table));
 515        tbl.maxlen = sizeof(unsigned int);
 516
 517        if (write)
 518                tbl.data = &new_value;
 519        else
 520                tbl.data = &net->sctp.auth_enable;
 521
 522        ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
 523        if (write && ret == 0) {
 524                struct sock *sk = net->sctp.ctl_sock;
 525
 526                net->sctp.auth_enable = new_value;
 527                /* Update the value in the control socket */
 528                lock_sock(sk);
 529                sctp_sk(sk)->ep->auth_enable = new_value;
 530                release_sock(sk);
 531        }
 532
 533        return ret;
 534}
 535
 536static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write,
 537                                 void *buffer, size_t *lenp, loff_t *ppos)
 538{
 539        struct net *net = current->nsproxy->net_ns;
 540        unsigned int min = *(unsigned int *)ctl->extra1;
 541        unsigned int max = *(unsigned int *)ctl->extra2;
 542        struct ctl_table tbl;
 543        int ret, new_value;
 544
 545        memset(&tbl, 0, sizeof(struct ctl_table));
 546        tbl.maxlen = sizeof(unsigned int);
 547
 548        if (write)
 549                tbl.data = &new_value;
 550        else
 551                tbl.data = &net->sctp_udp_port;
 552
 553        ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
 554        if (write && ret == 0) {
 555                struct sock *sk = net->sctp.ctl_sock;
 556
 557                if (new_value > max || new_value < min)
 558                        return -EINVAL;
 559
 560                net->sctp_udp_port = new_value;
 561                sctp_udp_sock_stop(net);
 562                if (new_value) {
 563                        ret = sctp_udp_sock_start(net);
 564                        if (ret)
 565                                net->sctp_udp_port = 0;
 566                }
 567
 568                /* Update the value in the control socket */
 569                lock_sock(sk);
 570                sctp_sk(sk)->udp_port = htons(net->sctp_udp_port);
 571                release_sock(sk);
 572        }
 573
 574        return ret;
 575}
 576
 577static int proc_sctp_do_probe_interval(struct ctl_table *ctl, int write,
 578                                       void __user *buffer, size_t *lenp, loff_t *ppos)
 579{
 580        struct net *net = current->nsproxy->net_ns;
 581        struct ctl_table tbl;
 582        int ret, new_value;
 583
 584        memset(&tbl, 0, sizeof(struct ctl_table));
 585        tbl.maxlen = sizeof(unsigned int);
 586
 587        if (write)
 588                tbl.data = &new_value;
 589        else
 590                tbl.data = &net->sctp_probe_interval;
 591
 592        ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
 593        if (write && ret == 0) {
 594                if (new_value && new_value < SCTP_PROBE_TIMER_MIN)
 595                        return -EINVAL;
 596
 597                net->sctp_probe_interval = new_value;
 598        }
 599
 600        return ret;
 601}
 602
 603int sctp_sysctl_net_register(struct net *net)
 604{
 605        struct ctl_table *table;
 606        int i;
 607
 608        table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL);
 609        if (!table)
 610                return -ENOMEM;
 611
 612        for (i = 0; table[i].data; i++)
 613                table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp;
 614
 615        net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table);
 616        if (net->sctp.sysctl_header == NULL) {
 617                kfree(table);
 618                return -ENOMEM;
 619        }
 620        return 0;
 621}
 622
 623void sctp_sysctl_net_unregister(struct net *net)
 624{
 625        struct ctl_table *table;
 626
 627        table = net->sctp.sysctl_header->ctl_table_arg;
 628        unregister_net_sysctl_table(net->sctp.sysctl_header);
 629        kfree(table);
 630}
 631
 632static struct ctl_table_header *sctp_sysctl_header;
 633
 634/* Sysctl registration.  */
 635void sctp_sysctl_register(void)
 636{
 637        sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table);
 638}
 639
 640/* Sysctl deregistration.  */
 641void sctp_sysctl_unregister(void)
 642{
 643        unregister_net_sysctl_table(sctp_sysctl_header);
 644}
 645