void *arg;
 };
 
-static DEFINE_RWLOCK(fib6_walker_lock);
-
 #ifdef CONFIG_IPV6_SUBTREES
 #define FWS_INIT FWS_S
 #else
 static void fib6_prune_clones(struct net *net, struct fib6_node *fn);
 static struct rt6_info *fib6_find_prefix(struct net *net, struct fib6_node *fn);
 static struct fib6_node *fib6_repair_tree(struct net *net, struct fib6_node *fn);
-static int fib6_walk(struct fib6_walker *w);
+static int fib6_walk(struct net *net, struct fib6_walker *w);
 static int fib6_walk_continue(struct fib6_walker *w);
 
 /*
 
 static void fib6_gc_timer_cb(unsigned long arg);
 
-static LIST_HEAD(fib6_walkers);
-#define FOR_WALKERS(w) list_for_each_entry(w, &fib6_walkers, lh)
+#define FOR_WALKERS(net, w) \
+       list_for_each_entry(w, &(net)->ipv6.fib6_walkers, lh)
 
-static void fib6_walker_link(struct fib6_walker *w)
+static void fib6_walker_link(struct net *net, struct fib6_walker *w)
 {
-       write_lock_bh(&fib6_walker_lock);
-       list_add(&w->lh, &fib6_walkers);
-       write_unlock_bh(&fib6_walker_lock);
+       write_lock_bh(&net->ipv6.fib6_walker_lock);
+       list_add(&w->lh, &net->ipv6.fib6_walkers);
+       write_unlock_bh(&net->ipv6.fib6_walker_lock);
 }
 
-static void fib6_walker_unlink(struct fib6_walker *w)
+static void fib6_walker_unlink(struct net *net, struct fib6_walker *w)
 {
-       write_lock_bh(&fib6_walker_lock);
+       write_lock_bh(&net->ipv6.fib6_walker_lock);
        list_del(&w->lh);
-       write_unlock_bh(&fib6_walker_lock);
+       write_unlock_bh(&net->ipv6.fib6_walker_lock);
 }
 
 static int fib6_new_sernum(struct net *net)
 
 static void fib6_dump_end(struct netlink_callback *cb)
 {
+       struct net *net = sock_net(cb->skb->sk);
        struct fib6_walker *w = (void *)cb->args[2];
 
        if (w) {
                if (cb->args[4]) {
                        cb->args[4] = 0;
-                       fib6_walker_unlink(w);
+                       fib6_walker_unlink(net, w);
                }
                cb->args[2] = 0;
                kfree(w);
 static int fib6_dump_table(struct fib6_table *table, struct sk_buff *skb,
                           struct netlink_callback *cb)
 {
+       struct net *net = sock_net(skb->sk);
        struct fib6_walker *w;
        int res;
 
                w->skip = 0;
 
                read_lock_bh(&table->tb6_lock);
-               res = fib6_walk(w);
+               res = fib6_walk(net, w);
                read_unlock_bh(&table->tb6_lock);
                if (res > 0) {
                        cb->args[4] = 1;
                res = fib6_walk_continue(w);
                read_unlock_bh(&table->tb6_lock);
                if (res <= 0) {
-                       fib6_walker_unlink(w);
+                       fib6_walker_unlink(net, w);
                        cb->args[4] = 0;
                }
        }
                }
 #endif
 
-               read_lock(&fib6_walker_lock);
-               FOR_WALKERS(w) {
+               read_lock(&net->ipv6.fib6_walker_lock);
+               FOR_WALKERS(net, w) {
                        if (!child) {
                                if (w->root == fn) {
                                        w->root = w->node = NULL;
                                }
                        }
                }
-               read_unlock(&fib6_walker_lock);
+               read_unlock(&net->ipv6.fib6_walker_lock);
 
                node_free(fn);
                if (pn->fn_flags & RTN_RTINFO || FIB6_SUBTREE(pn))
        }
 
        /* Adjust walkers */
