mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-06-15 17:14:48 +00:00
lib,zebra: Fix ALL_NEXTHOPS iterator
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
This commit is contained in:
parent
7215c4f058
commit
9fb47c0584
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
33
zebra/rib.h
33
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
|
||||
|
Loading…
Reference in New Issue
Block a user