diff options
-rw-r--r-- | include/net/xfrm.h | 3 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 11 | ||||
-rw-r--r-- | net/xfrm/xfrm_proc.c | 26 |
3 files changed, 21 insertions, 19 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 78ec3e8a95ed..1554ccd0c940 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1306,7 +1306,8 @@ static inline void xfrm6_fini(void) #endif #ifdef CONFIG_XFRM_STATISTICS -extern int xfrm_proc_init(void); +extern int xfrm_proc_init(struct net *net); +extern void xfrm_proc_fini(struct net *net); #endif extern void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto); diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index e239a25e571c..38822b34ba7d 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -2377,14 +2377,20 @@ static struct notifier_block xfrm_dev_notifier = { #ifdef CONFIG_XFRM_STATISTICS static int __net_init xfrm_statistics_init(struct net *net) { + int rv; + if (snmp_mib_init((void **)net->mib.xfrm_statistics, sizeof(struct linux_xfrm_mib)) < 0) return -ENOMEM; - return 0; + rv = xfrm_proc_init(net); + if (rv < 0) + snmp_mib_free((void **)net->mib.xfrm_statistics); + return rv; } static void xfrm_statistics_fini(struct net *net) { + xfrm_proc_fini(net); snmp_mib_free((void **)net->mib.xfrm_statistics); } #else @@ -2524,9 +2530,6 @@ void __init xfrm_init(void) { register_pernet_subsys(&xfrm_net_ops); xfrm_input_init(); -#ifdef CONFIG_XFRM_STATISTICS - xfrm_proc_init(); -#endif } #ifdef CONFIG_AUDITSYSCALL diff --git a/net/xfrm/xfrm_proc.c b/net/xfrm/xfrm_proc.c index 27a2ab92d874..284eaef1dbf2 100644 --- a/net/xfrm/xfrm_proc.c +++ b/net/xfrm/xfrm_proc.c @@ -59,17 +59,18 @@ fold_field(void *mib[], int offt) static int xfrm_statistics_seq_show(struct seq_file *seq, void *v) { + struct net *net = seq->private; int i; for (i=0; xfrm_mib_list[i].name; i++) seq_printf(seq, "%-24s\t%lu\n", xfrm_mib_list[i].name, - fold_field((void **)init_net.mib.xfrm_statistics, + fold_field((void **)net->mib.xfrm_statistics, xfrm_mib_list[i].entry)); return 0; } static int xfrm_statistics_seq_open(struct inode *inode, struct file *file) { - return single_open(file, xfrm_statistics_seq_show, NULL); + return single_open_net(inode, file, xfrm_statistics_seq_show); } static struct file_operations xfrm_statistics_seq_fops = { @@ -77,21 +78,18 @@ static struct file_operations xfrm_statistics_seq_fops = { .open = xfrm_statistics_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = single_release, + .release = single_release_net, }; -int __init xfrm_proc_init(void) +int __net_init xfrm_proc_init(struct net *net) { - int rc = 0; - - if (!proc_net_fops_create(&init_net, "xfrm_stat", S_IRUGO, + if (!proc_net_fops_create(net, "xfrm_stat", S_IRUGO, &xfrm_statistics_seq_fops)) - goto stat_fail; - - out: - return rc; + return -ENOMEM; + return 0; +} - stat_fail: - rc = -ENOMEM; - goto out; +void xfrm_proc_fini(struct net *net) +{ + proc_net_remove(net, "xfrm_stat"); } |