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>
This commit is contained in:
parent
1f53c80850
commit
8d068875ca
|
@ -22,6 +22,7 @@ struct netns_ipv4 {
|
||||||
struct ctl_table_header *frags_hdr;
|
struct ctl_table_header *frags_hdr;
|
||||||
struct ctl_table_header *ipv4_hdr;
|
struct ctl_table_header *ipv4_hdr;
|
||||||
struct ctl_table_header *route_hdr;
|
struct ctl_table_header *route_hdr;
|
||||||
|
struct ctl_table_header *xfrm4_hdr;
|
||||||
#endif
|
#endif
|
||||||
struct ipv4_devconf *devconf_all;
|
struct ipv4_devconf *devconf_all;
|
||||||
struct ipv4_devconf *devconf_dflt;
|
struct ipv4_devconf *devconf_dflt;
|
||||||
|
|
|
@ -16,6 +16,7 @@ struct netns_sysctl_ipv6 {
|
||||||
struct ctl_table_header *route_hdr;
|
struct ctl_table_header *route_hdr;
|
||||||
struct ctl_table_header *icmp_hdr;
|
struct ctl_table_header *icmp_hdr;
|
||||||
struct ctl_table_header *frags_hdr;
|
struct ctl_table_header *frags_hdr;
|
||||||
|
struct ctl_table_header *xfrm6_hdr;
|
||||||
#endif
|
#endif
|
||||||
int bindv6only;
|
int bindv6only;
|
||||||
int flush_delay;
|
int flush_delay;
|
||||||
|
|
|
@ -262,7 +262,51 @@ static struct ctl_table xfrm4_policy_table[] = {
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ctl_table_header *sysctl_hdr;
|
static int __net_init xfrm4_net_init(struct net *net)
|
||||||
|
{
|
||||||
|
struct ctl_table *table;
|
||||||
|
struct ctl_table_header *hdr;
|
||||||
|
|
||||||
|
table = xfrm4_policy_table;
|
||||||
|
if (!net_eq(net, &init_net)) {
|
||||||
|
table = kmemdup(table, sizeof(xfrm4_policy_table), GFP_KERNEL);
|
||||||
|
if (!table)
|
||||||
|
goto err_alloc;
|
||||||
|
|
||||||
|
table[0].data = &net->xfrm.xfrm4_dst_ops.gc_thresh;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdr = register_net_sysctl(net, "net/ipv4", table);
|
||||||
|
if (!hdr)
|
||||||
|
goto err_reg;
|
||||||
|
|
||||||
|
net->ipv4.xfrm4_hdr = hdr;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_reg:
|
||||||
|
if (!net_eq(net, &init_net))
|
||||||
|
kfree(table);
|
||||||
|
err_alloc:
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __net_exit xfrm4_net_exit(struct net *net)
|
||||||
|
{
|
||||||
|
struct ctl_table *table;
|
||||||
|
|
||||||
|
if (net->ipv4.xfrm4_hdr == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
table = net->ipv4.xfrm4_hdr->ctl_table_arg;
|
||||||
|
unregister_net_sysctl_table(net->ipv4.xfrm4_hdr);
|
||||||
|
if (!net_eq(net, &init_net))
|
||||||
|
kfree(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pernet_operations __net_initdata xfrm4_net_ops = {
|
||||||
|
.init = xfrm4_net_init,
|
||||||
|
.exit = xfrm4_net_exit,
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void __init xfrm4_policy_init(void)
|
static void __init xfrm4_policy_init(void)
|
||||||
|
@ -277,8 +321,7 @@ void __init xfrm4_init(void)
|
||||||
xfrm4_state_init();
|
xfrm4_state_init();
|
||||||
xfrm4_policy_init();
|
xfrm4_policy_init();
|
||||||
#ifdef CONFIG_SYSCTL
|
#ifdef CONFIG_SYSCTL
|
||||||
sysctl_hdr = register_net_sysctl(&init_net, "net/ipv4",
|
register_pernet_subsys(&xfrm4_net_ops);
|
||||||
xfrm4_policy_table);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -320,7 +320,51 @@ static struct ctl_table xfrm6_policy_table[] = {
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ctl_table_header *sysctl_hdr;
|
static int __net_init xfrm6_net_init(struct net *net)
|
||||||
|
{
|
||||||
|
struct ctl_table *table;
|
||||||
|
struct ctl_table_header *hdr;
|
||||||
|
|
||||||
|
table = xfrm6_policy_table;
|
||||||
|
if (!net_eq(net, &init_net)) {
|
||||||
|
table = kmemdup(table, sizeof(xfrm6_policy_table), GFP_KERNEL);
|
||||||
|
if (!table)
|
||||||
|
goto err_alloc;
|
||||||
|
|
||||||
|
table[0].data = &net->xfrm.xfrm6_dst_ops.gc_thresh;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdr = register_net_sysctl(net, "net/ipv6", table);
|
||||||
|
if (!hdr)
|
||||||
|
goto err_reg;
|
||||||
|
|
||||||
|
net->ipv6.sysctl.xfrm6_hdr = hdr;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_reg:
|
||||||
|
if (!net_eq(net, &init_net))
|
||||||
|
kfree(table);
|
||||||
|
err_alloc:
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __net_exit xfrm6_net_exit(struct net *net)
|
||||||
|
{
|
||||||
|
struct ctl_table *table;
|
||||||
|
|
||||||
|
if (net->ipv6.sysctl.xfrm6_hdr == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
table = net->ipv6.sysctl.xfrm6_hdr->ctl_table_arg;
|
||||||
|
unregister_net_sysctl_table(net->ipv6.sysctl.xfrm6_hdr);
|
||||||
|
if (!net_eq(net, &init_net))
|
||||||
|
kfree(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pernet_operations xfrm6_net_ops = {
|
||||||
|
.init = xfrm6_net_init,
|
||||||
|
.exit = xfrm6_net_exit,
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int __init xfrm6_init(void)
|
int __init xfrm6_init(void)
|
||||||
|
@ -339,8 +383,7 @@ int __init xfrm6_init(void)
|
||||||
goto out_policy;
|
goto out_policy;
|
||||||
|
|
||||||
#ifdef CONFIG_SYSCTL
|
#ifdef CONFIG_SYSCTL
|
||||||
sysctl_hdr = register_net_sysctl(&init_net, "net/ipv6",
|
register_pernet_subsys(&xfrm6_net_ops);
|
||||||
xfrm6_policy_table);
|
|
||||||
#endif
|
#endif
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -352,8 +395,7 @@ out_policy:
|
||||||
void xfrm6_fini(void)
|
void xfrm6_fini(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SYSCTL
|
#ifdef CONFIG_SYSCTL
|
||||||
if (sysctl_hdr)
|
unregister_pernet_subsys(&xfrm6_net_ops);
|
||||||
unregister_net_sysctl_table(sysctl_hdr);
|
|
||||||
#endif
|
#endif
|
||||||
xfrm6_policy_fini();
|
xfrm6_policy_fini();
|
||||||
xfrm6_state_fini();
|
xfrm6_state_fini();
|
||||||
|
|
Loading…
Reference in New Issue