Skip to content

Commit 4eb5e5c

Browse files
Nikolay Aleksandrovgregkh
authored andcommitted
net: ip6mr: fix static mfc/dev leaks on table destruction
[ Upstream commit 4c69804 ] Similar to ipv4, when destroying an mrt table the static mfc entries and the static devices are kept, which leads to devices that can never be destroyed (because of refcnt taken) and leaked memory. Make sure that everything is cleaned up on netns destruction. Fixes: 8229efd ("netns: ip6mr: enable namespace support in ipv6 multicast forwarding code") CC: Benjamin Thery <[email protected]> Signed-off-by: Nikolay Aleksandrov <[email protected]> Reviewed-by: Cong Wang <[email protected]> Signed-off-by: David S. Miller <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 47f7066 commit 4eb5e5c

File tree

1 file changed

+8
-7
lines changed

1 file changed

+8
-7
lines changed

net/ipv6/ip6mr.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ static void mr6_netlink_event(struct mr6_table *mrt, struct mfc6_cache *mfc,
118118
int cmd);
119119
static int ip6mr_rtm_dumproute(struct sk_buff *skb,
120120
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);
122122
static void ipmr_expire_process(unsigned long arg);
123123

124124
#ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
@@ -334,7 +334,7 @@ static struct mr6_table *ip6mr_new_table(struct net *net, u32 id)
334334
static void ip6mr_free_table(struct mr6_table *mrt)
335335
{
336336
del_timer_sync(&mrt->ipmr_expire_timer);
337-
mroute_clean_tables(mrt);
337+
mroute_clean_tables(mrt, true);
338338
kfree(mrt);
339339
}
340340

@@ -1542,7 +1542,7 @@ static int ip6mr_mfc_add(struct net *net, struct mr6_table *mrt,
15421542
* Close the multicast socket, and clear the vif tables etc
15431543
*/
15441544

1545-
static void mroute_clean_tables(struct mr6_table *mrt)
1545+
static void mroute_clean_tables(struct mr6_table *mrt, bool all)
15461546
{
15471547
int i;
15481548
LIST_HEAD(list);
@@ -1552,8 +1552,9 @@ static void mroute_clean_tables(struct mr6_table *mrt)
15521552
* Shut down all active vif entries
15531553
*/
15541554
for (i = 0; i < mrt->maxvif; i++) {
1555-
if (!(mrt->vif6_table[i].flags & VIFF_STATIC))
1556-
mif6_delete(mrt, i, &list);
1555+
if (!all && (mrt->vif6_table[i].flags & VIFF_STATIC))
1556+
continue;
1557+
mif6_delete(mrt, i, &list);
15571558
}
15581559
unregister_netdevice_many(&list);
15591560

@@ -1562,7 +1563,7 @@ static void mroute_clean_tables(struct mr6_table *mrt)
15621563
*/
15631564
for (i = 0; i < MFC6_LINES; i++) {
15641565
list_for_each_entry_safe(c, next, &mrt->mfc6_cache_array[i], list) {
1565-
if (c->mfc_flags & MFC_STATIC)
1566+
if (!all && (c->mfc_flags & MFC_STATIC))
15661567
continue;
15671568
write_lock_bh(&mrt_lock);
15681569
list_del(&c->list);
@@ -1625,7 +1626,7 @@ int ip6mr_sk_done(struct sock *sk)
16251626
net->ipv6.devconf_all);
16261627
write_unlock_bh(&mrt_lock);
16271628

1628-
mroute_clean_tables(mrt);
1629+
mroute_clean_tables(mrt, false);
16291630
err = 0;
16301631
break;
16311632
}

0 commit comments

Comments
 (0)