diff options
Diffstat (limited to 'net/ipv6/ip6_fib.c')
-rw-r--r-- | net/ipv6/ip6_fib.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index f626ea2b304f..77e122f53ea6 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -319,12 +319,26 @@ static int fib6_dump_table(struct fib6_table *table, struct sk_buff *skb, | |||
319 | w->root = &table->tb6_root; | 319 | w->root = &table->tb6_root; |
320 | 320 | ||
321 | if (cb->args[4] == 0) { | 321 | if (cb->args[4] == 0) { |
322 | w->count = 0; | ||
323 | w->skip = 0; | ||
324 | |||
322 | read_lock_bh(&table->tb6_lock); | 325 | read_lock_bh(&table->tb6_lock); |
323 | res = fib6_walk(w); | 326 | res = fib6_walk(w); |
324 | read_unlock_bh(&table->tb6_lock); | 327 | read_unlock_bh(&table->tb6_lock); |
325 | if (res > 0) | 328 | if (res > 0) { |
326 | cb->args[4] = 1; | 329 | cb->args[4] = 1; |
330 | cb->args[5] = w->root->fn_sernum; | ||
331 | } | ||
327 | } else { | 332 | } else { |
333 | if (cb->args[5] != w->root->fn_sernum) { | ||
334 | /* Begin at the root if the tree changed */ | ||
335 | cb->args[5] = w->root->fn_sernum; | ||
336 | w->state = FWS_INIT; | ||
337 | w->node = w->root; | ||
338 | w->skip = w->count; | ||
339 | } else | ||
340 | w->skip = 0; | ||
341 | |||
328 | read_lock_bh(&table->tb6_lock); | 342 | read_lock_bh(&table->tb6_lock); |
329 | res = fib6_walk_continue(w); | 343 | res = fib6_walk_continue(w); |
330 | read_unlock_bh(&table->tb6_lock); | 344 | read_unlock_bh(&table->tb6_lock); |
@@ -1250,9 +1264,18 @@ static int fib6_walk_continue(struct fib6_walker_t *w) | |||
1250 | w->leaf = fn->leaf; | 1264 | w->leaf = fn->leaf; |
1251 | case FWS_C: | 1265 | case FWS_C: |
1252 | if (w->leaf && fn->fn_flags&RTN_RTINFO) { | 1266 | if (w->leaf && fn->fn_flags&RTN_RTINFO) { |
1253 | int err = w->func(w); | 1267 | int err; |
1268 | |||
1269 | if (w->count < w->skip) { | ||
1270 | w->count++; | ||
1271 | continue; | ||
1272 | } | ||
1273 | |||
1274 | err = w->func(w); | ||
1254 | if (err) | 1275 | if (err) |
1255 | return err; | 1276 | return err; |
1277 | |||
1278 | w->count++; | ||
1256 | continue; | 1279 | continue; |
1257 | } | 1280 | } |
1258 | w->state = FWS_U; | 1281 | w->state = FWS_U; |
@@ -1346,6 +1369,8 @@ static void fib6_clean_tree(struct net *net, struct fib6_node *root, | |||
1346 | c.w.root = root; | 1369 | c.w.root = root; |
1347 | c.w.func = fib6_clean_node; | 1370 | c.w.func = fib6_clean_node; |
1348 | c.w.prune = prune; | 1371 | c.w.prune = prune; |
1372 | c.w.count = 0; | ||
1373 | c.w.skip = 0; | ||
1349 | c.func = func; | 1374 | c.func = func; |
1350 | c.arg = arg; | 1375 | c.arg = arg; |
1351 | c.net = net; | 1376 | c.net = net; |