Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[cascardo/linux.git] / net / ipv6 / ip6_fib.c
index 0c220a4..a83bf06 100644 (file)
@@ -197,6 +197,7 @@ static struct fib6_table *fib6_alloc_table(struct net *net, u32 id)
                table->tb6_id = id;
                table->tb6_root.leaf = net->ipv6.ip6_null_entry;
                table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
+               inet_peer_base_init(&table->tb6_peers);
        }
 
        return table;
@@ -1561,7 +1562,7 @@ static int fib6_age(struct rt6_info *rt, void *arg)
                                neigh_flags = neigh->flags;
                                neigh_release(neigh);
                        }
-                       if (neigh_flags & NTF_ROUTER) {
+                       if (!(neigh_flags & NTF_ROUTER)) {
                                RT6_TRACE("purging route %p via non-router but gateway\n",
                                          rt);
                                return -1;
@@ -1633,6 +1634,7 @@ static int __net_init fib6_net_init(struct net *net)
        net->ipv6.fib6_main_tbl->tb6_root.leaf = net->ipv6.ip6_null_entry;
        net->ipv6.fib6_main_tbl->tb6_root.fn_flags =
                RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
+       inet_peer_base_init(&net->ipv6.fib6_main_tbl->tb6_peers);
 
 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
        net->ipv6.fib6_local_tbl = kzalloc(sizeof(*net->ipv6.fib6_local_tbl),
@@ -1643,6 +1645,7 @@ static int __net_init fib6_net_init(struct net *net)
        net->ipv6.fib6_local_tbl->tb6_root.leaf = net->ipv6.ip6_null_entry;
        net->ipv6.fib6_local_tbl->tb6_root.fn_flags =
                RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
+       inet_peer_base_init(&net->ipv6.fib6_local_tbl->tb6_peers);
 #endif
        fib6_tables_init(net);
 
@@ -1666,8 +1669,10 @@ static void fib6_net_exit(struct net *net)
        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);
        kfree(net->ipv6.fib_table_hash);
        kfree(net->ipv6.rt6_stats);
@@ -1692,21 +1697,25 @@ int __init fib6_init(void)
        ret = register_pernet_subsys(&fib6_net_ops);
        if (ret)
                goto out_kmem_cache_create;
-
-       ret = __rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib,
-                             NULL);
-       if (ret)
-               goto out_unregister_subsys;
 out:
        return ret;
 
-out_unregister_subsys:
-       unregister_pernet_subsys(&fib6_net_ops);
 out_kmem_cache_create:
        kmem_cache_destroy(fib6_node_kmem);
        goto out;
 }
 
+int __init fib6_init_late(void)
+{
+       return __rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib,
+                              NULL);
+}
+
+void fib6_cleanup_late(void)
+{
+       rtnl_unregister(PF_INET6, RTM_GETROUTE);
+}
+
 void fib6_gc_cleanup(void)
 {
        unregister_pernet_subsys(&fib6_net_ops);