diff options
author | Wang Chen <wangchen@cn.fujitsu.com> | 2008-07-03 00:13:30 -0400 |
---|---|---|
committer | YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> | 2008-07-03 04:51:56 -0400 |
commit | 623d1a1af77bd52a389c6eda5920e28eb2ee468b (patch) | |
tree | 85d0a7fbcd83b5a2cacf50b24a66c0063f7eca07 /net/ipv6/ip6mr.c | |
parent | dd3abc4ef52597ec8268274222574b2700ba3ded (diff) |
ipv6: Do cleanup for ip6_mr_init.
If do not do it, we will get following issues:
1. Leaving junks after inet6_init failing halfway.
2. Leaving proc and notifier junks after ipv6 modules unloading.
Signed-off-by: Wang Chen <wangchen@cn.fujitsu.com>
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Diffstat (limited to 'net/ipv6/ip6mr.c')
-rw-r--r-- | net/ipv6/ip6mr.c | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 90e763073dc5..cfac26d674ed 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -948,23 +948,51 @@ static struct notifier_block ip6_mr_notifier = { | |||
948 | * Setup for IP multicast routing | 948 | * Setup for IP multicast routing |
949 | */ | 949 | */ |
950 | 950 | ||
951 | void __init ip6_mr_init(void) | 951 | int __init ip6_mr_init(void) |
952 | { | 952 | { |
953 | int err; | ||
954 | |||
953 | mrt_cachep = kmem_cache_create("ip6_mrt_cache", | 955 | mrt_cachep = kmem_cache_create("ip6_mrt_cache", |
954 | sizeof(struct mfc6_cache), | 956 | sizeof(struct mfc6_cache), |
955 | 0, SLAB_HWCACHE_ALIGN, | 957 | 0, SLAB_HWCACHE_ALIGN, |
956 | NULL); | 958 | NULL); |
957 | if (!mrt_cachep) | 959 | if (!mrt_cachep) |
958 | panic("cannot allocate ip6_mrt_cache"); | 960 | return -ENOMEM; |
959 | 961 | ||
960 | setup_timer(&ipmr_expire_timer, ipmr_expire_process, 0); | 962 | setup_timer(&ipmr_expire_timer, ipmr_expire_process, 0); |
961 | register_netdevice_notifier(&ip6_mr_notifier); | 963 | err = register_netdevice_notifier(&ip6_mr_notifier); |
964 | if (err) | ||
965 | goto reg_notif_fail; | ||
966 | #ifdef CONFIG_PROC_FS | ||
967 | err = -ENOMEM; | ||
968 | if (!proc_net_fops_create(&init_net, "ip6_mr_vif", 0, &ip6mr_vif_fops)) | ||
969 | goto proc_vif_fail; | ||
970 | if (!proc_net_fops_create(&init_net, "ip6_mr_cache", | ||
971 | 0, &ip6mr_mfc_fops)) | ||
972 | goto proc_cache_fail; | ||
973 | #endif | ||
974 | return 0; | ||
975 | reg_notif_fail: | ||
976 | kmem_cache_destroy(mrt_cachep); | ||
962 | #ifdef CONFIG_PROC_FS | 977 | #ifdef CONFIG_PROC_FS |
963 | proc_net_fops_create(&init_net, "ip6_mr_vif", 0, &ip6mr_vif_fops); | 978 | proc_vif_fail: |
964 | proc_net_fops_create(&init_net, "ip6_mr_cache", 0, &ip6mr_mfc_fops); | 979 | unregister_netdevice_notifier(&ip6_mr_notifier); |
980 | proc_cache_fail: | ||
981 | proc_net_remove(&init_net, "ip6_mr_vif"); | ||
965 | #endif | 982 | #endif |
983 | return err; | ||
966 | } | 984 | } |
967 | 985 | ||
986 | void ip6_mr_cleanup(void) | ||
987 | { | ||
988 | #ifdef CONFIG_PROC_FS | ||
989 | proc_net_remove(&init_net, "ip6_mr_cache"); | ||
990 | proc_net_remove(&init_net, "ip6_mr_vif"); | ||
991 | #endif | ||
992 | unregister_netdevice_notifier(&ip6_mr_notifier); | ||
993 | del_timer(&ipmr_expire_timer); | ||
994 | kmem_cache_destroy(mrt_cachep); | ||
995 | } | ||
968 | 996 | ||
969 | static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock) | 997 | static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock) |
970 | { | 998 | { |