aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6mr.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ip6mr.c')
-rw-r--r--net/ipv6/ip6mr.c19
1 files changed, 8 insertions, 11 deletions
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index ad19136086dd..a10e77103c88 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -118,7 +118,7 @@ static void mr6_netlink_event(struct mr6_table *mrt, struct mfc6_cache *mfc,
118 int cmd); 118 int cmd);
119static int ip6mr_rtm_dumproute(struct sk_buff *skb, 119static int ip6mr_rtm_dumproute(struct sk_buff *skb,
120 struct netlink_callback *cb); 120 struct netlink_callback *cb);
121static void mroute_clean_tables(struct mr6_table *mrt); 121static void mroute_clean_tables(struct mr6_table *mrt, bool all);
122static void ipmr_expire_process(unsigned long arg); 122static void ipmr_expire_process(unsigned long arg);
123 123
124#ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES 124#ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
@@ -334,7 +334,7 @@ static struct mr6_table *ip6mr_new_table(struct net *net, u32 id)
334static void ip6mr_free_table(struct mr6_table *mrt) 334static void ip6mr_free_table(struct mr6_table *mrt)
335{ 335{
336 del_timer_sync(&mrt->ipmr_expire_timer); 336 del_timer_sync(&mrt->ipmr_expire_timer);
337 mroute_clean_tables(mrt); 337 mroute_clean_tables(mrt, true);
338 kfree(mrt); 338 kfree(mrt);
339} 339}
340 340
@@ -765,10 +765,6 @@ static struct net_device *ip6mr_reg_vif(struct net *net, struct mr6_table *mrt)
765 return dev; 765 return dev;
766 766
767failure: 767failure:
768 /* allow the register to be completed before unregistering. */
769 rtnl_unlock();
770 rtnl_lock();
771
772 unregister_netdevice(dev); 768 unregister_netdevice(dev);
773 return NULL; 769 return NULL;
774} 770}
@@ -1542,7 +1538,7 @@ static int ip6mr_mfc_add(struct net *net, struct mr6_table *mrt,
1542 * Close the multicast socket, and clear the vif tables etc 1538 * Close the multicast socket, and clear the vif tables etc
1543 */ 1539 */
1544 1540
1545static void mroute_clean_tables(struct mr6_table *mrt) 1541static void mroute_clean_tables(struct mr6_table *mrt, bool all)
1546{ 1542{
1547 int i; 1543 int i;
1548 LIST_HEAD(list); 1544 LIST_HEAD(list);
@@ -1552,8 +1548,9 @@ static void mroute_clean_tables(struct mr6_table *mrt)
1552 * Shut down all active vif entries 1548 * Shut down all active vif entries
1553 */ 1549 */
1554 for (i = 0; i < mrt->maxvif; i++) { 1550 for (i = 0; i < mrt->maxvif; i++) {
1555 if (!(mrt->vif6_table[i].flags & VIFF_STATIC)) 1551 if (!all && (mrt->vif6_table[i].flags & VIFF_STATIC))
1556 mif6_delete(mrt, i, &list); 1552 continue;
1553 mif6_delete(mrt, i, &list);
1557 } 1554 }
1558 unregister_netdevice_many(&list); 1555 unregister_netdevice_many(&list);
1559 1556
@@ -1562,7 +1559,7 @@ static void mroute_clean_tables(struct mr6_table *mrt)
1562 */ 1559 */
1563 for (i = 0; i < MFC6_LINES; i++) { 1560 for (i = 0; i < MFC6_LINES; i++) {
1564 list_for_each_entry_safe(c, next, &mrt->mfc6_cache_array[i], list) { 1561 list_for_each_entry_safe(c, next, &mrt->mfc6_cache_array[i], list) {
1565 if (c->mfc_flags & MFC_STATIC) 1562 if (!all && (c->mfc_flags & MFC_STATIC))
1566 continue; 1563 continue;
1567 write_lock_bh(&mrt_lock); 1564 write_lock_bh(&mrt_lock);
1568 list_del(&c->list); 1565 list_del(&c->list);
@@ -1625,7 +1622,7 @@ int ip6mr_sk_done(struct sock *sk)
1625 net->ipv6.devconf_all); 1622 net->ipv6.devconf_all);
1626 write_unlock_bh(&mrt_lock); 1623 write_unlock_bh(&mrt_lock);
1627 1624
1628 mroute_clean_tables(mrt); 1625 mroute_clean_tables(mrt, false);
1629 err = 0; 1626 err = 0;
1630 break; 1627 break;
1631 } 1628 }