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/init.h> 15 #include <linux/slab.h> 16 17 #include <net/ip.h> 18 #include <net/sock.h> 19 20 static struct ctl_table net_core_table[] = { 21 #ifdef CONFIG_NET 22 { 23 .procname = "wmem_max", 24 .data = &sysctl_wmem_max, 25 .maxlen = sizeof(int), 26 .mode = 0644, 27 .proc_handler = proc_dointvec 28 }, 29 { 30 .procname = "rmem_max", 31 .data = &sysctl_rmem_max, 32 .maxlen = sizeof(int), 33 .mode = 0644, 34 .proc_handler = proc_dointvec 35 }, 36 { 37 .procname = "wmem_default", 38 .data = &sysctl_wmem_default, 39 .maxlen = sizeof(int), 40 .mode = 0644, 41 .proc_handler = proc_dointvec 42 }, 43 { 44 .procname = "rmem_default", 45 .data = &sysctl_rmem_default, 46 .maxlen = sizeof(int), 47 .mode = 0644, 48 .proc_handler = proc_dointvec 49 }, 50 { 51 .procname = "dev_weight", 52 .data = &weight_p, 53 .maxlen = sizeof(int), 54 .mode = 0644, 55 .proc_handler = proc_dointvec 56 }, 57 { 58 .procname = "netdev_max_backlog", 59 .data = &netdev_max_backlog, 60 .maxlen = sizeof(int), 61 .mode = 0644, 62 .proc_handler = proc_dointvec 63 }, 64 { 65 .procname = "message_cost", 66 .data = &net_ratelimit_state.interval, 67 .maxlen = sizeof(int), 68 .mode = 0644, 69 .proc_handler = proc_dointvec_jiffies, 70 }, 71 { 72 .procname = "message_burst", 73 .data = &net_ratelimit_state.burst, 74 .maxlen = sizeof(int), 75 .mode = 0644, 76 .proc_handler = proc_dointvec, 77 }, 78 { 79 .procname = "optmem_max", 80 .data = &sysctl_optmem_max, 81 .maxlen = sizeof(int), 82 .mode = 0644, 83 .proc_handler = proc_dointvec 84 }, 85 #endif /* CONFIG_NET */ 86 { 87 .procname = "netdev_budget", 88 .data = &netdev_budget, 89 .maxlen = sizeof(int), 90 .mode = 0644, 91 .proc_handler = proc_dointvec 92 }, 93 { 94 .procname = "warnings", 95 .data = &net_msg_warn, 96 .maxlen = sizeof(int), 97 .mode = 0644, 98 .proc_handler = proc_dointvec 99 }, 100 { } 101 }; 102 103 static struct ctl_table netns_core_table[] = { 104 { 105 .procname = "somaxconn", 106 .data = &init_net.core.sysctl_somaxconn, 107 .maxlen = sizeof(int), 108 .mode = 0644, 109 .proc_handler = proc_dointvec 110 }, 111 { } 112 }; 113 114 __net_initdata struct ctl_path net_core_path[] = { 115 { .procname = "net", }, 116 { .procname = "core", }, 117 { }, 118 }; 119 120 static __net_init int sysctl_core_net_init(struct net *net) 121 { 122 struct ctl_table *tbl; 123 124 net->core.sysctl_somaxconn = SOMAXCONN; 125 126 tbl = netns_core_table; 127 if (!net_eq(net, &init_net)) { 128 tbl = kmemdup(tbl, sizeof(netns_core_table), GFP_KERNEL); 129 if (tbl == NULL) 130 goto err_dup; 131 132 tbl[0].data = &net->core.sysctl_somaxconn; 133 } 134 135 net->core.sysctl_hdr = register_net_sysctl_table(net, 136 net_core_path, tbl); 137 if (net->core.sysctl_hdr == NULL) 138 goto err_reg; 139 140 return 0; 141 142 err_reg: 143 if (tbl != netns_core_table) 144 kfree(tbl); 145 err_dup: 146 return -ENOMEM; 147 } 148 149 static __net_exit void sysctl_core_net_exit(struct net *net) 150 { 151 struct ctl_table *tbl; 152 153 tbl = net->core.sysctl_hdr->ctl_table_arg; 154 unregister_net_sysctl_table(net->core.sysctl_hdr); 155 BUG_ON(tbl == netns_core_table); 156 kfree(tbl); 157 } 158 159 static __net_initdata struct pernet_operations sysctl_core_ops = { 160 .init = sysctl_core_net_init, 161 .exit = sysctl_core_net_exit, 162 }; 163 164 static __init int sysctl_core_init(void) 165 { 166 static struct ctl_table empty[1]; 167 168 register_sysctl_paths(net_core_path, empty); 169 register_net_sysctl_rotable(net_core_path, net_core_table); 170 return register_pernet_subsys(&sysctl_core_ops); 171 } 172 173 fs_initcall(sysctl_core_init); 174