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 = SCTP_SCOPE_POLICY_MAX;
  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       = "intl_enable",
 293                .data           = &init_net.sctp.intl_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         = &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         = &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        { /* sentinel */ }
 334};
 335
 336static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
 337                                void __user *buffer, size_t *lenp,
 338                                loff_t *ppos)
 339{
 340        struct net *net = current->nsproxy->net_ns;
 341        struct ctl_table tbl;
 342        bool changed = false;
 343        char *none = "none";
 344        char tmp[8] = {0};
 345        int ret;
 346
 347        memset(&tbl, 0, sizeof(struct ctl_table));
 348
 349        if (write) {
 350                tbl.data = tmp;
 351                tbl.maxlen = sizeof(tmp);
 352        } else {
 353                tbl.data = net->sctp.sctp_hmac_alg ? : none;
 354                tbl.maxlen = strlen(tbl.data);
 355        }
 356
 357        ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
 358        if (write && ret == 0) {
 359#ifdef CONFIG_CRYPTO_MD5
 360                if (!strncmp(tmp, "md5", 3)) {
 361                        net->sctp.sctp_hmac_alg = "md5";
 362                        changed = true;
 363                }
 364#endif
 365#ifdef CONFIG_CRYPTO_SHA1
 366                if (!strncmp(tmp, "sha1", 4)) {
 367                        net->sctp.sctp_hmac_alg = "sha1";
 368                        changed = true;
 369                }
 370#endif
 371                if (!strncmp(tmp, "none", 4)) {
 372                        net->sctp.sctp_hmac_alg = NULL;
 373                        changed = true;
 374                }
 375                if (!changed)
 376                        ret = -EINVAL;
 377        }
 378
 379        return ret;
 380}
 381
 382static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
 383                                void __user *buffer, size_t *lenp,
 384                                loff_t *ppos)
 385{
 386        struct net *net = current->nsproxy->net_ns;
 387        unsigned int min = *(unsigned int *) ctl->extra1;
 388        unsigned int max = *(unsigned int *) ctl->extra2;
 389        struct ctl_table tbl;
 390        int ret, new_value;
 391
 392        memset(&tbl, 0, sizeof(struct ctl_table));
 393        tbl.maxlen = sizeof(unsigned int);
 394
 395        if (write)
 396                tbl.data = &new_value;
 397        else
 398                tbl.data = &net->sctp.rto_min;
 399
 400        ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
 401        if (write && ret == 0) {
 402                if (new_value > max || new_value < min)
 403                        return -EINVAL;
 404
 405                net->sctp.rto_min = new_value;
 406        }
 407
 408        return ret;
 409}
 410
 411static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
 412                                void __user *buffer, size_t *lenp,
 413                                loff_t *ppos)
 414{
 415        struct net *net = current->nsproxy->net_ns;
 416        unsigned int min = *(unsigned int *) ctl->extra1;
 417        unsigned int max = *(unsigned int *) ctl->extra2;
 418        struct ctl_table tbl;
 419        int ret, new_value;
 420
 421        memset(&tbl, 0, sizeof(struct ctl_table));
 422        tbl.maxlen = sizeof(unsigned int);
 423
 424        if (write)
 425                tbl.data = &new_value;
 426        else
 427                tbl.data = &net->sctp.rto_max;
 428
 429        ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
 430        if (write && ret == 0) {
 431                if (new_value > max || new_value < min)
 432                        return -EINVAL;
 433
 434                net->sctp.rto_max = new_value;
 435        }
 436
 437        return ret;
 438}
 439
 440static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
 441                                   void __user *buffer, size_t *lenp,
 442                                   loff_t *ppos)
 443{
 444        if (write)
 445                pr_warn_once("Changing rto_alpha or rto_beta may lead to "
 446                             "suboptimal rtt/srtt estimations!\n");
 447
 448        return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos);
 449}
 450
 451static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
 452                             void __user *buffer, size_t *lenp,
 453                             loff_t *ppos)
 454{
 455        struct net *net = current->nsproxy->net_ns;
 456        struct ctl_table tbl;
 457        int new_value, ret;
 458
 459        memset(&tbl, 0, sizeof(struct ctl_table));
 460        tbl.maxlen = sizeof(unsigned int);
 461
 462        if (write)
 463                tbl.data = &new_value;
 464        else
 465                tbl.data = &net->sctp.auth_enable;
 466
 467        ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
 468        if (write && ret == 0) {
 469                struct sock *sk = net->sctp.ctl_sock;
 470
 471                net->sctp.auth_enable = new_value;
 472                /* Update the value in the control socket */
 473                lock_sock(sk);
 474                sctp_sk(sk)->ep->auth_enable = new_value;
 475                release_sock(sk);
 476        }
 477
 478        return ret;
 479}
 480
 481int sctp_sysctl_net_register(struct net *net)
 482{
 483        struct ctl_table *table;
 484        int i;
 485
 486        table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL);
 487        if (!table)
 488                return -ENOMEM;
 489
 490        for (i = 0; table[i].data; i++)
 491                table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp;
 492
 493        net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table);
 494        if (net->sctp.sysctl_header == NULL) {
 495                kfree(table);
 496                return -ENOMEM;
 497        }
 498        return 0;
 499}
 500
 501void sctp_sysctl_net_unregister(struct net *net)
 502{
 503        struct ctl_table *table;
 504
 505        table = net->sctp.sysctl_header->ctl_table_arg;
 506        unregister_net_sysctl_table(net->sctp.sysctl_header);
 507        kfree(table);
 508}
 509
 510static struct ctl_table_header *sctp_sysctl_header;
 511
 512/* Sysctl registration.  */
 513void sctp_sysctl_register(void)
 514{
 515        sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table);
 516}
 517
 518/* Sysctl deregistration.  */
 519void sctp_sysctl_unregister(void)
 520{
 521        unregister_net_sysctl_table(sctp_sysctl_header);
 522}
 523