diff options
Diffstat (limited to 'net/ipv4/ipmr.c')
| -rw-r--r-- | net/ipv4/ipmr.c | 20 | 
1 files changed, 15 insertions, 5 deletions
| diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 29bbe2b08ae9..c860519d57ee 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -268,13 +268,12 @@ static void __net_exit ipmr_rules_exit(struct net *net)  {  	struct mr_table *mrt, *next; -	rtnl_lock(); +	ASSERT_RTNL();  	list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) {  		list_del(&mrt->list);  		ipmr_free_table(mrt);  	}  	fib_rules_unregister(net->ipv4.mr_rules_ops); -	rtnl_unlock();  }  static int ipmr_rules_dump(struct net *net, struct notifier_block *nb, @@ -330,10 +329,9 @@ static int __net_init ipmr_rules_init(struct net *net)  static void __net_exit ipmr_rules_exit(struct net *net)  { -	rtnl_lock(); +	ASSERT_RTNL();  	ipmr_free_table(net->ipv4.mrt);  	net->ipv4.mrt = NULL; -	rtnl_unlock();  }  static int ipmr_rules_dump(struct net *net, struct notifier_block *nb, @@ -3077,7 +3075,9 @@ static int __net_init ipmr_net_init(struct net *net)  proc_cache_fail:  	remove_proc_entry("ip_mr_vif", net->proc_net);  proc_vif_fail: +	rtnl_lock();  	ipmr_rules_exit(net); +	rtnl_unlock();  #endif  ipmr_rules_fail:  	ipmr_notifier_exit(net); @@ -3092,12 +3092,22 @@ static void __net_exit ipmr_net_exit(struct net *net)  	remove_proc_entry("ip_mr_vif", net->proc_net);  #endif  	ipmr_notifier_exit(net); -	ipmr_rules_exit(net); +} + +static void __net_exit ipmr_net_exit_batch(struct list_head *net_list) +{ +	struct net *net; + +	rtnl_lock(); +	list_for_each_entry(net, net_list, exit_list) +		ipmr_rules_exit(net); +	rtnl_unlock();  }  static struct pernet_operations ipmr_net_ops = {  	.init = ipmr_net_init,  	.exit = ipmr_net_exit, +	.exit_batch = ipmr_net_exit_batch,  };  int __init ip_mr_init(void) | 
