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 #include <linux/kmemleak.h> 18 19 #include <net/ip.h> 20 #include <net/sock.h> 21 #include <net/net_ratelimit.h> 22 23 static int one = 1; 24 25 #ifdef CONFIG_RPS 26 static int rps_sock_flow_sysctl(ctl_table *table, int write, 27 void __user *buffer, size_t *lenp, loff_t *ppos) 28 { 29 unsigned int orig_size, size; 30 int ret, i; 31 ctl_table tmp = { 32 .data = &size, 33 .maxlen = sizeof(size), 34 .mode = table->mode 35 }; 36 struct rps_sock_flow_table *orig_sock_table, *sock_table; 37 static DEFINE_MUTEX(sock_flow_mutex); 38 39 mutex_lock(&sock_flow_mutex); 40 41 orig_sock_table = rcu_dereference_protected(rps_sock_flow_table, 42 lockdep_is_held(&sock_flow_mutex)); 43 size = orig_size = orig_sock_table ? orig_sock_table->mask + 1 : 0; 44 45 ret = proc_dointvec(&tmp, write, buffer, lenp, ppos); 46 47 if (write) { 48 if (size) { 49 if (size > 1<<30) { 50 /* Enforce limit to prevent overflow */ 51 mutex_unlock(&sock_flow_mutex); 52 return -EINVAL; 53 } 54 size = roundup_pow_of_two(size); 55 if (size != orig_size) { 56 sock_table = 57 vmalloc(RPS_SOCK_FLOW_TABLE_SIZE(size)); 58 if (!sock_table) { 59 mutex_unlock(&sock_flow_mutex); 60 return -ENOMEM; 61 } 62 63 sock_table->mask = size - 1; 64 } else 65 sock_table = orig_sock_table; 66 67 for (i = 0; i < size; i++) 68 sock_table->ents[i] = RPS_NO_CPU; 69 } else 70 sock_table = NULL; 71 72 if (sock_table != orig_sock_table) { 73 rcu_assign_pointer(rps_sock_flow_table, sock_table); 74 if (sock_table) 75 static_key_slow_inc(&rps_needed); 76 if (orig_sock_table) { 77 static_key_slow_dec(&rps_needed); 78 synchronize_rcu(); 79 vfree(orig_sock_table); 80 } 81 } 82 } 83 84 mutex_unlock(&sock_flow_mutex); 85 86 return ret; 87 } 88 #endif /* CONFIG_RPS */ 89 90 static struct ctl_table net_core_table[] = { 91 #ifdef CONFIG_NET 92 { 93 .procname = "wmem_max", 94 .data = &sysctl_wmem_max, 95 .maxlen = sizeof(int), 96 .mode = 0644, 97 .proc_handler = proc_dointvec_minmax, 98 .extra1 = &one, 99 }, 100 { 101 .procname = "rmem_max", 102 .data = &sysctl_rmem_max, 103 .maxlen = sizeof(int), 104 .mode = 0644, 105 .proc_handler = proc_dointvec_minmax, 106 .extra1 = &one, 107 }, 108 { 109 .procname = "wmem_default", 110 .data = &sysctl_wmem_default, 111 .maxlen = sizeof(int), 112 .mode = 0644, 113 .proc_handler = proc_dointvec_minmax, 114 .extra1 = &one, 115 }, 116 { 117 .procname = "rmem_default", 118 .data = &sysctl_rmem_default, 119 .maxlen = sizeof(int), 120 .mode = 0644, 121 .proc_handler = proc_dointvec_minmax, 122 .extra1 = &one, 123 }, 124 { 125 .procname = "dev_weight", 126 .data = &weight_p, 127 .maxlen = sizeof(int), 128 .mode = 0644, 129 .proc_handler = proc_dointvec 130 }, 131 { 132 .procname = "netdev_max_backlog", 133 .data = &netdev_max_backlog, 134 .maxlen = sizeof(int), 135 .mode = 0644, 136 .proc_handler = proc_dointvec 137 }, 138 #ifdef CONFIG_BPF_JIT 139 { 140 .procname = "bpf_jit_enable", 141 .data = &bpf_jit_enable, 142 .maxlen = sizeof(int), 143 .mode = 0644, 144 .proc_handler = proc_dointvec 145 }, 146 #endif 147 { 148 .procname = "netdev_tstamp_prequeue", 149 .data = &netdev_tstamp_prequeue, 150 .maxlen = sizeof(int), 151 .mode = 0644, 152 .proc_handler = proc_dointvec 153 }, 154 { 155 .procname = "message_cost", 156 .data = &net_ratelimit_state.interval, 157 .maxlen = sizeof(int), 158 .mode = 0644, 159 .proc_handler = proc_dointvec_jiffies, 160 }, 161 { 162 .procname = "message_burst", 163 .data = &net_ratelimit_state.burst, 164 .maxlen = sizeof(int), 165 .mode = 0644, 166 .proc_handler = proc_dointvec, 167 }, 168 { 169 .procname = "optmem_max", 170 .data = &sysctl_optmem_max, 171 .maxlen = sizeof(int), 172 .mode = 0644, 173 .proc_handler = proc_dointvec 174 }, 175 #ifdef CONFIG_RPS 176 { 177 .procname = "rps_sock_flow_entries", 178 .maxlen = sizeof(int), 179 .mode = 0644, 180 .proc_handler = rps_sock_flow_sysctl 181 }, 182 #endif 183 #endif /* CONFIG_NET */ 184 { 185 .procname = "netdev_budget", 186 .data = &netdev_budget, 187 .maxlen = sizeof(int), 188 .mode = 0644, 189 .proc_handler = proc_dointvec 190 }, 191 { 192 .procname = "warnings", 193 .data = &net_msg_warn, 194 .maxlen = sizeof(int), 195 .mode = 0644, 196 .proc_handler = proc_dointvec 197 }, 198 { } 199 }; 200 201 static struct ctl_table netns_core_table[] = { 202 { 203 .procname = "somaxconn", 204 .data = &init_net.core.sysctl_somaxconn, 205 .maxlen = sizeof(int), 206 .mode = 0644, 207 .proc_handler = proc_dointvec 208 }, 209 { } 210 }; 211 212 static __net_init int sysctl_core_net_init(struct net *net) 213 { 214 struct ctl_table *tbl; 215 216 net->core.sysctl_somaxconn = SOMAXCONN; 217 218 tbl = netns_core_table; 219 if (!net_eq(net, &init_net)) { 220 tbl = kmemdup(tbl, sizeof(netns_core_table), GFP_KERNEL); 221 if (tbl == NULL) 222 goto err_dup; 223 224 tbl[0].data = &net->core.sysctl_somaxconn; 225 226 /* Don't export any sysctls to unprivileged users */ 227 if (net->user_ns != &init_user_ns) { 228 tbl[0].procname = NULL; 229 } 230 } 231 232 net->core.sysctl_hdr = register_net_sysctl(net, "net/core", tbl); 233 if (net->core.sysctl_hdr == NULL) 234 goto err_reg; 235 236 return 0; 237 238 err_reg: 239 if (tbl != netns_core_table) 240 kfree(tbl); 241 err_dup: 242 return -ENOMEM; 243 } 244 245 static __net_exit void sysctl_core_net_exit(struct net *net) 246 { 247 struct ctl_table *tbl; 248 249 tbl = net->core.sysctl_hdr->ctl_table_arg; 250 unregister_net_sysctl_table(net->core.sysctl_hdr); 251 BUG_ON(tbl == netns_core_table); 252 kfree(tbl); 253 } 254 255 static __net_initdata struct pernet_operations sysctl_core_ops = { 256 .init = sysctl_core_net_init, 257 .exit = sysctl_core_net_exit, 258 }; 259 260 static __init int sysctl_core_init(void) 261 { 262 register_net_sysctl(&init_net, "net/core", net_core_table); 263 return register_pernet_subsys(&sysctl_core_ops); 264 } 265 266 fs_initcall(sysctl_core_init); 267