summaryrefslogtreecommitdiff
path: root/zebra/rib.h
diff options
context:
space:
mode:
authorßingen <bingen@voltanet.io>2017-06-27 12:49:49 +0200
committerßingen <bingen@voltanet.io>2017-06-28 21:32:18 +0200
commitf9e1b38e1a48b72cac7caaded16b9355c80d7899 (patch)
tree78ad561127d3cf9e3ba6d58972c21cc40a87d326 /zebra/rib.h
parent3d07d27345fe5832045632d292ac6cdfabbc75e0 (diff)
Allow for more than 1 NH recursion level
Before, only one level of recursive resolution was supported. Signed-off-by: ßingen <bingen@voltanet.io>
Diffstat (limited to 'zebra/rib.h')
-rw-r--r--zebra/rib.h38
1 files changed, 15 insertions, 23 deletions
diff --git a/zebra/rib.h b/zebra/rib.h
index 88f2bf39ab..e4e2c45486 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -197,32 +197,24 @@ typedef struct rib_dest_t_
* Iteration check: Check that the `nexthop' pointer is not NULL.
*
* Iteration step: This is the tricky part. Check if `nexthop' has
- * NEXTHOP_FLAG_RECURSIVE set. If yes, this implies that `nexthop' is in
- * the top level chain and has at least one nexthop attached to
- * `nexthop->resolved'. As we want to descend into `nexthop->resolved',
- * set `recursing' to 1 and set `nexthop' to `nexthop->resolved'.
- * `tnexthop' is left alone in that case so we can remember which nexthop
- * in the top level chain we are currently handling.
+ * NEXTHOP_FLAG_RECURSIVE set. If yes, this implies that `nexthop' has
+ * at least one nexthop attached to `nexthop->resolved'.
*
* If NEXTHOP_FLAG_RECURSIVE is not set, `nexthop' will progress in its
- * current chain. If we are recursing, `nexthop' will be set to
- * `nexthop->next' and `tnexthop' will be left alone. If we are not
- * recursing, both `tnexthop' and `nexthop' will be set to `nexthop->next'
- * as we are progressing in the top level chain.
- * If we encounter `nexthop->next == NULL', we will clear the `recursing'
- * flag as we arived either at the end of the resolved chain or at the end
- * of the top level chain. In both cases, we set `tnexthop' and `nexthop'
- * to `tnexthop->next', progressing to the next position in the top-level
- * chain and possibly to its end marked by NULL.
+ * current chain. In case its current chain end is reached, it will try
+ * to get up to the previous recursion level 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
*/
-#define ALL_NEXTHOPS_RO(head, nexthop, tnexthop, recursing) \
- (tnexthop) = (nexthop) = (head), (recursing) = 0; \
- (nexthop); \
- (nexthop) = CHECK_FLAG((nexthop)->flags, NEXTHOP_FLAG_RECURSIVE) \
- ? (((recursing) = 1), (nexthop)->resolved) \
- : ((nexthop)->next ? ((recursing) ? (nexthop)->next \
- : ((tnexthop) = (nexthop)->next)) \
- : (((recursing) = 0),((tnexthop) = (tnexthop)->next)))
+#define ALL_NEXTHOPS_RO(head, nexthop) \
+ (nexthop) = (head); \
+ (nexthop); \
+ (nexthop) = CHECK_FLAG((nexthop)->flags, NEXTHOP_FLAG_RECURSIVE) \
+ ? ((nexthop)->resolved) \
+ : ((nexthop)->next ? (nexthop)->next \
+ : ((nexthop)->rparent ? (nexthop)->rparent->next : NULL))
#if defined (HAVE_RTADV)
/* Structure which hold status of router advertisement. */