aboutsummaryrefslogtreecommitdiffstats
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.c29
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;