Skip to content

Commit 623d1a1

Browse files
Wang Chenyoshfuji
authored andcommitted
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>
1 parent dd3abc4 commit 623d1a1

File tree

3 files changed

+45
-7
lines changed

3 files changed

+45
-7
lines changed

include/linux/mroute6.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ extern int ip6_mroute_setsockopt(struct sock *, int, char __user *, int);
135135
extern int ip6_mroute_getsockopt(struct sock *, int, char __user *, int __user *);
136136
extern int ip6_mr_input(struct sk_buff *skb);
137137
extern int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg);
138-
extern void ip6_mr_init(void);
138+
extern int ip6_mr_init(void);
139+
extern void ip6_mr_cleanup(void);
139140

140141
struct mif_device
141142
{

net/ipv6/af_inet6.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,9 @@ static int __init inet6_init(void)
953953
if (err)
954954
goto icmp_fail;
955955
#ifdef CONFIG_IPV6_MROUTE
956-
ip6_mr_init();
956+
err = ip6_mr_init();
957+
if (err)
958+
goto ipmr_fail;
957959
#endif
958960
err = ndisc_init();
959961
if (err)
@@ -1057,6 +1059,10 @@ static int __init inet6_init(void)
10571059
igmp_fail:
10581060
ndisc_cleanup();
10591061
ndisc_fail:
1062+
#ifdef CONFIG_IPV6_MROUTE
1063+
ip6_mr_cleanup();
1064+
ipmr_fail:
1065+
#endif
10601066
icmpv6_cleanup();
10611067
icmp_fail:
10621068
unregister_pernet_subsys(&inet6_net_ops);
@@ -1111,6 +1117,9 @@ static void __exit inet6_exit(void)
11111117
ipv6_netfilter_fini();
11121118
igmp6_cleanup();
11131119
ndisc_cleanup();
1120+
#ifdef CONFIG_IPV6_MROUTE
1121+
ip6_mr_cleanup();
1122+
#endif
11141123
icmpv6_cleanup();
11151124
rawv6_exit();
11161125

net/ipv6/ip6mr.c

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -948,23 +948,51 @@ static struct notifier_block ip6_mr_notifier = {
948948
* Setup for IP multicast routing
949949
*/
950950

951-
void __init ip6_mr_init(void)
951+
int __init ip6_mr_init(void)
952952
{
953+
int err;
954+
953955
mrt_cachep = kmem_cache_create("ip6_mrt_cache",
954956
sizeof(struct mfc6_cache),
955957
0, SLAB_HWCACHE_ALIGN,
956958
NULL);
957959
if (!mrt_cachep)
958-
panic("cannot allocate ip6_mrt_cache");
960+
return -ENOMEM;
959961

960962
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);
962977
#ifdef CONFIG_PROC_FS
963-
proc_net_fops_create(&init_net, "ip6_mr_vif", 0, &ip6mr_vif_fops);
964-
proc_net_fops_create(&init_net, "ip6_mr_cache", 0, &ip6mr_mfc_fops);
978+
proc_vif_fail:
979+
unregister_netdevice_notifier(&ip6_mr_notifier);
980+
proc_cache_fail:
981+
proc_net_remove(&init_net, "ip6_mr_vif");
965982
#endif
983+
return err;
966984
}
967985

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+
}
968996

969997
static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock)
970998
{

0 commit comments

Comments
 (0)