summaryrefslogtreecommitdiff
path: root/net/ipv6/ip6_fib.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ip6_fib.c')
-rw-r--r--net/ipv6/ip6_fib.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 05ffa54fcf21..5550a8113a6d 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -1771,6 +1771,7 @@ struct ipv6_route_iter {
struct fib6_walker_t w;
loff_t skip;
struct fib6_table *tbl;
+ __u32 sernum;
};
static int ipv6_route_seq_show(struct seq_file *seq, void *v)
@@ -1823,6 +1824,7 @@ static void ipv6_route_seq_setup_walk(struct ipv6_route_iter *iter)
iter->w.state = FWS_INIT;
iter->w.node = iter->w.root;
iter->w.args = iter;
+ iter->sernum = iter->w.root->fn_sernum;
INIT_LIST_HEAD(&iter->w.lh);
fib6_walker_link(&iter->w);
}
@@ -1848,6 +1850,17 @@ static struct fib6_table *ipv6_route_seq_next_table(struct fib6_table *tbl,
return hlist_entry_safe(node, struct fib6_table, tb6_hlist);
}
+static void ipv6_route_check_sernum(struct ipv6_route_iter *iter)
+{
+ if (iter->sernum != iter->w.root->fn_sernum) {
+ iter->sernum = iter->w.root->fn_sernum;
+ iter->w.state = FWS_INIT;
+ iter->w.node = iter->w.root;
+ WARN_ON(iter->w.skip);
+ iter->w.skip = iter->w.count;
+ }
+}
+
static void *ipv6_route_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
int r;
@@ -1865,6 +1878,7 @@ static void *ipv6_route_seq_next(struct seq_file *seq, void *v, loff_t *pos)
}
iter_table:
+ ipv6_route_check_sernum(iter);
read_lock(&iter->tbl->tb6_lock);
r = fib6_walk_continue(&iter->w);
read_unlock(&iter->tbl->tb6_lock);