aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netns/ipv4.h1
-rw-r--r--include/net/netns/ipv6.h1
-rw-r--r--net/ipv4/xfrm4_policy.c49
-rw-r--r--net/ipv6/xfrm6_policy.c52
4 files changed, 95 insertions, 8 deletions
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index 9b78862014a4..2ba9de89e8ec 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -22,6 +22,7 @@ struct netns_ipv4 {
22 struct ctl_table_header *frags_hdr; 22 struct ctl_table_header *frags_hdr;
23 struct ctl_table_header *ipv4_hdr; 23 struct ctl_table_header *ipv4_hdr;
24 struct ctl_table_header *route_hdr; 24 struct ctl_table_header *route_hdr;
25 struct ctl_table_header *xfrm4_hdr;
25#endif 26#endif
26 struct ipv4_devconf *devconf_all; 27 struct ipv4_devconf *devconf_all;
27 struct ipv4_devconf *devconf_dflt; 28 struct ipv4_devconf *devconf_dflt;
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index 214cb0a53359..1242f371718b 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -16,6 +16,7 @@ struct netns_sysctl_ipv6 {
16 struct ctl_table_header *route_hdr; 16 struct ctl_table_header *route_hdr;
17 struct ctl_table_header *icmp_hdr; 17 struct ctl_table_header *icmp_hdr;
18 struct ctl_table_header *frags_hdr; 18 struct ctl_table_header *frags_hdr;
19 struct ctl_table_header *xfrm6_hdr;
19#endif 20#endif
20 int bindv6only; 21 int bindv6only;
21 int flush_delay; 22 int flush_delay;
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 0e28383c096f..9a459be24af7 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -262,7 +262,51 @@ static struct ctl_table xfrm4_policy_table[] = {
262 { } 262 { }
263}; 263};
264 264
265static struct ctl_table_header *sysctl_hdr; 265static int __net_init xfrm4_net_init(struct net *net)
266{
267 struct ctl_table *table;
268 struct ctl_table_header *hdr;
269
270 table = xfrm4_policy_table;
271 if (!net_eq(net, &init_net)) {
272 table = kmemdup(table, sizeof(xfrm4_policy_table), GFP_KERNEL);
273 if (!table)
274 goto err_alloc;
275
276 table[0].data = &net->xfrm.xfrm4_dst_ops.gc_thresh;
277 }
278
279 hdr = register_net_sysctl(net, "net/ipv4", table);
280 if (!hdr)
281 goto err_reg;
282
283 net->ipv4.xfrm4_hdr = hdr;
284 return 0;
285
286err_reg:
287 if (!net_eq(net, &init_net))
288 kfree(table);
289err_alloc:
290 return -ENOMEM;
291}
292
293static void __net_exit xfrm4_net_exit(struct net *net)
294{
295 struct ctl_table *table;
296
297 if (net->ipv4.xfrm4_hdr == NULL)
298 return;
299
300 table = net->ipv4.xfrm4_hdr->ctl_table_arg;
301 unregister_net_sysctl_table(net->ipv4.xfrm4_hdr);
302 if (!net_eq(net, &init_net))
303 kfree(table);
304}
305
306static struct pernet_operations __net_initdata xfrm4_net_ops = {
307 .init = xfrm4_net_init,
308 .exit = xfrm4_net_exit,
309};
266#endif 310#endif
267 311
268static void __init xfrm4_policy_init(void) 312static void __init xfrm4_policy_init(void)
@@ -277,8 +321,7 @@ void __init xfrm4_init(void)
277 xfrm4_state_init(); 321 xfrm4_state_init();
278 xfrm4_policy_init(); 322 xfrm4_policy_init();
279#ifdef CONFIG_SYSCTL 323#ifdef CONFIG_SYSCTL
280 sysctl_hdr = register_net_sysctl(&init_net, "net/ipv4", 324 register_pernet_subsys(&xfrm4_net_ops);
281 xfrm4_policy_table);
282#endif 325#endif
283} 326}
284 327
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
323static struct ctl_table_header *sysctl_hdr; 323static 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
344err_reg:
345 if (!net_eq(net, &init_net))
346 kfree(table);
347err_alloc:
348 return -ENOMEM;
349}
350
351static 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
364static struct pernet_operations xfrm6_net_ops = {
365 .init = xfrm6_net_init,
366 .exit = xfrm6_net_exit,
367};
324#endif 368#endif
325 369
326int __init xfrm6_init(void) 370int __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
345out: 388out:
346 return ret; 389 return ret;
@@ -352,8 +395,7 @@ out_policy:
352void xfrm6_fini(void) 395void 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();