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       = "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       = "addr_scope_policy",
 286                .data           = &init_net.sctp.scope_policy,
 287                .maxlen         = sizeof(int),
 288                .mode           = 0644,
 289                .proc_handler   = proc_dointvec_minmax,
 290                .extra1         = &zero,
 291                .extra2         = &addr_scope_max,
 292        },
 293        {
 294                .procname       = "rwnd_update_shift",
 295                .data           = &init_net.sctp.rwnd_upd_shift,
 296                .maxlen         = sizeof(int),
 297                .mode           = 0644,
 298                .proc_handler   = &proc_dointvec_minmax,
 299                .extra1         = &one,
 300                .extra2         = &rwnd_scale_max,
 301        },
 302        {
 303                .procname       = "max_autoclose",
 304                .data           = &init_net.sctp.max_autoclose,
 305                .maxlen         = sizeof(unsigned long),
 306                .mode           = 0644,
 307                .proc_handler   = &proc_doulongvec_minmax,
 308                .extra1         = &max_autoclose_min,
 309                .extra2         = &max_autoclose_max,
 310        },
 311        {
 312                .procname       = "pf_enable",
 313                .data           = &init_net.sctp.pf_enable,
 314                .maxlen         = sizeof(int),
 315                .mode           = 0644,
 316                .proc_handler   = proc_dointvec,
 317        },
 318
 319        { /* sentinel */ }
 320};
 321
 322static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
 323                                void __user *buffer, size_t *lenp,
 324                                loff_t *ppos)
 325{
 326        struct net *net = current->nsproxy->net_ns;
 327        struct ctl_table tbl;
 328        bool changed = false;
 329        char *none = "none";
 330        char tmp[8] = {0};
 331        int ret;
 332
 333        memset(&tbl, 0, sizeof(struct ctl_table));
 334
 335        if (write) {
 336                tbl.data = tmp;
 337                tbl.maxlen = sizeof(tmp);
 338        } else {
 339                tbl.data = net->sctp.sctp_hmac_alg ? : none;
 340                tbl.maxlen = strlen(tbl.data);
 341        }
 342
 343        ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
 344        if (write && ret == 0) {
 345#ifdef CONFIG_CRYPTO_MD5
 346                if (!strncmp(tmp, "md5", 3)) {
 347                        net->sctp.sctp_hmac_alg = "md5";
 348                        changed = true;
 349                }
 350#endif
 351#ifdef CONFIG_CRYPTO_SHA1
 352                if (!strncmp(tmp, "sha1", 4)) {
 353                        net->sctp.sctp_hmac_alg = "sha1";
 354                        changed = true;
 355                }
 356#endif
 357                if (!strncmp(tmp, "none", 4)) {
 358                        net->sctp.sctp_hmac_alg = NULL;
 359                        changed = true;
 360                }
 361                if (!changed)
 362                        ret = -EINVAL;
 363        }
 364
 365        return ret;
 366}
 367
 368static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
 369                                void __user *buffer, size_t *lenp,
 370                                loff_t *ppos)
 371{
 372        struct net *net = current->nsproxy->net_ns;
 373        unsigned int min = *(unsigned int *) ctl->extra1;
 374        unsigned int max = *(unsigned int *) ctl->extra2;
 375        struct ctl_table tbl;
 376        int ret, new_value;
 377
 378        memset(&tbl, 0, sizeof(struct ctl_table));
 379        tbl.maxlen = sizeof(unsigned int);
 380
 381        if (write)
 382                tbl.data = &new_value;
 383        else
 384                tbl.data = &net->sctp.rto_min;
 385
 386        ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
 387        if (write && ret == 0) {
 388                if (new_value > max || new_value < min)
 389                        return -EINVAL;
 390
 391                net->sctp.rto_min = new_value;
 392        }
 393
 394        return ret;
 395}
 396
 397static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
 398                                void __user *buffer, size_t *lenp,
 399                                loff_t *ppos)
 400{
 401        struct net *net = current->nsproxy->net_ns;
 402        unsigned int min = *(unsigned int *) ctl->extra1;
 403        unsigned int max = *(unsigned int *) ctl->extra2;
 404        struct ctl_table tbl;
 405        int ret, new_value;
 406
 407        memset(&tbl, 0, sizeof(struct ctl_table));
 408        tbl.maxlen = sizeof(unsigned int);
 409
 410        if (write)
 411                tbl.data = &new_value;
 412        else
 413                tbl.data = &net->sctp.rto_max;
 414
 415        ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
 416        if (write && ret == 0) {
 417                if (new_value > max || new_value < min)
 418                        return -EINVAL;
 419
 420                net->sctp.rto_max = new_value;
 421        }
 422
 423        return ret;
 424}
 425
 426static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
 427                                   void __user *buffer, size_t *lenp,
 428                                   loff_t *ppos)
 429{
 430        if (write)
 431                pr_warn_once("Changing rto_alpha or rto_beta may lead to "
 432                             "suboptimal rtt/srtt estimations!\n");
 433
 434        return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos);
 435}
 436
 437static int proc_sctp_do_auth(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        struct ctl_table tbl;
 443        int new_value, ret;
 444
 445        memset(&tbl, 0, sizeof(struct ctl_table));
 446        tbl.maxlen = sizeof(unsigned int);
 447
 448        if (write)
 449                tbl.data = &new_value;
 450        else
 451                tbl.data = &net->sctp.auth_enable;
 452
 453        ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
 454        if (write && ret == 0) {
 455                struct sock *sk = net->sctp.ctl_sock;
 456
 457                net->sctp.auth_enable = new_value;
 458                /* Update the value in the control socket */
 459                lock_sock(sk);
 460                sctp_sk(sk)->ep->auth_enable = new_value;
 461                release_sock(sk);
 462        }
 463
 464        return ret;
 465}
 466
 467int sctp_sysctl_net_register(struct net *net)
 468{
 469        struct ctl_table *table;
 470        int i;
 471
 472        table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL);
 473        if (!table)
 474                return -ENOMEM;
 475
 476        for (i = 0; table[i].data; i++)
 477                table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp;
 478
 479        net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table);
 480        if (net->sctp.sysctl_header == NULL) {
 481                kfree(table);
 482                return -ENOMEM;
 483        }
 484        return 0;
 485}
 486
 487void sctp_sysctl_net_unregister(struct net *net)
 488{
 489        struct ctl_table *table;
 490
 491        table = net->sctp.sysctl_header->ctl_table_arg;
 492        unregister_net_sysctl_table(net->sctp.sysctl_header);
 493        kfree(table);
 494}
 495
 496static struct ctl_table_header *sctp_sysctl_header;
 497
 498/* Sysctl registration.  */
 499void sctp_sysctl_register(void)
 500{
 501        sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table);
 502}
 503
 504/* Sysctl deregistration.  */
 505void sctp_sysctl_unregister(void)
 506{
 507        unregister_net_sysctl_table(sctp_sysctl_header);
 508}
 509