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