diff options
-rw-r--r-- | include/net/netns/ipv4.h | 1 | ||||
-rw-r--r-- | include/net/netns/ipv6.h | 1 | ||||
-rw-r--r-- | net/ipv4/xfrm4_policy.c | 49 | ||||
-rw-r--r-- | net/ipv6/xfrm6_policy.c | 52 |
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 | ||
265 | static struct ctl_table_header *sysctl_hdr; | 265 | static 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 | |||
286 | err_reg: | ||
287 | if (!net_eq(net, &init_net)) | ||
288 | kfree(table); | ||
289 | err_alloc: | ||
290 | return -ENOMEM; | ||
291 | } | ||
292 | |||
293 | static 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 | |||
306 | static 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 | ||
268 | static void __init xfrm4_policy_init(void) | 312 | static 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 | ||
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(); |