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