Skip to content

Commit 9c6ecd3

Browse files
idoschdavem330
authored andcommitted
ipv6: Only Replay routes of interest to new listeners
When a new listener is registered to the FIB notification chain it receives a dump of all the available routes in the system. Instead, make sure to only replay the IPv6 routes that are actually used in the data path and are of any interest to the new listener. This is done by iterating over all the routing tables in the given namespace, but from each traversed node only the first route ('leaf') is notified. Multipath routes are notified in a single notification instead of one for each nexthop. Add fib6_rt_dump_tmp() to do that. Later on in the patch set it will be renamed to fib6_rt_dump() instead of the existing one. Signed-off-by: Ido Schimmel <[email protected]> Reviewed-by: Jiri Pirko <[email protected]> Reviewed-by: David Ahern <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 0ee0f47 commit 9c6ecd3

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

net/ipv6/ip6_fib.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,21 @@ static int call_fib6_entry_notifier(struct notifier_block *nb,
370370
return call_fib6_notifier(nb, event_type, &info.info);
371371
}
372372

373+
static int call_fib6_multipath_entry_notifier(struct notifier_block *nb,
374+
enum fib_event_type event_type,
375+
struct fib6_info *rt,
376+
unsigned int nsiblings,
377+
struct netlink_ext_ack *extack)
378+
{
379+
struct fib6_entry_notifier_info info = {
380+
.info.extack = extack,
381+
.rt = rt,
382+
.nsiblings = nsiblings,
383+
};
384+
385+
return call_fib6_notifier(nb, event_type, &info.info);
386+
}
387+
373388
int call_fib6_entry_notifiers(struct net *net,
374389
enum fib_event_type event_type,
375390
struct fib6_info *rt,
@@ -414,16 +429,41 @@ static int fib6_rt_dump(struct fib6_info *rt, struct fib6_dump_arg *arg)
414429
rt, arg->extack);
415430
}
416431

432+
static int fib6_rt_dump_tmp(struct fib6_info *rt, struct fib6_dump_arg *arg)
433+
{
434+
enum fib_event_type fib_event = FIB_EVENT_ENTRY_REPLACE_TMP;
435+
int err;
436+
437+
if (!rt || rt == arg->net->ipv6.fib6_null_entry)
438+
return 0;
439+
440+
if (rt->fib6_nsiblings)
441+
err = call_fib6_multipath_entry_notifier(arg->nb, fib_event,
442+
rt,
443+
rt->fib6_nsiblings,
444+
arg->extack);
445+
else
446+
err = call_fib6_entry_notifier(arg->nb, fib_event, rt,
447+
arg->extack);
448+
449+
return err;
450+
}
451+
417452
static int fib6_node_dump(struct fib6_walker *w)
418453
{
419454
struct fib6_info *rt;
420455
int err = 0;
421456

457+
err = fib6_rt_dump_tmp(w->leaf, w->args);
458+
if (err)
459+
goto out;
460+
422461
for_each_fib6_walker_rt(w) {
423462
err = fib6_rt_dump(rt, w->args);
424463
if (err)
425464
break;
426465
}
466+
out:
427467
w->leaf = NULL;
428468
return err;
429469
}

0 commit comments

Comments
 (0)