-       read_lock(&fib6_walker_lock);
-       FOR_WALKERS(w) {
+       read_lock(&net->ipv6.fib6_walker_lock);
+       FOR_WALKERS(net, w) {
                if (w->state == FWS_C && w->leaf == rt) {
                        RT6_TRACE("walker %p adjusted by delroute\n", w);
                        w->leaf = rt->dst.rt6_next;
                                w->state = FWS_U;
                }
        }
-       read_unlock(&fib6_walker_lock);
+       read_unlock(&net->ipv6.fib6_walker_lock);
 
        rt->dst.rt6_next = NULL;
 
        }
 }
 
-static int fib6_walk(struct fib6_walker *w)
+static int fib6_walk(struct net *net, struct fib6_walker *w)
 {
        int res;
 
        w->state = FWS_INIT;
        w->node = w->root;
 
-       fib6_walker_link(w);
+       fib6_walker_link(net, w);
        res = fib6_walk_continue(w);
        if (res <= 0)
-               fib6_walker_unlink(w);
+               fib6_walker_unlink(net, w);
        return res;
 }
 
        c.arg = arg;
        c.net = net;
 
-       fib6_walk(&c.w);
+       fib6_walk(net, &c.w);
 }
 
 static void __fib6_clean_all(struct net *net,
 {
        size_t size = sizeof(struct hlist_head) * FIB6_TABLE_HASHSZ;
 
+       rwlock_init(&net->ipv6.fib6_walker_lock);
+       INIT_LIST_HEAD(&net->ipv6.fib6_walkers);
        setup_timer(&net->ipv6.ip6_fib_timer, fib6_gc_timer_cb, (unsigned long)net);
 
        net->ipv6.rt6_stats = kzalloc(sizeof(*net->ipv6.rt6_stats), GFP_KERNEL);
        return 0;
 }
 
-static void ipv6_route_seq_setup_walk(struct ipv6_route_iter *iter)
+static void ipv6_route_seq_setup_walk(struct ipv6_route_iter *iter,
+                                     struct net *net)
 {
        memset(&iter->w, 0, sizeof(iter->w));
        iter->w.func = ipv6_route_yield;
        iter->w.args = iter;
        iter->sernum = iter->w.root->fn_sernum;
        INIT_LIST_HEAD(&iter->w.lh);
-       fib6_walker_link(&iter->w);
+       fib6_walker_link(net, &iter->w);
 }
 
 static struct fib6_table *ipv6_route_seq_next_table(struct fib6_table *tbl,
                        ++*pos;
                return iter->w.leaf;
        } else if (r < 0) {
-               fib6_walker_unlink(&iter->w);
+               fib6_walker_unlink(net, &iter->w);
                return NULL;
        }
-       fib6_walker_unlink(&iter->w);
+       fib6_walker_unlink(net, &iter->w);
 
        iter->tbl = ipv6_route_seq_next_table(iter->tbl, net);
        if (!iter->tbl)
                return NULL;
 
-       ipv6_route_seq_setup_walk(iter);
+       ipv6_route_seq_setup_walk(iter, net);
        goto iter_table;
 }
 
        iter->skip = *pos;
 
        if (iter->tbl) {
-               ipv6_route_seq_setup_walk(iter);
+               ipv6_route_seq_setup_walk(iter, net);
                return ipv6_route_seq_next(seq, NULL, pos);
        } else {
                return NULL;
 static void ipv6_route_seq_stop(struct seq_file *seq, void *v)
        __releases(RCU_BH)
 {
+       struct net *net = seq_file_net(seq);
        struct ipv6_route_iter *iter = seq->private;
 
        if (ipv6_route_iter_active(iter))
-               fib6_walker_unlink(&iter->w);
+               fib6_walker_unlink(net, &iter->w);
 
        rcu_read_unlock_bh();
 }