diff options
Diffstat (limited to 'net/ipv6/ip6mr.c')
-rw-r--r-- | net/ipv6/ip6mr.c | 19 |
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); |
119 | static int ip6mr_rtm_dumproute(struct sk_buff *skb, | 119 | static int ip6mr_rtm_dumproute(struct sk_buff *skb, |
120 | struct netlink_callback *cb); | 120 | struct netlink_callback *cb); |
121 | static void mroute_clean_tables(struct mr6_table *mrt); | 121 | static void mroute_clean_tables(struct mr6_table *mrt, bool all); |
122 | static void ipmr_expire_process(unsigned long arg); | 122 | static 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) | |||
334 | static void ip6mr_free_table(struct mr6_table *mrt) | 334 | static 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 | ||
767 | failure: | 767 | failure: |
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 | ||
1545 | static void mroute_clean_tables(struct mr6_table *mrt) | 1541 | static 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 | } |