linux/net/core/sysctl_net_core.c
<<
>>
Prefs
   1/* -*- linux-c -*-
   2 * sysctl_net_core.c: sysctl interface to net core subsystem.
   3 *
   4 * Begun April 1, 1996, Mike Shaver.
   5 * Added /proc/sys/net/core directory entry (empty =) ). [MS]
   6 */
   7
   8#include <linux/mm.h>
   9#include <linux/sysctl.h>
  10#include <linux/module.h>
  11#include <linux/socket.h>
  12#include <linux/netdevice.h>
  13#include <linux/ratelimit.h>
  14#include <linux/vmalloc.h>
  15#include <linux/init.h>
  16#include <linux/slab.h>
  17
  18#include <net/ip.h>
  19#include <net/sock.h>
  20
  21#ifdef CONFIG_RPS
  22static int rps_sock_flow_sysctl(ctl_table *table, int write,
  23                                void __user *buffer, size_t *lenp, loff_t *ppos)
  24{
  25        unsigned int orig_size, size;
  26        int ret, i;
  27        ctl_table tmp = {
  28                .data = &size,
  29                .maxlen = sizeof(size),
  30                .mode = table->mode
  31        };
  32        struct rps_sock_flow_table *orig_sock_table, *sock_table;
  33        static DEFINE_MUTEX(sock_flow_mutex);
  34
  35        mutex_lock(&sock_flow_mutex);
  36
  37        orig_sock_table = rps_sock_flow_table;
  38        size = orig_size = orig_sock_table ? orig_sock_table->mask + 1 : 0;
  39
  40        ret = proc_dointvec(&tmp, write, buffer, lenp, ppos);
  41
  42        if (write) {
  43                if (size) {
  44                        if (size > 1<<30) {
  45                                /* Enforce limit to prevent overflow */
  46                                mutex_unlock(&sock_flow_mutex);
  47                                return -EINVAL;
  48                        }
  49                        size = roundup_pow_of_two(size);
  50                        if (size != orig_size) {
  51                                sock_table =
  52                                    vmalloc(RPS_SOCK_FLOW_TABLE_SIZE(size));
  53                                if (!sock_table) {
  54                                        mutex_unlock(&sock_flow_mutex);
  55                                        return -ENOMEM;
  56                                }
  57
  58                                sock_table->mask = size - 1;
  59                        } else
  60                                sock_table = orig_sock_table;
  61
  62                        for (i = 0; i < size; i++)
  63                                sock_table->ents[i] = RPS_NO_CPU;
  64                } else
  65                        sock_table = NULL;
  66
  67                if (sock_table != orig_sock_table) {
  68                        rcu_assign_pointer(rps_sock_flow_table, sock_table);
  69                        synchronize_rcu();
  70                        vfree(orig_sock_table);
  71                }
  72        }
  73
  74        mutex_unlock(&sock_flow_mutex);
  75
  76        return ret;
  77}
  78#endif /* CONFIG_RPS */
  79
  80static struct ctl_table net_core_table[] = {
  81#ifdef CONFIG_NET
  82        {
  83                .procname       = "wmem_max",
  84                .data           = &sysctl_wmem_max,
  85                .maxlen         = sizeof(int),
  86                .mode           = 0644,
  87                .proc_handler   = proc_dointvec
  88        },
  89        {
  90                .procname       = "rmem_max",
  91                .data           = &sysctl_rmem_max,
  92                .maxlen         = sizeof(int),
  93                .mode           = 0644,
  94                .proc_handler   = proc_dointvec
  95        },
  96        {
  97                .procname       = "wmem_default",
  98                .data           = &sysctl_wmem_default,
  99                .maxlen         = sizeof(int),
 100                .mode           = 0644,
 101                .proc_handler   = proc_dointvec
 102        },
 103        {
 104                .procname       = "rmem_default",
 105                .data           = &sysctl_rmem_default,
 106                .maxlen         = sizeof(int),
 107                .mode           = 0644,
 108                .proc_handler   = proc_dointvec
 109        },
 110        {
 111                .procname       = "dev_weight",
 112                .data           = &weight_p,
 113                .maxlen         = sizeof(int),
 114                .mode           = 0644,
 115                .proc_handler   = proc_dointvec
 116        },
 117        {
 118                .procname       = "netdev_max_backlog",
 119                .data           = &netdev_max_backlog,
 120                .maxlen         = sizeof(int),
 121                .mode           = 0644,
 122                .proc_handler   = proc_dointvec
 123        },
 124        {
 125                .procname       = "netdev_tstamp_prequeue",
 126                .data           = &netdev_tstamp_prequeue,
 127                .maxlen         = sizeof(int),
 128                .mode           = 0644,
 129                .proc_handler   = proc_dointvec
 130        },
 131        {
 132                .procname       = "message_cost",
 133                .data           = &net_ratelimit_state.interval,
 134                .maxlen         = sizeof(int),
 135                .mode           = 0644,
 136                .proc_handler   = proc_dointvec_jiffies,
 137        },
 138        {
 139                .procname       = "message_burst",
 140                .data           = &net_ratelimit_state.burst,
 141                .maxlen         = sizeof(int),
 142                .mode           = 0644,
 143                .proc_handler   = proc_dointvec,
 144        },
 145        {
 146                .procname       = "optmem_max",
 147                .data           = &sysctl_optmem_max,
 148                .maxlen         = sizeof(int),
 149                .mode           = 0644,
 150                .proc_handler   = proc_dointvec
 151        },
 152#ifdef CONFIG_RPS
 153        {
 154                .procname       = "rps_sock_flow_entries",
 155                .maxlen         = sizeof(int),
 156                .mode           = 0644,
 157                .proc_handler   = rps_sock_flow_sysctl
 158        },
 159#endif
 160#endif /* CONFIG_NET */
 161        {
 162                .procname       = "netdev_budget",
 163                .data           = &netdev_budget,
 164                .maxlen         = sizeof(int),
 165                .mode           = 0644,
 166                .proc_handler   = proc_dointvec
 167        },
 168        {
 169                .procname       = "warnings",
 170                .data           = &net_msg_warn,
 171                .maxlen         = sizeof(int),
 172                .mode           = 0644,
 173                .proc_handler   = proc_dointvec
 174        },
 175        { }
 176};
 177
 178static struct ctl_table netns_core_table[] = {
 179        {
 180                .procname       = "somaxconn",
 181                .data           = &init_net.core.sysctl_somaxconn,
 182                .maxlen         = sizeof(int),
 183                .mode           = 0644,
 184                .proc_handler   = proc_dointvec
 185        },
 186        { }
 187};
 188
 189__net_initdata struct ctl_path net_core_path[] = {
 190        { .procname = "net", },
 191        { .procname = "core", },
 192        { },
 193};
 194
 195static __net_init int sysctl_core_net_init(struct net *net)
 196{
 197        struct ctl_table *tbl;
 198
 199        net->core.sysctl_somaxconn = SOMAXCONN;
 200
 201        tbl = netns_core_table;
 202        if (!net_eq(net, &init_net)) {
 203                tbl = kmemdup(tbl, sizeof(netns_core_table), GFP_KERNEL);
 204                if (tbl == NULL)
 205                        goto err_dup;
 206
 207                tbl[0].data = &net->core.sysctl_somaxconn;
 208        }
 209
 210        net->core.sysctl_hdr = register_net_sysctl_table(net,
 211                        net_core_path, tbl);
 212        if (net->core.sysctl_hdr == NULL)
 213                goto err_reg;
 214
 215        return 0;
 216
 217err_reg:
 218        if (tbl != netns_core_table)
 219                kfree(tbl);
 220err_dup:
 221        return -ENOMEM;
 222}
 223
 224static __net_exit void sysctl_core_net_exit(struct net *net)
 225{
 226        struct ctl_table *tbl;
 227
 228        tbl = net->core.sysctl_hdr->ctl_table_arg;
 229        unregister_net_sysctl_table(net->core.sysctl_hdr);
 230        BUG_ON(tbl == netns_core_table);
 231        kfree(tbl);
 232}
 233
 234static __net_initdata struct pernet_operations sysctl_core_ops = {
 235        .init = sysctl_core_net_init,
 236        .exit = sysctl_core_net_exit,
 237};
 238
 239static __init int sysctl_core_init(void)
 240{
 241        static struct ctl_table empty[1];
 242
 243        register_sysctl_paths(net_core_path, empty);
 244        register_net_sysctl_rotable(net_core_path, net_core_table);
 245        return register_pernet_subsys(&sysctl_core_ops);
 246}
 247
 248fs_initcall(sysctl_core_init);
 249
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.