|
@@ -134,7 +134,7 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
|
|
|
struct mfc_cache *c, struct rtmsg *rtm);
|
|
|
static void mroute_netlink_event(struct mr_table *mrt, struct mfc_cache *mfc,
|
|
|
int cmd);
|
|
|
-static void mroute_clean_tables(struct mr_table *mrt);
|
|
|
+static void mroute_clean_tables(struct mr_table *mrt, bool all);
|
|
|
static void ipmr_expire_process(unsigned long arg);
|
|
|
|
|
|
#ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES
|
|
@@ -350,7 +350,7 @@ static struct mr_table *ipmr_new_table(struct net *net, u32 id)
|
|
|
static void ipmr_free_table(struct mr_table *mrt)
|
|
|
{
|
|
|
del_timer_sync(&mrt->ipmr_expire_timer);
|
|
|
- mroute_clean_tables(mrt);
|
|
|
+ mroute_clean_tables(mrt, true);
|
|
|
kfree(mrt);
|
|
|
}
|
|
|
|
|
@@ -1208,7 +1208,7 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
|
|
|
* Close the multicast socket, and clear the vif tables etc
|
|
|
*/
|
|
|
|
|
|
-static void mroute_clean_tables(struct mr_table *mrt)
|
|
|
+static void mroute_clean_tables(struct mr_table *mrt, bool all)
|
|
|
{
|
|
|
int i;
|
|
|
LIST_HEAD(list);
|
|
@@ -1217,8 +1217,9 @@ static void mroute_clean_tables(struct mr_table *mrt)
|
|
|
/* Shut down all active vif entries */
|
|
|
|
|
|
for (i = 0; i < mrt->maxvif; i++) {
|
|
|
- if (!(mrt->vif_table[i].flags & VIFF_STATIC))
|
|
|
- vif_delete(mrt, i, 0, &list);
|
|
|
+ if (!all && (mrt->vif_table[i].flags & VIFF_STATIC))
|
|
|
+ continue;
|
|
|
+ vif_delete(mrt, i, 0, &list);
|
|
|
}
|
|
|
unregister_netdevice_many(&list);
|
|
|
|
|
@@ -1226,7 +1227,7 @@ static void mroute_clean_tables(struct mr_table *mrt)
|
|
|
|
|
|
for (i = 0; i < MFC_LINES; i++) {
|
|
|
list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[i], list) {
|
|
|
- if (c->mfc_flags & MFC_STATIC)
|
|
|
+ if (!all && (c->mfc_flags & MFC_STATIC))
|
|
|
continue;
|
|
|
list_del_rcu(&c->list);
|
|
|
mroute_netlink_event(mrt, c, RTM_DELROUTE);
|
|
@@ -1261,7 +1262,7 @@ static void mrtsock_destruct(struct sock *sk)
|
|
|
NETCONFA_IFINDEX_ALL,
|
|
|
net->ipv4.devconf_all);
|
|
|
RCU_INIT_POINTER(mrt->mroute_sk, NULL);
|
|
|
- mroute_clean_tables(mrt);
|
|
|
+ mroute_clean_tables(mrt, false);
|
|
|
}
|
|
|
}
|
|
|
rtnl_unlock();
|