Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /* SCTP kernel implementation
0003  * (C) Copyright IBM Corp. 2002, 2004
0004  * Copyright (c) 2002 Intel Corp.
0005  *
0006  * This file is part of the SCTP kernel implementation
0007  *
0008  * Sysctl related interfaces for SCTP.
0009  *
0010  * Please send any bug reports or fixes you make to the
0011  * email address(es):
0012  *    lksctp developers <linux-sctp@vger.kernel.org>
0013  *
0014  * Written or modified by:
0015  *    Mingqin Liu           <liuming@us.ibm.com>
0016  *    Jon Grimm             <jgrimm@us.ibm.com>
0017  *    Ardelle Fan           <ardelle.fan@intel.com>
0018  *    Ryan Layer            <rmlayer@us.ibm.com>
0019  *    Sridhar Samudrala     <sri@us.ibm.com>
0020  */
0021 
0022 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0023 
0024 #include <net/sctp/structs.h>
0025 #include <net/sctp/sctp.h>
0026 #include <linux/sysctl.h>
0027 
0028 static int timer_max = 86400000; /* ms in one day */
0029 static int sack_timer_min = 1;
0030 static int sack_timer_max = 500;
0031 static int addr_scope_max = SCTP_SCOPE_POLICY_MAX;
0032 static int rwnd_scale_max = 16;
0033 static int rto_alpha_min = 0;
0034 static int rto_beta_min = 0;
0035 static int rto_alpha_max = 1000;
0036 static int rto_beta_max = 1000;
0037 static int pf_expose_max = SCTP_PF_EXPOSE_MAX;
0038 static int ps_retrans_max = SCTP_PS_RETRANS_MAX;
0039 static int udp_port_max = 65535;
0040 
0041 static unsigned long max_autoclose_min = 0;
0042 static unsigned long max_autoclose_max =
0043     (MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX)
0044     ? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ;
0045 
0046 static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
0047                  void *buffer, size_t *lenp, loff_t *ppos);
0048 static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
0049                 void *buffer, size_t *lenp, loff_t *ppos);
0050 static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, void *buffer,
0051                 size_t *lenp, loff_t *ppos);
0052 static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write, void *buffer,
0053                  size_t *lenp, loff_t *ppos);
0054 static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
0055                    void *buffer, size_t *lenp, loff_t *ppos);
0056 static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
0057                  void *buffer, size_t *lenp, loff_t *ppos);
0058 static int proc_sctp_do_probe_interval(struct ctl_table *ctl, int write,
0059                        void *buffer, size_t *lenp, loff_t *ppos);
0060 
0061 static struct ctl_table sctp_table[] = {
0062     {
0063         .procname   = "sctp_mem",
0064         .data       = &sysctl_sctp_mem,
0065         .maxlen     = sizeof(sysctl_sctp_mem),
0066         .mode       = 0644,
0067         .proc_handler   = proc_doulongvec_minmax
0068     },
0069     {
0070         .procname   = "sctp_rmem",
0071         .data       = &sysctl_sctp_rmem,
0072         .maxlen     = sizeof(sysctl_sctp_rmem),
0073         .mode       = 0644,
0074         .proc_handler   = proc_dointvec,
0075     },
0076     {
0077         .procname   = "sctp_wmem",
0078         .data       = &sysctl_sctp_wmem,
0079         .maxlen     = sizeof(sysctl_sctp_wmem),
0080         .mode       = 0644,
0081         .proc_handler   = proc_dointvec,
0082     },
0083 
0084     { /* sentinel */ }
0085 };
0086 
0087 static struct ctl_table sctp_net_table[] = {
0088     {
0089         .procname   = "rto_initial",
0090         .data       = &init_net.sctp.rto_initial,
0091         .maxlen     = sizeof(unsigned int),
0092         .mode       = 0644,
0093         .proc_handler   = proc_dointvec_minmax,
0094         .extra1         = SYSCTL_ONE,
0095         .extra2         = &timer_max
0096     },
0097     {
0098         .procname   = "rto_min",
0099         .data       = &init_net.sctp.rto_min,
0100         .maxlen     = sizeof(unsigned int),
0101         .mode       = 0644,
0102         .proc_handler   = proc_sctp_do_rto_min,
0103         .extra1         = SYSCTL_ONE,
0104         .extra2         = &init_net.sctp.rto_max
0105     },
0106     {
0107         .procname   = "rto_max",
0108         .data       = &init_net.sctp.rto_max,
0109         .maxlen     = sizeof(unsigned int),
0110         .mode       = 0644,
0111         .proc_handler   = proc_sctp_do_rto_max,
0112         .extra1         = &init_net.sctp.rto_min,
0113         .extra2         = &timer_max
0114     },
0115     {
0116         .procname   = "rto_alpha_exp_divisor",
0117         .data       = &init_net.sctp.rto_alpha,
0118         .maxlen     = sizeof(int),
0119         .mode       = 0644,
0120         .proc_handler   = proc_sctp_do_alpha_beta,
0121         .extra1     = &rto_alpha_min,
0122         .extra2     = &rto_alpha_max,
0123     },
0124     {
0125         .procname   = "rto_beta_exp_divisor",
0126         .data       = &init_net.sctp.rto_beta,
0127         .maxlen     = sizeof(int),
0128         .mode       = 0644,
0129         .proc_handler   = proc_sctp_do_alpha_beta,
0130         .extra1     = &rto_beta_min,
0131         .extra2     = &rto_beta_max,
0132     },
0133     {
0134         .procname   = "max_burst",
0135         .data       = &init_net.sctp.max_burst,
0136         .maxlen     = sizeof(int),
0137         .mode       = 0644,
0138         .proc_handler   = proc_dointvec_minmax,
0139         .extra1     = SYSCTL_ZERO,
0140         .extra2     = SYSCTL_INT_MAX,
0141     },
0142     {
0143         .procname   = "cookie_preserve_enable",
0144         .data       = &init_net.sctp.cookie_preserve_enable,
0145         .maxlen     = sizeof(int),
0146         .mode       = 0644,
0147         .proc_handler   = proc_dointvec,
0148     },
0149     {
0150         .procname   = "cookie_hmac_alg",
0151         .data       = &init_net.sctp.sctp_hmac_alg,
0152         .maxlen     = 8,
0153         .mode       = 0644,
0154         .proc_handler   = proc_sctp_do_hmac_alg,
0155     },
0156     {
0157         .procname   = "valid_cookie_life",
0158         .data       = &init_net.sctp.valid_cookie_life,
0159         .maxlen     = sizeof(unsigned int),
0160         .mode       = 0644,
0161         .proc_handler   = proc_dointvec_minmax,
0162         .extra1         = SYSCTL_ONE,
0163         .extra2         = &timer_max
0164     },
0165     {
0166         .procname   = "sack_timeout",
0167         .data       = &init_net.sctp.sack_timeout,
0168         .maxlen     = sizeof(int),
0169         .mode       = 0644,
0170         .proc_handler   = proc_dointvec_minmax,
0171         .extra1         = &sack_timer_min,
0172         .extra2         = &sack_timer_max,
0173     },
0174     {
0175         .procname   = "hb_interval",
0176         .data       = &init_net.sctp.hb_interval,
0177         .maxlen     = sizeof(unsigned int),
0178         .mode       = 0644,
0179         .proc_handler   = proc_dointvec_minmax,
0180         .extra1         = SYSCTL_ONE,
0181         .extra2         = &timer_max
0182     },
0183     {
0184         .procname   = "association_max_retrans",
0185         .data       = &init_net.sctp.max_retrans_association,
0186         .maxlen     = sizeof(int),
0187         .mode       = 0644,
0188         .proc_handler   = proc_dointvec_minmax,
0189         .extra1     = SYSCTL_ONE,
0190         .extra2     = SYSCTL_INT_MAX,
0191     },
0192     {
0193         .procname   = "path_max_retrans",
0194         .data       = &init_net.sctp.max_retrans_path,
0195         .maxlen     = sizeof(int),
0196         .mode       = 0644,
0197         .proc_handler   = proc_dointvec_minmax,
0198         .extra1     = SYSCTL_ONE,
0199         .extra2     = SYSCTL_INT_MAX,
0200     },
0201     {
0202         .procname   = "max_init_retransmits",
0203         .data       = &init_net.sctp.max_retrans_init,
0204         .maxlen     = sizeof(int),
0205         .mode       = 0644,
0206         .proc_handler   = proc_dointvec_minmax,
0207         .extra1     = SYSCTL_ONE,
0208         .extra2     = SYSCTL_INT_MAX,
0209     },
0210     {
0211         .procname   = "pf_retrans",
0212         .data       = &init_net.sctp.pf_retrans,
0213         .maxlen     = sizeof(int),
0214         .mode       = 0644,
0215         .proc_handler   = proc_dointvec_minmax,
0216         .extra1     = SYSCTL_ZERO,
0217         .extra2     = &init_net.sctp.ps_retrans,
0218     },
0219     {
0220         .procname   = "ps_retrans",
0221         .data       = &init_net.sctp.ps_retrans,
0222         .maxlen     = sizeof(int),
0223         .mode       = 0644,
0224         .proc_handler   = proc_dointvec_minmax,
0225         .extra1     = &init_net.sctp.pf_retrans,
0226         .extra2     = &ps_retrans_max,
0227     },
0228     {
0229         .procname   = "sndbuf_policy",
0230         .data       = &init_net.sctp.sndbuf_policy,
0231         .maxlen     = sizeof(int),
0232         .mode       = 0644,
0233         .proc_handler   = proc_dointvec,
0234     },
0235     {
0236         .procname   = "rcvbuf_policy",
0237         .data       = &init_net.sctp.rcvbuf_policy,
0238         .maxlen     = sizeof(int),
0239         .mode       = 0644,
0240         .proc_handler   = proc_dointvec,
0241     },
0242     {
0243         .procname   = "default_auto_asconf",
0244         .data       = &init_net.sctp.default_auto_asconf,
0245         .maxlen     = sizeof(int),
0246         .mode       = 0644,
0247         .proc_handler   = proc_dointvec,
0248     },
0249     {
0250         .procname   = "addip_enable",
0251         .data       = &init_net.sctp.addip_enable,
0252         .maxlen     = sizeof(int),
0253         .mode       = 0644,
0254         .proc_handler   = proc_dointvec,
0255     },
0256     {
0257         .procname   = "addip_noauth_enable",
0258         .data       = &init_net.sctp.addip_noauth,
0259         .maxlen     = sizeof(int),
0260         .mode       = 0644,
0261         .proc_handler   = proc_dointvec,
0262     },
0263     {
0264         .procname   = "prsctp_enable",
0265         .data       = &init_net.sctp.prsctp_enable,
0266         .maxlen     = sizeof(int),
0267         .mode       = 0644,
0268         .proc_handler   = proc_dointvec,
0269     },
0270     {
0271         .procname   = "reconf_enable",
0272         .data       = &init_net.sctp.reconf_enable,
0273         .maxlen     = sizeof(int),
0274         .mode       = 0644,
0275         .proc_handler   = proc_dointvec,
0276     },
0277     {
0278         .procname   = "auth_enable",
0279         .data       = &init_net.sctp.auth_enable,
0280         .maxlen     = sizeof(int),
0281         .mode       = 0644,
0282         .proc_handler   = proc_sctp_do_auth,
0283     },
0284     {
0285         .procname   = "intl_enable",
0286         .data       = &init_net.sctp.intl_enable,
0287         .maxlen     = sizeof(int),
0288         .mode       = 0644,
0289         .proc_handler   = proc_dointvec,
0290     },
0291     {
0292         .procname   = "ecn_enable",
0293         .data       = &init_net.sctp.ecn_enable,
0294         .maxlen     = sizeof(int),
0295         .mode       = 0644,
0296         .proc_handler   = proc_dointvec,
0297     },
0298     {
0299         .procname   = "plpmtud_probe_interval",
0300         .data       = &init_net.sctp.probe_interval,
0301         .maxlen     = sizeof(int),
0302         .mode       = 0644,
0303         .proc_handler   = proc_sctp_do_probe_interval,
0304     },
0305     {
0306         .procname   = "udp_port",
0307         .data       = &init_net.sctp.udp_port,
0308         .maxlen     = sizeof(int),
0309         .mode       = 0644,
0310         .proc_handler   = proc_sctp_do_udp_port,
0311         .extra1     = SYSCTL_ZERO,
0312         .extra2     = &udp_port_max,
0313     },
0314     {
0315         .procname   = "encap_port",
0316         .data       = &init_net.sctp.encap_port,
0317         .maxlen     = sizeof(int),
0318         .mode       = 0644,
0319         .proc_handler   = proc_dointvec_minmax,
0320         .extra1     = SYSCTL_ZERO,
0321         .extra2     = &udp_port_max,
0322     },
0323     {
0324         .procname   = "addr_scope_policy",
0325         .data       = &init_net.sctp.scope_policy,
0326         .maxlen     = sizeof(int),
0327         .mode       = 0644,
0328         .proc_handler   = proc_dointvec_minmax,
0329         .extra1     = SYSCTL_ZERO,
0330         .extra2     = &addr_scope_max,
0331     },
0332     {
0333         .procname   = "rwnd_update_shift",
0334         .data       = &init_net.sctp.rwnd_upd_shift,
0335         .maxlen     = sizeof(int),
0336         .mode       = 0644,
0337         .proc_handler   = &proc_dointvec_minmax,
0338         .extra1     = SYSCTL_ONE,
0339         .extra2     = &rwnd_scale_max,
0340     },
0341     {
0342         .procname   = "max_autoclose",
0343         .data       = &init_net.sctp.max_autoclose,
0344         .maxlen     = sizeof(unsigned long),
0345         .mode       = 0644,
0346         .proc_handler   = &proc_doulongvec_minmax,
0347         .extra1     = &max_autoclose_min,
0348         .extra2     = &max_autoclose_max,
0349     },
0350     {
0351         .procname   = "pf_enable",
0352         .data       = &init_net.sctp.pf_enable,
0353         .maxlen     = sizeof(int),
0354         .mode       = 0644,
0355         .proc_handler   = proc_dointvec,
0356     },
0357     {
0358         .procname   = "pf_expose",
0359         .data       = &init_net.sctp.pf_expose,
0360         .maxlen     = sizeof(int),
0361         .mode       = 0644,
0362         .proc_handler   = proc_dointvec_minmax,
0363         .extra1     = SYSCTL_ZERO,
0364         .extra2     = &pf_expose_max,
0365     },
0366 
0367     { /* sentinel */ }
0368 };
0369 
0370 static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
0371                  void *buffer, size_t *lenp, loff_t *ppos)
0372 {
0373     struct net *net = current->nsproxy->net_ns;
0374     struct ctl_table tbl;
0375     bool changed = false;
0376     char *none = "none";
0377     char tmp[8] = {0};
0378     int ret;
0379 
0380     memset(&tbl, 0, sizeof(struct ctl_table));
0381 
0382     if (write) {
0383         tbl.data = tmp;
0384         tbl.maxlen = sizeof(tmp);
0385     } else {
0386         tbl.data = net->sctp.sctp_hmac_alg ? : none;
0387         tbl.maxlen = strlen(tbl.data);
0388     }
0389 
0390     ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
0391     if (write && ret == 0) {
0392 #ifdef CONFIG_CRYPTO_MD5
0393         if (!strncmp(tmp, "md5", 3)) {
0394             net->sctp.sctp_hmac_alg = "md5";
0395             changed = true;
0396         }
0397 #endif
0398 #ifdef CONFIG_CRYPTO_SHA1
0399         if (!strncmp(tmp, "sha1", 4)) {
0400             net->sctp.sctp_hmac_alg = "sha1";
0401             changed = true;
0402         }
0403 #endif
0404         if (!strncmp(tmp, "none", 4)) {
0405             net->sctp.sctp_hmac_alg = NULL;
0406             changed = true;
0407         }
0408         if (!changed)
0409             ret = -EINVAL;
0410     }
0411 
0412     return ret;
0413 }
0414 
0415 static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
0416                 void *buffer, size_t *lenp, loff_t *ppos)
0417 {
0418     struct net *net = current->nsproxy->net_ns;
0419     unsigned int min = *(unsigned int *) ctl->extra1;
0420     unsigned int max = *(unsigned int *) ctl->extra2;
0421     struct ctl_table tbl;
0422     int ret, new_value;
0423 
0424     memset(&tbl, 0, sizeof(struct ctl_table));
0425     tbl.maxlen = sizeof(unsigned int);
0426 
0427     if (write)
0428         tbl.data = &new_value;
0429     else
0430         tbl.data = &net->sctp.rto_min;
0431 
0432     ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
0433     if (write && ret == 0) {
0434         if (new_value > max || new_value < min)
0435             return -EINVAL;
0436 
0437         net->sctp.rto_min = new_value;
0438     }
0439 
0440     return ret;
0441 }
0442 
0443 static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
0444                 void *buffer, size_t *lenp, loff_t *ppos)
0445 {
0446     struct net *net = current->nsproxy->net_ns;
0447     unsigned int min = *(unsigned int *) ctl->extra1;
0448     unsigned int max = *(unsigned int *) ctl->extra2;
0449     struct ctl_table tbl;
0450     int ret, new_value;
0451 
0452     memset(&tbl, 0, sizeof(struct ctl_table));
0453     tbl.maxlen = sizeof(unsigned int);
0454 
0455     if (write)
0456         tbl.data = &new_value;
0457     else
0458         tbl.data = &net->sctp.rto_max;
0459 
0460     ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
0461     if (write && ret == 0) {
0462         if (new_value > max || new_value < min)
0463             return -EINVAL;
0464 
0465         net->sctp.rto_max = new_value;
0466     }
0467 
0468     return ret;
0469 }
0470 
0471 static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
0472                    void *buffer, size_t *lenp, loff_t *ppos)
0473 {
0474     if (write)
0475         pr_warn_once("Changing rto_alpha or rto_beta may lead to "
0476                  "suboptimal rtt/srtt estimations!\n");
0477 
0478     return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos);
0479 }
0480 
0481 static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
0482                  void *buffer, size_t *lenp, loff_t *ppos)
0483 {
0484     struct net *net = current->nsproxy->net_ns;
0485     struct ctl_table tbl;
0486     int new_value, ret;
0487 
0488     memset(&tbl, 0, sizeof(struct ctl_table));
0489     tbl.maxlen = sizeof(unsigned int);
0490 
0491     if (write)
0492         tbl.data = &new_value;
0493     else
0494         tbl.data = &net->sctp.auth_enable;
0495 
0496     ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
0497     if (write && ret == 0) {
0498         struct sock *sk = net->sctp.ctl_sock;
0499 
0500         net->sctp.auth_enable = new_value;
0501         /* Update the value in the control socket */
0502         lock_sock(sk);
0503         sctp_sk(sk)->ep->auth_enable = new_value;
0504         release_sock(sk);
0505     }
0506 
0507     return ret;
0508 }
0509 
0510 static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write,
0511                  void *buffer, size_t *lenp, loff_t *ppos)
0512 {
0513     struct net *net = current->nsproxy->net_ns;
0514     unsigned int min = *(unsigned int *)ctl->extra1;
0515     unsigned int max = *(unsigned int *)ctl->extra2;
0516     struct ctl_table tbl;
0517     int ret, new_value;
0518 
0519     memset(&tbl, 0, sizeof(struct ctl_table));
0520     tbl.maxlen = sizeof(unsigned int);
0521 
0522     if (write)
0523         tbl.data = &new_value;
0524     else
0525         tbl.data = &net->sctp.udp_port;
0526 
0527     ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
0528     if (write && ret == 0) {
0529         struct sock *sk = net->sctp.ctl_sock;
0530 
0531         if (new_value > max || new_value < min)
0532             return -EINVAL;
0533 
0534         net->sctp.udp_port = new_value;
0535         sctp_udp_sock_stop(net);
0536         if (new_value) {
0537             ret = sctp_udp_sock_start(net);
0538             if (ret)
0539                 net->sctp.udp_port = 0;
0540         }
0541 
0542         /* Update the value in the control socket */
0543         lock_sock(sk);
0544         sctp_sk(sk)->udp_port = htons(net->sctp.udp_port);
0545         release_sock(sk);
0546     }
0547 
0548     return ret;
0549 }
0550 
0551 static int proc_sctp_do_probe_interval(struct ctl_table *ctl, int write,
0552                        void *buffer, size_t *lenp, loff_t *ppos)
0553 {
0554     struct net *net = current->nsproxy->net_ns;
0555     struct ctl_table tbl;
0556     int ret, new_value;
0557 
0558     memset(&tbl, 0, sizeof(struct ctl_table));
0559     tbl.maxlen = sizeof(unsigned int);
0560 
0561     if (write)
0562         tbl.data = &new_value;
0563     else
0564         tbl.data = &net->sctp.probe_interval;
0565 
0566     ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
0567     if (write && ret == 0) {
0568         if (new_value && new_value < SCTP_PROBE_TIMER_MIN)
0569             return -EINVAL;
0570 
0571         net->sctp.probe_interval = new_value;
0572     }
0573 
0574     return ret;
0575 }
0576 
0577 int sctp_sysctl_net_register(struct net *net)
0578 {
0579     struct ctl_table *table;
0580     int i;
0581 
0582     table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL);
0583     if (!table)
0584         return -ENOMEM;
0585 
0586     for (i = 0; table[i].data; i++)
0587         table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp;
0588 
0589     net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table);
0590     if (net->sctp.sysctl_header == NULL) {
0591         kfree(table);
0592         return -ENOMEM;
0593     }
0594     return 0;
0595 }
0596 
0597 void sctp_sysctl_net_unregister(struct net *net)
0598 {
0599     struct ctl_table *table;
0600 
0601     table = net->sctp.sysctl_header->ctl_table_arg;
0602     unregister_net_sysctl_table(net->sctp.sysctl_header);
0603     kfree(table);
0604 }
0605 
0606 static struct ctl_table_header *sctp_sysctl_header;
0607 
0608 /* Sysctl registration.  */
0609 void sctp_sysctl_register(void)
0610 {
0611     sctp_sysctl_header = register_net_sysctl(&init_net, "net/sctp", sctp_table);
0612 }
0613 
0614 /* Sysctl deregistration.  */
0615 void sctp_sysctl_unregister(void)
0616 {
0617     unregister_net_sysctl_table(sctp_sysctl_header);
0618 }