summaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorNeil Horman <nhorman@tuxdriver.com>2009-07-27 10:22:46 +0200
committerDavid S. Miller <davem@davemloft.net>2009-07-27 20:35:32 +0200
commita44a4a006b860476881ec0098c36584036e1cb91 (patch)
treed1f6f519b734ca3b4b9e18ad473577884fb6b0d1 /net/ipv6
parentnet: ethtool_op_get_rx_csum() should be public and exported (diff)
downloadlinux-a44a4a006b860476881ec0098c36584036e1cb91.tar.xz
linux-a44a4a006b860476881ec0098c36584036e1cb91.zip
xfrm: export xfrm garbage collector thresholds via sysctl
Export garbage collector thresholds for xfrm[4|6]_dst_ops Had a problem reported to me recently in which a high volume of ipsec connections on a system began reporting ENOBUFS for new connections eventually. It seemed that after about 2000 connections we started being unable to create more. A quick look revealed that the xfrm code used a dst_ops structure that limited the gc_thresh value to 1024, and always dropped route cache entries after 2x the gc_thresh. It seems the most direct solution is to export the gc_thresh values in the xfrm[4|6] dst_ops as sysctls, like the main routing table does, so that higher volumes of connections can be supported. This patch has been tested and allows the reporter to increase their ipsec connection volume successfully. Reported-by: Joe Nall <joe@nall.com> Signed-off-by: Neil Horman <nhorman@tuxdriver.com> ipv4/xfrm4_policy.c | 18 ++++++++++++++++++ ipv6/xfrm6_policy.c | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/xfrm6_policy.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 3a3c677bc0f2..4acc308eac7f 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -306,6 +306,20 @@ static void xfrm6_policy_fini(void)
xfrm_policy_unregister_afinfo(&xfrm6_policy_afinfo);
}
+static struct ctl_table xfrm6_policy_table[] = {
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "xfrm6_gc_thresh",
+ .data = &xfrm6_dst_ops.gc_thresh,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ },
+ { }
+};
+
+static struct ctl_table_header *sysctl_hdr;
+
int __init xfrm6_init(void)
{
int ret;
@@ -317,6 +331,8 @@ int __init xfrm6_init(void)
ret = xfrm6_state_init();
if (ret)
goto out_policy;
+ sysctl_hdr = register_net_sysctl_table(&init_net, net_ipv6_ctl_path,
+ xfrm6_policy_table);
out:
return ret;
out_policy:
@@ -326,6 +342,8 @@ out_policy:
void xfrm6_fini(void)
{
+ if (sysctl_hdr)
+ unregister_net_sysctl_table(sysctl_hdr);
//xfrm6_input_fini();
xfrm6_policy_fini();
xfrm6_state_fini();