diff options
author | Michal Kubecek <mkubecek@suse.cz> | 2013-02-06 04:46:33 -0500 |
---|---|---|
committer | Steffen Klassert <steffen.klassert@secunet.com> | 2013-02-06 05:36:29 -0500 |
commit | 8d068875caca3b507ffa8a57d521483fd4eebcc7 (patch) | |
tree | 2c12e956ab40e55abbb803f4cf710f09e5d72b70 /net/ipv6 | |
parent | 1f53c808502f1472bfc5829e6dd80317c7198a4a (diff) |
xfrm: make gc_thresh configurable in all namespaces
The xfrm gc threshold can be configured via xfrm{4,6}_gc_thresh
sysctl but currently only in init_net, other namespaces always
use the default value. This can substantially limit the number
of IPsec tunnels that can be effectively used.
Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/xfrm6_policy.c | 52 |
1 files changed, 47 insertions, 5 deletions
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 128273744332..4ef7bdb65440 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -320,7 +320,51 @@ static struct ctl_table xfrm6_policy_table[] = { | |||
320 | { } | 320 | { } |
321 | }; | 321 | }; |
322 | 322 | ||
323 | static struct ctl_table_header *sysctl_hdr; | 323 | static int __net_init xfrm6_net_init(struct net *net) |
324 | { | ||
325 | struct ctl_table *table; | ||
326 | struct ctl_table_header *hdr; | ||
327 | |||
328 | table = xfrm6_policy_table; | ||
329 | if (!net_eq(net, &init_net)) { | ||
330 | table = kmemdup(table, sizeof(xfrm6_policy_table), GFP_KERNEL); | ||
331 | if (!table) | ||
332 | goto err_alloc; | ||
333 | |||
334 | table[0].data = &net->xfrm.xfrm6_dst_ops.gc_thresh; | ||
335 | } | ||
336 | |||
337 | hdr = register_net_sysctl(net, "net/ipv6", table); | ||
338 | if (!hdr) | ||
339 | goto err_reg; | ||
340 | |||
341 | net->ipv6.sysctl.xfrm6_hdr = hdr; | ||
342 | return 0; | ||
343 | |||
344 | err_reg: | ||
345 | if (!net_eq(net, &init_net)) | ||
346 | kfree(table); | ||
347 | err_alloc: | ||
348 | return -ENOMEM; | ||
349 | } | ||
350 | |||
351 | static void __net_exit xfrm6_net_exit(struct net *net) | ||
352 | { | ||
353 | struct ctl_table *table; | ||
354 | |||
355 | if (net->ipv6.sysctl.xfrm6_hdr == NULL) | ||
356 | return; | ||
357 | |||
358 | table = net->ipv6.sysctl.xfrm6_hdr->ctl_table_arg; | ||
359 | unregister_net_sysctl_table(net->ipv6.sysctl.xfrm6_hdr); | ||
360 | if (!net_eq(net, &init_net)) | ||
361 | kfree(table); | ||
362 | } | ||
363 | |||
364 | static struct pernet_operations xfrm6_net_ops = { | ||
365 | .init = xfrm6_net_init, | ||
366 | .exit = xfrm6_net_exit, | ||
367 | }; | ||
324 | #endif | 368 | #endif |
325 | 369 | ||
326 | int __init xfrm6_init(void) | 370 | int __init xfrm6_init(void) |
@@ -339,8 +383,7 @@ int __init xfrm6_init(void) | |||
339 | goto out_policy; | 383 | goto out_policy; |
340 | 384 | ||
341 | #ifdef CONFIG_SYSCTL | 385 | #ifdef CONFIG_SYSCTL |
342 | sysctl_hdr = register_net_sysctl(&init_net, "net/ipv6", | 386 | register_pernet_subsys(&xfrm6_net_ops); |
343 | xfrm6_policy_table); | ||
344 | #endif | 387 | #endif |
345 | out: | 388 | out: |
346 | return ret; | 389 | return ret; |
@@ -352,8 +395,7 @@ out_policy: | |||
352 | void xfrm6_fini(void) | 395 | void xfrm6_fini(void) |
353 | { | 396 | { |
354 | #ifdef CONFIG_SYSCTL | 397 | #ifdef CONFIG_SYSCTL |
355 | if (sysctl_hdr) | 398 | unregister_pernet_subsys(&xfrm6_net_ops); |
356 | unregister_net_sysctl_table(sysctl_hdr); | ||
357 | #endif | 399 | #endif |
358 | xfrm6_policy_fini(); | 400 | xfrm6_policy_fini(); |
359 | xfrm6_state_fini(); | 401 | xfrm6_state_fini(); |