|
@@ -191,6 +191,12 @@ void rt6_free_pcpu(struct rt6_info *non_pcpu_rt)
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(rt6_free_pcpu);
|
|
|
|
|
|
+static void fib6_free_table(struct fib6_table *table)
|
|
|
+{
|
|
|
+ inetpeer_invalidate_tree(&table->tb6_peers);
|
|
|
+ kfree(table);
|
|
|
+}
|
|
|
+
|
|
|
static void fib6_link_table(struct net *net, struct fib6_table *tb)
|
|
|
{
|
|
|
unsigned int h;
|
|
@@ -2022,15 +2028,22 @@ out_timer:
|
|
|
|
|
|
static void fib6_net_exit(struct net *net)
|
|
|
{
|
|
|
+ unsigned int i;
|
|
|
+
|
|
|
rt6_ifdown(net, NULL);
|
|
|
del_timer_sync(&net->ipv6.ip6_fib_timer);
|
|
|
|
|
|
-#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
|
|
- inetpeer_invalidate_tree(&net->ipv6.fib6_local_tbl->tb6_peers);
|
|
|
- kfree(net->ipv6.fib6_local_tbl);
|
|
|
-#endif
|
|
|
- inetpeer_invalidate_tree(&net->ipv6.fib6_main_tbl->tb6_peers);
|
|
|
- kfree(net->ipv6.fib6_main_tbl);
|
|
|
+ for (i = 0; i < FIB_TABLE_HASHSZ; i++) {
|
|
|
+ struct hlist_head *head = &net->ipv6.fib_table_hash[i];
|
|
|
+ struct hlist_node *tmp;
|
|
|
+ struct fib6_table *tb;
|
|
|
+
|
|
|
+ hlist_for_each_entry_safe(tb, tmp, head, tb6_hlist) {
|
|
|
+ hlist_del(&tb->tb6_hlist);
|
|
|
+ fib6_free_table(tb);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
kfree(net->ipv6.fib_table_hash);
|
|
|
kfree(net->ipv6.rt6_stats);
|
|
|
fib6_notifier_exit(net);
|