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