diff options
| author | Christian Franke <chris@opensourcerouting.org> | 2017-07-12 18:27:55 +0200 |
|---|---|---|
| committer | Christian Franke <chris@opensourcerouting.org> | 2017-07-12 18:27:55 +0200 |
| commit | 9fb47c0584ced64080c977ade8597de377d47b7f (patch) | |
| tree | 3b5c2a42de7ac98eb3b9afae688c1ef2829a5102 /lib/nexthop.c | |
| parent | 7215c4f0584c5bf2804890a3dc2d69697a05c49a (diff) | |
lib,zebra: Fix ALL_NEXTHOPS iterator
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
Diffstat (limited to 'lib/nexthop.c')
| -rw-r--r-- | lib/nexthop.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/lib/nexthop.c b/lib/nexthop.c index 948baca198..ef9ae800f6 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -242,3 +242,34 @@ nexthop2str (struct nexthop *nexthop, char *str, int size) return str; } + +/* + * Iteration step for ALL_NEXTHOPS macro: + * This is the tricky part. Check if `nexthop' has + * NEXTHOP_FLAG_RECURSIVE set. If yes, this implies that `nexthop' has + * at least one nexthop attached to `nexthop->resolved', which will be + * the next one. + * + * If NEXTHOP_FLAG_RECURSIVE is not set, `nexthop' will progress in its + * current chain. In case its current chain end is reached, it will move + * upwards in the recursion levels and progress there. Whenever a step + * forward in a chain is done, recursion will be checked again. + * In a nustshell, it's equivalent to a pre-traversal order assuming that + * left branch is 'resolved' and right branch is 'next': + * https://en.wikipedia.org/wiki/Tree_traversal#/media/File:Sorted_binary_tree_preorder.svg + */ +struct nexthop * +nexthop_next(struct nexthop *nexthop) +{ + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) + return nexthop->resolved; + + if (nexthop->next) + return nexthop->next; + + for (struct nexthop *par = nexthop->rparent; par; par = par->rparent) + if (par->next) + return par->next; + + return NULL; +} |
