aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWang Chen <wangchen@cn.fujitsu.com>2008-07-03 00:13:30 -0400
committerYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>2008-07-03 04:51:56 -0400
commit623d1a1af77bd52a389c6eda5920e28eb2ee468b (patch)
tree85d0a7fbcd83b5a2cacf50b24a66c0063f7eca07
parentdd3abc4ef52597ec8268274222574b2700ba3ded (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>
-rw-r--r--include/linux/mroute6.h3
-rw-r--r--net/ipv6/af_inet6.c11
-rw-r--r--net/ipv6/ip6mr.c38
3 files changed, 45 insertions, 7 deletions
diff --git a/include/linux/mroute6.h b/include/linux/mroute6.h
index e7989593142b..4c4d6f57d5c5 100644
--- a/include/linux/mroute6.h
+++ b/include/linux/mroute6.h
@@ -135,7 +135,8 @@ extern int ip6_mroute_setsockopt(struct sock *, int, char __user *, int);
135extern int ip6_mroute_getsockopt(struct sock *, int, char __user *, int __user *); 135extern int ip6_mroute_getsockopt(struct sock *, int, char __user *, int __user *);
136extern int ip6_mr_input(struct sk_buff *skb); 136extern int ip6_mr_input(struct sk_buff *skb);
137extern int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg); 137extern int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg);
138extern void ip6_mr_init(void); 138extern int ip6_mr_init(void);
139extern void ip6_mr_cleanup(void);
139 140
140struct mif_device 141struct mif_device
141{ 142{
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 3ce8d2f318c6..6b39af1acb5e 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -953,7 +953,9 @@ static int __init inet6_init(void)
953 if (err) 953 if (err)
954 goto icmp_fail; 954 goto icmp_fail;
955#ifdef CONFIG_IPV6_MROUTE 955#ifdef CONFIG_IPV6_MROUTE
956 ip6_mr_init(); 956 err = ip6_mr_init();
957 if (err)
958 goto ipmr_fail;
957#endif 959#endif
958 err = ndisc_init(); 960 err = ndisc_init();
959 if (err) 961 if (err)
@@ -1057,6 +1059,10 @@ netfilter_fail:
1057igmp_fail: 1059igmp_fail:
1058 ndisc_cleanup(); 1060 ndisc_cleanup();
1059ndisc_fail: 1061ndisc_fail:
1062#ifdef CONFIG_IPV6_MROUTE
1063 ip6_mr_cleanup();
1064ipmr_fail:
1065#endif
1060 icmpv6_cleanup(); 1066 icmpv6_cleanup();
1061icmp_fail: 1067icmp_fail:
1062 unregister_pernet_subsys(&inet6_net_ops); 1068 unregister_pernet_subsys(&inet6_net_ops);
@@ -1111,6 +1117,9 @@ static void __exit inet6_exit(void)
1111 ipv6_netfilter_fini(); 1117 ipv6_netfilter_fini();
1112 igmp6_cleanup(); 1118 igmp6_cleanup();
1113 ndisc_cleanup(); 1119 ndisc_cleanup();
1120#ifdef CONFIG_IPV6_MROUTE
1121 ip6_mr_cleanup();
1122#endif
1114 icmpv6_cleanup(); 1123 icmpv6_cleanup();
1115 rawv6_exit(); 1124 rawv6_exit();
1116 1125
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
951void __init ip6_mr_init(void) 951int __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;
975reg_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); 978proc_vif_fail:
964 proc_net_fops_create(&init_net, "ip6_mr_cache", 0, &ip6mr_mfc_fops); 979 unregister_netdevice_notifier(&ip6_mr_notifier);
980proc_cache_fail:
981 proc_net_remove(&init_net, "ip6_mr_vif");
965#endif 982#endif
983 return err;
966} 984}
967 985
986void 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
969static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock) 997static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock)
970{ 998{