From: Christian Franke Date: Wed, 12 Jul 2017 16:27:55 +0000 (+0200) Subject: lib,zebra: Fix ALL_NEXTHOPS iterator X-Git-Tag: reindent-master-before~8^2~5 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=9fb47c0;p=matthieu%2Ffrr.git lib,zebra: Fix ALL_NEXTHOPS iterator Signed-off-by: Christian Franke --- 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; +} diff --git a/lib/nexthop.h b/lib/nexthop.h index f48c41dc55..4d7f32f6f0 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -93,6 +93,17 @@ struct nexthop struct nexthop_label *nh_label; }; +/* The following for loop allows to iterate over the nexthop + * structure of routes. + * + * head: The pointer to the first nexthop in the chain. + * + * nexthop: The pointer to the current nexthop, either in the + * top-level chain or in a resolved chain. + */ +#define ALL_NEXTHOPS(head, nexthop) \ + (nexthop) = (head); (nexthop); (nexthop) = nexthop_next(nexthop) + extern int zebra_rnh_ip_default_route; extern int zebra_rnh_ipv6_default_route; @@ -121,4 +132,5 @@ extern int nexthop_same_no_recurse (struct nexthop *next1, struct nexthop *next2 extern int nexthop_labels_match (struct nexthop *nh1, struct nexthop *nh2); extern const char * nexthop2str (struct nexthop *nexthop, char *str, int size); +extern struct nexthop *nexthop_next(struct nexthop *nexthop); #endif /*_LIB_NEXTHOP_H */ diff --git a/zebra/rib.h b/zebra/rib.h index 7a1b1485e9..999266241a 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -178,39 +178,6 @@ typedef struct rib_dest_t_ #define RNODE_FOREACH_RE_SAFE(rn, re, next) \ RE_DEST_FOREACH_ROUTE_SAFE (rib_dest_from_rnode (rn), re, next) -/* The following for loop allows to iterate over the nexthop - * structure of routes. - * - * head: The pointer to the first nexthop in the chain. - * - * nexthop: The pointer to the current nexthop, either in the - * top-level chain or in a resolved chain. - * - * Initialization: Set `nexthop' to the head of the top-level chain. - * - * 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' 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 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(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. */ struct rtadv