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