Commit 4aa2c466 authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by David S. Miller

fib: Fix fib zone and its hash leak on namespace stop

When we stop a namespace we flush the table and free one, but the
added fn_zone-s (and their hashes if grown) are leaked. Need to free.
Tries releases all its stuff in the flushing code.

Shame on us - this bug exists since the very first make-fib-per-net
patches in 2.6.27 :(
Signed-off-by: default avatarPavel Emelyanov <xemul@openvz.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b1424ed9
...@@ -158,6 +158,8 @@ extern int fib_table_flush(struct fib_table *table); ...@@ -158,6 +158,8 @@ extern int fib_table_flush(struct fib_table *table);
extern void fib_table_select_default(struct fib_table *table, extern void fib_table_select_default(struct fib_table *table,
const struct flowi *flp, const struct flowi *flp,
struct fib_result *res); struct fib_result *res);
extern void fib_free_table(struct fib_table *tb);
#ifndef CONFIG_IP_MULTIPLE_TABLES #ifndef CONFIG_IP_MULTIPLE_TABLES
......
...@@ -1052,7 +1052,7 @@ static void ip_fib_net_exit(struct net *net) ...@@ -1052,7 +1052,7 @@ static void ip_fib_net_exit(struct net *net)
hlist_for_each_entry_safe(tb, node, tmp, head, tb_hlist) { hlist_for_each_entry_safe(tb, node, tmp, head, tb_hlist) {
hlist_del(node); hlist_del(node);
fib_table_flush(tb); fib_table_flush(tb);
kfree(tb); fib_free_table(tb);
} }
} }
kfree(net->ipv4.fib_table_hash); kfree(net->ipv4.fib_table_hash);
......
...@@ -716,6 +716,24 @@ int fib_table_flush(struct fib_table *tb) ...@@ -716,6 +716,24 @@ int fib_table_flush(struct fib_table *tb)
return found; return found;
} }
void fib_free_table(struct fib_table *tb)
{
struct fn_hash *table = (struct fn_hash *) tb->tb_data;
struct fn_zone *fz, *next;
next = table->fn_zone_list;
while (next != NULL) {
fz = next;
next = fz->fz_next;
if (fz->fz_hash != fz->fz_embedded_hash)
fz_hash_free(fz->fz_hash, fz->fz_divisor);
kfree(fz);
}
kfree(tb);
}
static inline int static inline int
fn_hash_dump_bucket(struct sk_buff *skb, struct netlink_callback *cb, fn_hash_dump_bucket(struct sk_buff *skb, struct netlink_callback *cb,
......
...@@ -1797,6 +1797,11 @@ int fib_table_flush(struct fib_table *tb) ...@@ -1797,6 +1797,11 @@ int fib_table_flush(struct fib_table *tb)
return found; return found;
} }
void fib_free_table(struct fib_table *tb)
{
kfree(tb);
}
void fib_table_select_default(struct fib_table *tb, void fib_table_select_default(struct fib_table *tb,
const struct flowi *flp, const struct flowi *flp,
struct fib_result *res) struct fib_result *res)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment