Blame view
net/core/sysctl_net_core.c
14.8 KB
b24413180
|
1 |
// SPDX-License-Identifier: GPL-2.0 |
1da177e4c
|
2 3 4 5 6 7 8 9 10 |
/* -*- linux-c -*- * sysctl_net_core.c: sysctl interface to net core subsystem. * * Begun April 1, 1996, Mike Shaver. * Added /proc/sys/net/core directory entry (empty =) ). [MS] */ #include <linux/mm.h> #include <linux/sysctl.h> |
1da177e4c
|
11 |
#include <linux/module.h> |
20380731b
|
12 |
#include <linux/socket.h> |
a37ae4086
|
13 |
#include <linux/netdevice.h> |
3fff4c42b
|
14 |
#include <linux/ratelimit.h> |
fec5e652e
|
15 |
#include <linux/vmalloc.h> |
33eb9cfc7
|
16 |
#include <linux/init.h> |
5a0e3ad6a
|
17 |
#include <linux/slab.h> |
3fff4c42b
|
18 |
|
63d819cae
|
19 |
#include <net/ip.h> |
20380731b
|
20 |
#include <net/sock.h> |
c5c177b4a
|
21 |
#include <net/net_ratelimit.h> |
076bb0c82
|
22 |
#include <net/busy_poll.h> |
6da7c8fcb
|
23 |
#include <net/pkt_sched.h> |
1da177e4c
|
24 |
|
fa9dd599b
|
25 |
static int two __maybe_unused = 2; |
b1cb59cf2
|
26 27 |
static int min_sndbuf = SOCK_MIN_SNDBUF; static int min_rcvbuf = SOCK_MIN_RCVBUF; |
5f74f82ea
|
28 |
static int max_skb_frags = MAX_SKB_FRAGS; |
fdadd0493
|
29 30 |
static long long_one __maybe_unused = 1; static long long_max __maybe_unused = LONG_MAX; |
cdda88912
|
31 |
|
ba7a46f16
|
32 |
static int net_msg_warn; /* Unused, but still a sysctl */ |
79134e6ce
|
33 34 |
int sysctl_fb_tunnels_only_for_init_net __read_mostly = 0; EXPORT_SYMBOL(sysctl_fb_tunnels_only_for_init_net); |
856c395cf
|
35 36 37 38 39 40 41 42 |
/* 0 - Keep current behavior: * IPv4: inherit all current settings from init_net * IPv6: reset all settings to default * 1 - Both inherit all current settings from init_net * 2 - Both reset all settings to default */ int sysctl_devconf_inherit_init_net __read_mostly; EXPORT_SYMBOL(sysctl_devconf_inherit_init_net); |
fec5e652e
|
43 |
#ifdef CONFIG_RPS |
fe2c6338f
|
44 |
static int rps_sock_flow_sysctl(struct ctl_table *table, int write, |
fec5e652e
|
45 46 47 48 |
void __user *buffer, size_t *lenp, loff_t *ppos) { unsigned int orig_size, size; int ret, i; |
fe2c6338f
|
49 |
struct ctl_table tmp = { |
fec5e652e
|
50 51 52 53 54 55 56 57 |
.data = &size, .maxlen = sizeof(size), .mode = table->mode }; struct rps_sock_flow_table *orig_sock_table, *sock_table; static DEFINE_MUTEX(sock_flow_mutex); mutex_lock(&sock_flow_mutex); |
6e3f7faf3
|
58 59 |
orig_sock_table = rcu_dereference_protected(rps_sock_flow_table, lockdep_is_held(&sock_flow_mutex)); |
fec5e652e
|
60 61 62 63 64 65 |
size = orig_size = orig_sock_table ? orig_sock_table->mask + 1 : 0; ret = proc_dointvec(&tmp, write, buffer, lenp, ppos); if (write) { if (size) { |
93c1af6ca
|
66 |
if (size > 1<<29) { |
fec5e652e
|
67 68 69 70 71 72 73 74 75 76 77 78 |
/* Enforce limit to prevent overflow */ mutex_unlock(&sock_flow_mutex); return -EINVAL; } size = roundup_pow_of_two(size); if (size != orig_size) { sock_table = vmalloc(RPS_SOCK_FLOW_TABLE_SIZE(size)); if (!sock_table) { mutex_unlock(&sock_flow_mutex); return -ENOMEM; } |
567e4b797
|
79 |
rps_cpu_mask = roundup_pow_of_two(nr_cpu_ids) - 1; |
fec5e652e
|
80 81 82 83 84 85 86 87 88 89 90 |
sock_table->mask = size - 1; } else sock_table = orig_sock_table; for (i = 0; i < size; i++) sock_table->ents[i] = RPS_NO_CPU; } else sock_table = NULL; if (sock_table != orig_sock_table) { rcu_assign_pointer(rps_sock_flow_table, sock_table); |
13bfff25c
|
91 |
if (sock_table) { |
dc05360fe
|
92 93 |
static_branch_inc(&rps_needed); static_branch_inc(&rfs_needed); |
13bfff25c
|
94 |
} |
adc9300e7
|
95 |
if (orig_sock_table) { |
dc05360fe
|
96 97 |
static_branch_dec(&rps_needed); static_branch_dec(&rfs_needed); |
adc9300e7
|
98 99 100 |
synchronize_rcu(); vfree(orig_sock_table); } |
fec5e652e
|
101 102 103 104 105 106 107 108 |
} } mutex_unlock(&sock_flow_mutex); return ret; } #endif /* CONFIG_RPS */ |
99bbc7074
|
109 110 |
#ifdef CONFIG_NET_FLOW_LIMIT static DEFINE_MUTEX(flow_limit_update_mutex); |
fe2c6338f
|
111 |
static int flow_limit_cpu_sysctl(struct ctl_table *table, int write, |
99bbc7074
|
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
void __user *buffer, size_t *lenp, loff_t *ppos) { struct sd_flow_limit *cur; struct softnet_data *sd; cpumask_var_t mask; int i, len, ret = 0; if (!alloc_cpumask_var(&mask, GFP_KERNEL)) return -ENOMEM; if (write) { ret = cpumask_parse_user(buffer, *lenp, mask); if (ret) goto done; mutex_lock(&flow_limit_update_mutex); len = sizeof(*cur) + netdev_flow_limit_table_len; for_each_possible_cpu(i) { sd = &per_cpu(softnet_data, i); cur = rcu_dereference_protected(sd->flow_limit, lockdep_is_held(&flow_limit_update_mutex)); if (cur && !cpumask_test_cpu(i, mask)) { RCU_INIT_POINTER(sd->flow_limit, NULL); synchronize_rcu(); kfree(cur); } else if (!cur && cpumask_test_cpu(i, mask)) { |
5b59d467a
|
139 140 |
cur = kzalloc_node(len, GFP_KERNEL, cpu_to_node(i)); |
99bbc7074
|
141 142 143 144 145 146 147 148 149 150 151 152 |
if (!cur) { /* not unwinding previous changes */ ret = -ENOMEM; goto write_unlock; } cur->num_buckets = netdev_flow_limit_table_len; rcu_assign_pointer(sd->flow_limit, cur); } } write_unlock: mutex_unlock(&flow_limit_update_mutex); } else { |
5f121b9a8
|
153 |
char kbuf[128]; |
99bbc7074
|
154 155 156 157 158 159 160 161 162 163 164 165 166 |
if (*ppos || !*lenp) { *lenp = 0; goto done; } cpumask_clear(mask); rcu_read_lock(); for_each_possible_cpu(i) { sd = &per_cpu(softnet_data, i); if (rcu_dereference(sd->flow_limit)) cpumask_set_cpu(i, mask); } rcu_read_unlock(); |
5f121b9a8
|
167 |
len = min(sizeof(kbuf) - 1, *lenp); |
f09068276
|
168 |
len = scnprintf(kbuf, len, "%*pb", cpumask_pr_args(mask)); |
5f121b9a8
|
169 170 171 172 173 174 175 176 177 178 179 180 181 |
if (!len) { *lenp = 0; goto done; } if (len < *lenp) kbuf[len++] = ' '; if (copy_to_user(buffer, kbuf, len)) { ret = -EFAULT; goto done; } *lenp = len; *ppos += len; |
99bbc7074
|
182 183 184 185 186 187 |
} done: free_cpumask_var(mask); return ret; } |
fe2c6338f
|
188 |
static int flow_limit_table_len_sysctl(struct ctl_table *table, int write, |
99bbc7074
|
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
void __user *buffer, size_t *lenp, loff_t *ppos) { unsigned int old, *ptr; int ret; mutex_lock(&flow_limit_update_mutex); ptr = table->data; old = *ptr; ret = proc_dointvec(table, write, buffer, lenp, ppos); if (!ret && write && !is_power_of_2(*ptr)) { *ptr = old; ret = -EINVAL; } mutex_unlock(&flow_limit_update_mutex); return ret; } #endif /* CONFIG_NET_FLOW_LIMIT */ |
6da7c8fcb
|
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
#ifdef CONFIG_NET_SCHED static int set_default_qdisc(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { char id[IFNAMSIZ]; struct ctl_table tbl = { .data = id, .maxlen = IFNAMSIZ, }; int ret; qdisc_get_default(id, IFNAMSIZ); ret = proc_dostring(&tbl, write, buffer, lenp, ppos); if (write && ret == 0) ret = qdisc_set_default(id); return ret; } #endif |
3d48b53fb
|
228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
static int proc_do_dev_weight(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { int ret; ret = proc_dointvec(table, write, buffer, lenp, ppos); if (ret != 0) return ret; dev_rx_weight = weight_p * dev_weight_rx_bias; dev_tx_weight = weight_p * dev_weight_tx_bias; return ret; } |
960fb622f
|
242 243 244 245 246 247 248 249 250 251 252 |
static int proc_do_rss_key(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { struct ctl_table fake_table; char buf[NETDEV_RSS_KEY_LEN * 3]; snprintf(buf, sizeof(buf), "%*phC", NETDEV_RSS_KEY_LEN, netdev_rss_key); fake_table.data = buf; fake_table.maxlen = sizeof(buf); return proc_dostring(&fake_table, write, buffer, lenp, ppos); } |
2e4a30983
|
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
#ifdef CONFIG_BPF_JIT static int proc_dointvec_minmax_bpf_enable(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { int ret, jit_enable = *(int *)table->data; struct ctl_table tmp = *table; if (write && !capable(CAP_SYS_ADMIN)) return -EPERM; tmp.data = &jit_enable; ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos); if (write && !ret) { if (jit_enable < 2 || (jit_enable == 2 && bpf_dump_raw_ok())) { *(int *)table->data = jit_enable; if (jit_enable == 2) pr_warn("bpf_jit_enable = 2 was set! NEVER use this in production, only for JIT debugging! "); } else { ret = -EPERM; } } return ret; } |
1148f9adb
|
279 |
# ifdef CONFIG_HAVE_EBPF_JIT |
2e4a30983
|
280 281 282 283 284 285 286 287 288 289 |
static int proc_dointvec_minmax_bpf_restricted(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { if (!capable(CAP_SYS_ADMIN)) return -EPERM; return proc_dointvec_minmax(table, write, buffer, lenp, ppos); } |
1148f9adb
|
290 |
# endif /* CONFIG_HAVE_EBPF_JIT */ |
fdadd0493
|
291 292 293 294 295 296 297 298 299 300 301 |
static int proc_dolongvec_minmax_bpf_restricted(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { if (!capable(CAP_SYS_ADMIN)) return -EPERM; return proc_doulongvec_minmax(table, write, buffer, lenp, ppos); } |
2e4a30983
|
302 |
#endif |
33eb9cfc7
|
303 |
static struct ctl_table net_core_table[] = { |
1da177e4c
|
304 305 |
#ifdef CONFIG_NET { |
1da177e4c
|
306 307 308 309 |
.procname = "wmem_max", .data = &sysctl_wmem_max, .maxlen = sizeof(int), .mode = 0644, |
cdda88912
|
310 |
.proc_handler = proc_dointvec_minmax, |
b1cb59cf2
|
311 |
.extra1 = &min_sndbuf, |
1da177e4c
|
312 313 |
}, { |
1da177e4c
|
314 315 316 317 |
.procname = "rmem_max", .data = &sysctl_rmem_max, .maxlen = sizeof(int), .mode = 0644, |
cdda88912
|
318 |
.proc_handler = proc_dointvec_minmax, |
b1cb59cf2
|
319 |
.extra1 = &min_rcvbuf, |
1da177e4c
|
320 321 |
}, { |
1da177e4c
|
322 323 324 325 |
.procname = "wmem_default", .data = &sysctl_wmem_default, .maxlen = sizeof(int), .mode = 0644, |
cdda88912
|
326 |
.proc_handler = proc_dointvec_minmax, |
b1cb59cf2
|
327 |
.extra1 = &min_sndbuf, |
1da177e4c
|
328 329 |
}, { |
1da177e4c
|
330 331 332 333 |
.procname = "rmem_default", .data = &sysctl_rmem_default, .maxlen = sizeof(int), .mode = 0644, |
cdda88912
|
334 |
.proc_handler = proc_dointvec_minmax, |
b1cb59cf2
|
335 |
.extra1 = &min_rcvbuf, |
1da177e4c
|
336 337 |
}, { |
1da177e4c
|
338 339 340 341 |
.procname = "dev_weight", .data = &weight_p, .maxlen = sizeof(int), .mode = 0644, |
3d48b53fb
|
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 |
.proc_handler = proc_do_dev_weight, }, { .procname = "dev_weight_rx_bias", .data = &dev_weight_rx_bias, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_do_dev_weight, }, { .procname = "dev_weight_tx_bias", .data = &dev_weight_tx_bias, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_do_dev_weight, |
1da177e4c
|
357 358 |
}, { |
1da177e4c
|
359 360 361 362 |
.procname = "netdev_max_backlog", .data = &netdev_max_backlog, .maxlen = sizeof(int), .mode = 0644, |
6d9f239a1
|
363 |
.proc_handler = proc_dointvec |
1da177e4c
|
364 |
}, |
960fb622f
|
365 366 367 368 369 370 371 |
{ .procname = "netdev_rss_key", .data = &netdev_rss_key, .maxlen = sizeof(int), .mode = 0444, .proc_handler = proc_do_rss_key, }, |
0a14842f5
|
372 373 374 375 376 377 |
#ifdef CONFIG_BPF_JIT { .procname = "bpf_jit_enable", .data = &bpf_jit_enable, .maxlen = sizeof(int), .mode = 0644, |
2e4a30983
|
378 |
.proc_handler = proc_dointvec_minmax_bpf_enable, |
fa9dd599b
|
379 |
# ifdef CONFIG_BPF_JIT_ALWAYS_ON |
eec4844fa
|
380 381 |
.extra1 = SYSCTL_ONE, .extra2 = SYSCTL_ONE, |
fa9dd599b
|
382 |
# else |
eec4844fa
|
383 |
.extra1 = SYSCTL_ZERO, |
fa9dd599b
|
384 385 |
.extra2 = &two, # endif |
0a14842f5
|
386 |
}, |
4f3446bb8
|
387 388 389 390 391 392 |
# ifdef CONFIG_HAVE_EBPF_JIT { .procname = "bpf_jit_harden", .data = &bpf_jit_harden, .maxlen = sizeof(int), .mode = 0600, |
2e4a30983
|
393 |
.proc_handler = proc_dointvec_minmax_bpf_restricted, |
eec4844fa
|
394 |
.extra1 = SYSCTL_ZERO, |
fa9dd599b
|
395 |
.extra2 = &two, |
4f3446bb8
|
396 |
}, |
74451e66d
|
397 398 399 400 401 |
{ .procname = "bpf_jit_kallsyms", .data = &bpf_jit_kallsyms, .maxlen = sizeof(int), .mode = 0600, |
2e4a30983
|
402 |
.proc_handler = proc_dointvec_minmax_bpf_restricted, |
eec4844fa
|
403 404 |
.extra1 = SYSCTL_ZERO, .extra2 = SYSCTL_ONE, |
74451e66d
|
405 |
}, |
4f3446bb8
|
406 |
# endif |
ede95a63b
|
407 408 409 |
{ .procname = "bpf_jit_limit", .data = &bpf_jit_limit, |
fdadd0493
|
410 |
.maxlen = sizeof(long), |
ede95a63b
|
411 |
.mode = 0600, |
fdadd0493
|
412 413 414 |
.proc_handler = proc_dolongvec_minmax_bpf_restricted, .extra1 = &long_one, .extra2 = &long_max, |
ede95a63b
|
415 |
}, |
0a14842f5
|
416 |
#endif |
1da177e4c
|
417 |
{ |
3b098e2d7
|
418 419 420 421 422 423 424 |
.procname = "netdev_tstamp_prequeue", .data = &netdev_tstamp_prequeue, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec }, { |
1da177e4c
|
425 |
.procname = "message_cost", |
717115e1a
|
426 |
.data = &net_ratelimit_state.interval, |
1da177e4c
|
427 428 |
.maxlen = sizeof(int), .mode = 0644, |
6d9f239a1
|
429 |
.proc_handler = proc_dointvec_jiffies, |
1da177e4c
|
430 431 |
}, { |
1da177e4c
|
432 |
.procname = "message_burst", |
717115e1a
|
433 |
.data = &net_ratelimit_state.burst, |
1da177e4c
|
434 435 |
.maxlen = sizeof(int), .mode = 0644, |
6d9f239a1
|
436 |
.proc_handler = proc_dointvec, |
1da177e4c
|
437 438 |
}, { |
1da177e4c
|
439 440 441 442 |
.procname = "optmem_max", .data = &sysctl_optmem_max, .maxlen = sizeof(int), .mode = 0644, |
6d9f239a1
|
443 |
.proc_handler = proc_dointvec |
1da177e4c
|
444 |
}, |
b245be1f4
|
445 446 447 448 449 450 |
{ .procname = "tstamp_allow_data", .data = &sysctl_tstamp_allow_data, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec_minmax, |
eec4844fa
|
451 452 |
.extra1 = SYSCTL_ZERO, .extra2 = SYSCTL_ONE |
b245be1f4
|
453 |
}, |
fec5e652e
|
454 455 456 457 458 459 460 461 |
#ifdef CONFIG_RPS { .procname = "rps_sock_flow_entries", .maxlen = sizeof(int), .mode = 0644, .proc_handler = rps_sock_flow_sysctl }, #endif |
99bbc7074
|
462 463 464 465 466 467 468 469 470 471 472 473 474 475 |
#ifdef CONFIG_NET_FLOW_LIMIT { .procname = "flow_limit_cpu_bitmap", .mode = 0644, .proc_handler = flow_limit_cpu_sysctl }, { .procname = "flow_limit_table_len", .data = &netdev_flow_limit_table_len, .maxlen = sizeof(int), .mode = 0644, .proc_handler = flow_limit_table_len_sysctl }, #endif /* CONFIG_NET_FLOW_LIMIT */ |
e0d1095ae
|
476 |
#ifdef CONFIG_NET_RX_BUSY_POLL |
060212928
|
477 |
{ |
64b0dc517
|
478 479 |
.procname = "busy_poll", .data = &sysctl_net_busy_poll, |
eb6db6228
|
480 |
.maxlen = sizeof(unsigned int), |
060212928
|
481 |
.mode = 0644, |
95f255211
|
482 |
.proc_handler = proc_dointvec_minmax, |
eec4844fa
|
483 |
.extra1 = SYSCTL_ZERO, |
060212928
|
484 |
}, |
2d48d67fa
|
485 |
{ |
64b0dc517
|
486 487 |
.procname = "busy_read", .data = &sysctl_net_busy_read, |
2d48d67fa
|
488 489 |
.maxlen = sizeof(unsigned int), .mode = 0644, |
95f255211
|
490 |
.proc_handler = proc_dointvec_minmax, |
eec4844fa
|
491 |
.extra1 = SYSCTL_ZERO, |
2d48d67fa
|
492 |
}, |
6da7c8fcb
|
493 494 495 496 497 498 499 500 |
#endif #ifdef CONFIG_NET_SCHED { .procname = "default_qdisc", .mode = 0644, .maxlen = IFNAMSIZ, .proc_handler = set_default_qdisc }, |
060212928
|
501 |
#endif |
1da177e4c
|
502 503 |
#endif /* CONFIG_NET */ { |
51b0bdedb
|
504 505 506 507 |
.procname = "netdev_budget", .data = &netdev_budget, .maxlen = sizeof(int), .mode = 0644, |
6d9f239a1
|
508 |
.proc_handler = proc_dointvec |
51b0bdedb
|
509 |
}, |
a2a316fd0
|
510 |
{ |
a2a316fd0
|
511 512 513 514 |
.procname = "warnings", .data = &net_msg_warn, .maxlen = sizeof(int), .mode = 0644, |
6d9f239a1
|
515 |
.proc_handler = proc_dointvec |
a2a316fd0
|
516 |
}, |
5f74f82ea
|
517 518 519 520 521 522 |
{ .procname = "max_skb_frags", .data = &sysctl_max_skb_frags, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec_minmax, |
eec4844fa
|
523 |
.extra1 = SYSCTL_ONE, |
5f74f82ea
|
524 525 |
.extra2 = &max_skb_frags, }, |
7acf8a1e8
|
526 527 528 529 530 531 |
{ .procname = "netdev_budget_usecs", .data = &netdev_budget_usecs, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_minmax, |
eec4844fa
|
532 |
.extra1 = SYSCTL_ZERO, |
7acf8a1e8
|
533 |
}, |
79134e6ce
|
534 535 536 537 538 539 |
{ .procname = "fb_tunnels_only_for_init_net", .data = &sysctl_fb_tunnels_only_for_init_net, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec_minmax, |
eec4844fa
|
540 541 |
.extra1 = SYSCTL_ZERO, .extra2 = SYSCTL_ONE, |
79134e6ce
|
542 |
}, |
856c395cf
|
543 544 545 546 547 548 |
{ .procname = "devconf_inherit_init_net", .data = &sysctl_devconf_inherit_init_net, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec_minmax, |
eec4844fa
|
549 |
.extra1 = SYSCTL_ZERO, |
856c395cf
|
550 551 |
.extra2 = &two, }, |
ce27ec606
|
552 553 554 555 556 557 558 |
{ .procname = "high_order_alloc_disable", .data = &net_high_order_alloc_disable_key.key, .maxlen = sizeof(net_high_order_alloc_disable_key), .mode = 0644, .proc_handler = proc_do_static_key, }, |
323ebb61e
|
559 560 561 562 563 564 565 566 |
{ .procname = "gro_normal_batch", .data = &gro_normal_batch, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_minmax, .extra1 = SYSCTL_ONE, }, |
f8572d8f2
|
567 |
{ } |
1da177e4c
|
568 |
}; |
33eb9cfc7
|
569 |
|
d5a4502e9
|
570 571 |
static struct ctl_table netns_core_table[] = { { |
d5a4502e9
|
572 573 574 575 |
.procname = "somaxconn", .data = &init_net.core.sysctl_somaxconn, .maxlen = sizeof(int), .mode = 0644, |
eec4844fa
|
576 |
.extra1 = SYSCTL_ZERO, |
5f671d6b4
|
577 |
.proc_handler = proc_dointvec_minmax |
d5a4502e9
|
578 |
}, |
f8572d8f2
|
579 |
{ } |
d5a4502e9
|
580 |
}; |
024626e36
|
581 |
static __net_init int sysctl_core_net_init(struct net *net) |
33eb9cfc7
|
582 |
{ |
d5a4502e9
|
583 |
struct ctl_table *tbl; |
024626e36
|
584 |
|
d5a4502e9
|
585 |
tbl = netns_core_table; |
09ad9bc75
|
586 |
if (!net_eq(net, &init_net)) { |
d5a4502e9
|
587 |
tbl = kmemdup(tbl, sizeof(netns_core_table), GFP_KERNEL); |
024626e36
|
588 589 |
if (tbl == NULL) goto err_dup; |
d5a4502e9
|
590 |
tbl[0].data = &net->core.sysctl_somaxconn; |
464dc801c
|
591 592 593 594 595 |
/* Don't export any sysctls to unprivileged users */ if (net->user_ns != &init_user_ns) { tbl[0].procname = NULL; } |
024626e36
|
596 |
} |
ec8f23ce0
|
597 |
net->core.sysctl_hdr = register_net_sysctl(net, "net/core", tbl); |
8efa6e93c
|
598 |
if (net->core.sysctl_hdr == NULL) |
024626e36
|
599 |
goto err_reg; |
33eb9cfc7
|
600 |
|
024626e36
|
601 602 603 |
return 0; err_reg: |
d5a4502e9
|
604 |
if (tbl != netns_core_table) |
024626e36
|
605 606 607 608 609 610 611 612 |
kfree(tbl); err_dup: return -ENOMEM; } static __net_exit void sysctl_core_net_exit(struct net *net) { struct ctl_table *tbl; |
8efa6e93c
|
613 614 |
tbl = net->core.sysctl_hdr->ctl_table_arg; unregister_net_sysctl_table(net->core.sysctl_hdr); |
d5a4502e9
|
615 |
BUG_ON(tbl == netns_core_table); |
024626e36
|
616 617 618 619 620 621 622 623 624 625 |
kfree(tbl); } static __net_initdata struct pernet_operations sysctl_core_ops = { .init = sysctl_core_net_init, .exit = sysctl_core_net_exit, }; static __init int sysctl_core_init(void) { |
434447579
|
626 |
register_net_sysctl(&init_net, "net/core", net_core_table); |
024626e36
|
627 |
return register_pernet_subsys(&sysctl_core_ops); |
33eb9cfc7
|
628 |
} |
b27aeadb5
|
629 |
fs_initcall(sysctl_core_init); |