mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-11 18:48:14 +00:00
Allow for more than 1 NH recursion level
Before, only one level of recursive resolution was supported. Signed-off-by: ßingen <bingen@voltanet.io>
This commit is contained in:
parent
3d07d27345
commit
f9e1b38e1a
@ -135,7 +135,7 @@ nexthop_add (struct nexthop **target, struct nexthop *nexthop)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
copy_nexthops (struct nexthop **tnh, struct nexthop *nh)
|
copy_nexthops (struct nexthop **tnh, struct nexthop *nh, struct nexthop *rparent)
|
||||||
{
|
{
|
||||||
struct nexthop *nexthop;
|
struct nexthop *nexthop;
|
||||||
struct nexthop *nh1;
|
struct nexthop *nh1;
|
||||||
@ -150,11 +150,12 @@ copy_nexthops (struct nexthop **tnh, struct nexthop *nh)
|
|||||||
memcpy(&(nexthop->src), &(nh->src), sizeof(union g_addr));
|
memcpy(&(nexthop->src), &(nh->src), sizeof(union g_addr));
|
||||||
if (nh->nh_label)
|
if (nh->nh_label)
|
||||||
nexthop_add_labels (nexthop, nh->nh_label_type,
|
nexthop_add_labels (nexthop, nh->nh_label_type,
|
||||||
nh->nh_label->num_labels, &nh->nh_label->label[0]);
|
nh->nh_label->num_labels, &nh->nh_label->label[0]);
|
||||||
|
nexthop->rparent = rparent;
|
||||||
nexthop_add(tnh, nexthop);
|
nexthop_add(tnh, nexthop);
|
||||||
|
|
||||||
if (CHECK_FLAG(nh1->flags, NEXTHOP_FLAG_RECURSIVE))
|
if (CHECK_FLAG(nh1->flags, NEXTHOP_FLAG_RECURSIVE))
|
||||||
copy_nexthops(&nexthop->resolved, nh1->resolved);
|
copy_nexthops(&nexthop->resolved, nh1->resolved, nexthop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,8 +81,10 @@ struct nexthop
|
|||||||
* If the nexthop struct needs to be resolved recursively,
|
* If the nexthop struct needs to be resolved recursively,
|
||||||
* NEXTHOP_FLAG_RECURSIVE will be set in flags and the nexthops
|
* NEXTHOP_FLAG_RECURSIVE will be set in flags and the nexthops
|
||||||
* obtained by recursive resolution will be added to `resolved'.
|
* obtained by recursive resolution will be added to `resolved'.
|
||||||
* Only one level of recursive resolution is currently supported. */
|
*/
|
||||||
struct nexthop *resolved;
|
struct nexthop *resolved;
|
||||||
|
/* Recursive parent */
|
||||||
|
struct nexthop *rparent;
|
||||||
|
|
||||||
/* Type of label(s), if any */
|
/* Type of label(s), if any */
|
||||||
enum lsp_types_t nh_label_type;
|
enum lsp_types_t nh_label_type;
|
||||||
@ -107,7 +109,7 @@ nh_resolve_via_default(int family)
|
|||||||
struct nexthop *nexthop_new (void);
|
struct nexthop *nexthop_new (void);
|
||||||
void nexthop_add (struct nexthop **target, struct nexthop *nexthop);
|
void nexthop_add (struct nexthop **target, struct nexthop *nexthop);
|
||||||
|
|
||||||
void copy_nexthops (struct nexthop **tnh, struct nexthop *nh);
|
void copy_nexthops (struct nexthop **tnh, struct nexthop *nh, struct nexthop *rparent);
|
||||||
void nexthop_free (struct nexthop *nexthop);
|
void nexthop_free (struct nexthop *nexthop);
|
||||||
void nexthops_free (struct nexthop *nexthop);
|
void nexthops_free (struct nexthop *nexthop);
|
||||||
|
|
||||||
|
@ -173,13 +173,12 @@ nexthop_chain_free(struct nexthop_chain *nc)
|
|||||||
static void
|
static void
|
||||||
nexthop_chain_verify_iter(struct nexthop_chain *nc)
|
nexthop_chain_verify_iter(struct nexthop_chain *nc)
|
||||||
{
|
{
|
||||||
struct nexthop *nh, *tnh;
|
struct nexthop *nh;
|
||||||
int recursing;
|
|
||||||
char *repr = NULL;
|
char *repr = NULL;
|
||||||
|
|
||||||
for (ALL_NEXTHOPS_RO(nc->head, nh, tnh, recursing))
|
for (ALL_NEXTHOPS_RO(nc->head, nh))
|
||||||
{
|
{
|
||||||
if (recursing)
|
if (nh->rparent)
|
||||||
str_appendf(&repr, " %p\n", nh);
|
str_appendf(&repr, " %p\n", nh);
|
||||||
else
|
else
|
||||||
str_appendf(&repr, "%p\n", nh);
|
str_appendf(&repr, "%p\n", nh);
|
||||||
|
38
zebra/rib.h
38
zebra/rib.h
@ -197,32 +197,24 @@ typedef struct rib_dest_t_
|
|||||||
* Iteration check: Check that the `nexthop' pointer is not NULL.
|
* Iteration check: Check that the `nexthop' pointer is not NULL.
|
||||||
*
|
*
|
||||||
* Iteration step: This is the tricky part. Check if `nexthop' has
|
* Iteration step: This is the tricky part. Check if `nexthop' has
|
||||||
* NEXTHOP_FLAG_RECURSIVE set. If yes, this implies that `nexthop' is in
|
* NEXTHOP_FLAG_RECURSIVE set. If yes, this implies that `nexthop' has
|
||||||
* the top level chain and has at least one nexthop attached to
|
* at least one nexthop attached to `nexthop->resolved'.
|
||||||
* `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.
|
|
||||||
*
|
*
|
||||||
* If NEXTHOP_FLAG_RECURSIVE is not set, `nexthop' will progress in its
|
* If NEXTHOP_FLAG_RECURSIVE is not set, `nexthop' will progress in its
|
||||||
* current chain. If we are recursing, `nexthop' will be set to
|
* current chain. In case its current chain end is reached, it will try
|
||||||
* `nexthop->next' and `tnexthop' will be left alone. If we are not
|
* to get up to the previous recursion level and progress there. Whenever
|
||||||
* recursing, both `tnexthop' and `nexthop' will be set to `nexthop->next'
|
* a step forward in a chain is done, recursion will be checked again.
|
||||||
* as we are progressing in the top level chain.
|
* In a nustshell, it's equivalent to a pre-traversal order assuming that
|
||||||
* If we encounter `nexthop->next == NULL', we will clear the `recursing'
|
* left branch is 'resolved' and right branch is 'next':
|
||||||
* flag as we arived either at the end of the resolved chain or at the end
|
* https://en.wikipedia.org/wiki/Tree_traversal#/media/File:Sorted_binary_tree_preorder.svg
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
#define ALL_NEXTHOPS_RO(head, nexthop, tnexthop, recursing) \
|
#define ALL_NEXTHOPS_RO(head, nexthop) \
|
||||||
(tnexthop) = (nexthop) = (head), (recursing) = 0; \
|
(nexthop) = (head); \
|
||||||
(nexthop); \
|
(nexthop); \
|
||||||
(nexthop) = CHECK_FLAG((nexthop)->flags, NEXTHOP_FLAG_RECURSIVE) \
|
(nexthop) = CHECK_FLAG((nexthop)->flags, NEXTHOP_FLAG_RECURSIVE) \
|
||||||
? (((recursing) = 1), (nexthop)->resolved) \
|
? ((nexthop)->resolved) \
|
||||||
: ((nexthop)->next ? ((recursing) ? (nexthop)->next \
|
: ((nexthop)->next ? (nexthop)->next \
|
||||||
: ((tnexthop) = (nexthop)->next)) \
|
: ((nexthop)->rparent ? (nexthop)->rparent->next : NULL))
|
||||||
: (((recursing) = 0),((tnexthop) = (tnexthop)->next)))
|
|
||||||
|
|
||||||
#if defined (HAVE_RTADV)
|
#if defined (HAVE_RTADV)
|
||||||
/* Structure which hold status of router advertisement. */
|
/* Structure which hold status of router advertisement. */
|
||||||
|
@ -1190,8 +1190,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
|
|||||||
{
|
{
|
||||||
int bytelen;
|
int bytelen;
|
||||||
struct sockaddr_nl snl;
|
struct sockaddr_nl snl;
|
||||||
struct nexthop *nexthop = NULL, *tnexthop;
|
struct nexthop *nexthop = NULL;
|
||||||
int recursing;
|
|
||||||
unsigned int nexthop_num;
|
unsigned int nexthop_num;
|
||||||
int discard;
|
int discard;
|
||||||
int family = PREFIX_FAMILY(p);
|
int family = PREFIX_FAMILY(p);
|
||||||
@ -1283,7 +1282,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
|
|||||||
if (discard)
|
if (discard)
|
||||||
{
|
{
|
||||||
if (cmd == RTM_NEWROUTE)
|
if (cmd == RTM_NEWROUTE)
|
||||||
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
|
||||||
{
|
{
|
||||||
/* We shouldn't encounter recursive nexthops on discard routes,
|
/* We shouldn't encounter recursive nexthops on discard routes,
|
||||||
* but it is probably better to handle that case correctly anyway.
|
* but it is probably better to handle that case correctly anyway.
|
||||||
@ -1297,7 +1296,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
|
|||||||
/* Count overall nexthops so we can decide whether to use singlepath
|
/* Count overall nexthops so we can decide whether to use singlepath
|
||||||
* or multipath case. */
|
* or multipath case. */
|
||||||
nexthop_num = 0;
|
nexthop_num = 0;
|
||||||
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
|
||||||
{
|
{
|
||||||
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
||||||
continue;
|
continue;
|
||||||
@ -1313,7 +1312,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
|
|||||||
if (nexthop_num == 1 || multipath_num == 1)
|
if (nexthop_num == 1 || multipath_num == 1)
|
||||||
{
|
{
|
||||||
nexthop_num = 0;
|
nexthop_num = 0;
|
||||||
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
|
||||||
{
|
{
|
||||||
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
||||||
{
|
{
|
||||||
@ -1354,7 +1353,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
|
|||||||
|| (cmd == RTM_DELROUTE
|
|| (cmd == RTM_DELROUTE
|
||||||
&& CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
|
&& CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
|
||||||
{
|
{
|
||||||
routedesc = recursing ? "recursive, 1 hop" : "single hop";
|
routedesc = nexthop->rparent ? "recursive, 1 hop" : "single hop";
|
||||||
|
|
||||||
_netlink_route_debug(cmd, p, nexthop, routedesc, family, zvrf);
|
_netlink_route_debug(cmd, p, nexthop, routedesc, family, zvrf);
|
||||||
_netlink_route_build_singlepath(routedesc, bytelen,
|
_netlink_route_build_singlepath(routedesc, bytelen,
|
||||||
@ -1384,7 +1383,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
|
|||||||
rtnh = RTA_DATA (rta);
|
rtnh = RTA_DATA (rta);
|
||||||
|
|
||||||
nexthop_num = 0;
|
nexthop_num = 0;
|
||||||
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
|
||||||
{
|
{
|
||||||
if (nexthop_num >= multipath_num)
|
if (nexthop_num >= multipath_num)
|
||||||
break;
|
break;
|
||||||
@ -1429,7 +1428,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
|
|||||||
|| (cmd == RTM_DELROUTE
|
|| (cmd == RTM_DELROUTE
|
||||||
&& CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
|
&& CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
|
||||||
{
|
{
|
||||||
routedesc = recursing ? "recursive, multihop" : "multihop";
|
routedesc = nexthop->rparent ? "recursive, multihop" : "multihop";
|
||||||
nexthop_num++;
|
nexthop_num++;
|
||||||
|
|
||||||
_netlink_route_debug(cmd, p, nexthop,
|
_netlink_route_debug(cmd, p, nexthop,
|
||||||
|
@ -80,8 +80,7 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct route_entry *re)
|
|||||||
struct sockaddr_mpls smpls;
|
struct sockaddr_mpls smpls;
|
||||||
#endif
|
#endif
|
||||||
union sockunion *smplsp = NULL;
|
union sockunion *smplsp = NULL;
|
||||||
struct nexthop *nexthop, *tnexthop;
|
struct nexthop *nexthop;
|
||||||
int recursing;
|
|
||||||
int nexthop_num = 0;
|
int nexthop_num = 0;
|
||||||
ifindex_t ifindex = 0;
|
ifindex_t ifindex = 0;
|
||||||
int gate = 0;
|
int gate = 0;
|
||||||
@ -106,7 +105,7 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct route_entry *re)
|
|||||||
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
|
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
|
||||||
|
|
||||||
/* Make gateway. */
|
/* Make gateway. */
|
||||||
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
|
||||||
{
|
{
|
||||||
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
||||||
continue;
|
continue;
|
||||||
@ -266,8 +265,7 @@ kernel_rtm_ipv6 (int cmd, struct prefix *p, struct route_entry *re)
|
|||||||
{
|
{
|
||||||
struct sockaddr_in6 *mask;
|
struct sockaddr_in6 *mask;
|
||||||
struct sockaddr_in6 sin_dest, sin_mask, sin_gate;
|
struct sockaddr_in6 sin_dest, sin_mask, sin_gate;
|
||||||
struct nexthop *nexthop, *tnexthop;
|
struct nexthop *nexthop;
|
||||||
int recursing;
|
|
||||||
int nexthop_num = 0;
|
int nexthop_num = 0;
|
||||||
ifindex_t ifindex = 0;
|
ifindex_t ifindex = 0;
|
||||||
int gate = 0;
|
int gate = 0;
|
||||||
@ -289,7 +287,7 @@ kernel_rtm_ipv6 (int cmd, struct prefix *p, struct route_entry *re)
|
|||||||
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
|
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
|
||||||
|
|
||||||
/* Make gateway. */
|
/* Make gateway. */
|
||||||
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
|
||||||
{
|
{
|
||||||
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
||||||
continue;
|
continue;
|
||||||
|
@ -233,8 +233,7 @@ static int
|
|||||||
netlink_route_info_fill (netlink_route_info_t *ri, int cmd,
|
netlink_route_info_fill (netlink_route_info_t *ri, int cmd,
|
||||||
rib_dest_t *dest, struct route_entry *re)
|
rib_dest_t *dest, struct route_entry *re)
|
||||||
{
|
{
|
||||||
struct nexthop *nexthop, *tnexthop;
|
struct nexthop *nexthop;
|
||||||
int recursing;
|
|
||||||
int discard;
|
int discard;
|
||||||
|
|
||||||
memset (ri, 0, sizeof (*ri));
|
memset (ri, 0, sizeof (*ri));
|
||||||
@ -286,7 +285,7 @@ netlink_route_info_fill (netlink_route_info_t *ri, int cmd,
|
|||||||
if (discard)
|
if (discard)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
|
||||||
{
|
{
|
||||||
if (ri->num_nhs >= multipath_num)
|
if (ri->num_nhs >= multipath_num)
|
||||||
break;
|
break;
|
||||||
@ -299,7 +298,7 @@ netlink_route_info_fill (netlink_route_info_t *ri, int cmd,
|
|||||||
|| (cmd == RTM_DELROUTE
|
|| (cmd == RTM_DELROUTE
|
||||||
&& CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
|
&& CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
|
||||||
{
|
{
|
||||||
netlink_route_info_add_nh (ri, nexthop, recursing);
|
netlink_route_info_add_nh (ri, nexthop, (nexthop->rparent ? 1 : 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,9 +209,10 @@ route_entry_copy_nexthops (struct route_entry *re, struct nexthop *nh)
|
|||||||
if (nh->nh_label)
|
if (nh->nh_label)
|
||||||
nexthop_add_labels (nexthop, nh->nh_label_type, nh->nh_label->num_labels,
|
nexthop_add_labels (nexthop, nh->nh_label_type, nh->nh_label->num_labels,
|
||||||
&nh->nh_label->label[0]);
|
&nh->nh_label->label[0]);
|
||||||
|
nexthop->rparent = NULL;
|
||||||
route_entry_nexthop_add(re, nexthop);
|
route_entry_nexthop_add(re, nexthop);
|
||||||
if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RECURSIVE))
|
if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RECURSIVE))
|
||||||
copy_nexthops(&nexthop->resolved, nh->resolved);
|
copy_nexthops(&nexthop->resolved, nh->resolved, nexthop);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete specified nexthop from the list. */
|
/* Delete specified nexthop from the list. */
|
||||||
@ -389,6 +390,7 @@ nexthop_set_resolved (afi_t afi, struct nexthop *newhop, struct nexthop *nexthop
|
|||||||
resolved_hop->ifindex = newhop->ifindex;
|
resolved_hop->ifindex = newhop->ifindex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resolved_hop->rparent = nexthop;
|
||||||
nexthop_add(&nexthop->resolved, resolved_hop);
|
nexthop_add(&nexthop->resolved, resolved_hop);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,8 +405,7 @@ nexthop_active (afi_t afi, struct route_entry *re, struct nexthop *nexthop, int
|
|||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct route_entry *match;
|
struct route_entry *match;
|
||||||
int resolved;
|
int resolved;
|
||||||
struct nexthop *newhop, *tnewhop;
|
struct nexthop *newhop;
|
||||||
int recursing = 0;
|
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
if ((nexthop->type == NEXTHOP_TYPE_IPV4) || nexthop->type == NEXTHOP_TYPE_IPV6)
|
if ((nexthop->type == NEXTHOP_TYPE_IPV4) || nexthop->type == NEXTHOP_TYPE_IPV6)
|
||||||
@ -528,7 +529,7 @@ nexthop_active (afi_t afi, struct route_entry *re, struct nexthop *nexthop, int
|
|||||||
else if (CHECK_FLAG (re->flags, ZEBRA_FLAG_INTERNAL))
|
else if (CHECK_FLAG (re->flags, ZEBRA_FLAG_INTERNAL))
|
||||||
{
|
{
|
||||||
resolved = 0;
|
resolved = 0;
|
||||||
for (newhop = match->nexthop; newhop; newhop = newhop->next)
|
for (ALL_NEXTHOPS_RO(match->nexthop, newhop))
|
||||||
if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
|
if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
|
||||||
&& ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
|
&& ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
|
||||||
{
|
{
|
||||||
@ -546,7 +547,7 @@ nexthop_active (afi_t afi, struct route_entry *re, struct nexthop *nexthop, int
|
|||||||
else if (re->type == ZEBRA_ROUTE_STATIC)
|
else if (re->type == ZEBRA_ROUTE_STATIC)
|
||||||
{
|
{
|
||||||
resolved = 0;
|
resolved = 0;
|
||||||
for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
|
for (ALL_NEXTHOPS_RO(match->nexthop, newhop))
|
||||||
if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
|
if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
|
||||||
{
|
{
|
||||||
if (set)
|
if (set)
|
||||||
@ -577,8 +578,7 @@ rib_match (afi_t afi, safi_t safi, vrf_id_t vrf_id,
|
|||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct route_entry *match;
|
struct route_entry *match;
|
||||||
struct nexthop *newhop, *tnewhop;
|
struct nexthop *newhop;
|
||||||
int recursing;
|
|
||||||
|
|
||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
table = zebra_vrf_table (afi, safi, vrf_id);
|
table = zebra_vrf_table (afi, safi, vrf_id);
|
||||||
@ -628,7 +628,7 @@ rib_match (afi_t afi, safi_t safi, vrf_id_t vrf_id,
|
|||||||
if (match->type != ZEBRA_ROUTE_CONNECT)
|
if (match->type != ZEBRA_ROUTE_CONNECT)
|
||||||
{
|
{
|
||||||
int found = 0;
|
int found = 0;
|
||||||
for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing))
|
for (ALL_NEXTHOPS_RO(match->nexthop, newhop))
|
||||||
if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
|
if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
|
||||||
{
|
{
|
||||||
found = 1;
|
found = 1;
|
||||||
@ -724,8 +724,7 @@ rib_lookup_ipv4 (struct prefix_ipv4 *p, vrf_id_t vrf_id)
|
|||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct route_entry *match;
|
struct route_entry *match;
|
||||||
struct nexthop *nexthop, *tnexthop;
|
struct nexthop *nexthop;
|
||||||
int recursing;
|
|
||||||
|
|
||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
||||||
@ -754,8 +753,8 @@ rib_lookup_ipv4 (struct prefix_ipv4 *p, vrf_id_t vrf_id)
|
|||||||
|
|
||||||
if (match->type == ZEBRA_ROUTE_CONNECT)
|
if (match->type == ZEBRA_ROUTE_CONNECT)
|
||||||
return match;
|
return match;
|
||||||
|
|
||||||
for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
|
for (ALL_NEXTHOPS_RO(match->nexthop, nexthop))
|
||||||
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
|
||||||
return match;
|
return match;
|
||||||
|
|
||||||
@ -781,8 +780,7 @@ rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate,
|
|||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct route_entry *match;
|
struct route_entry *match;
|
||||||
struct nexthop *nexthop, *tnexthop;
|
struct nexthop *nexthop;
|
||||||
int recursing;
|
|
||||||
int nexthops_active;
|
int nexthops_active;
|
||||||
|
|
||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
@ -818,7 +816,7 @@ rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate,
|
|||||||
|
|
||||||
/* Ok, we have a cood candidate, let's check it's nexthop list... */
|
/* Ok, we have a cood candidate, let's check it's nexthop list... */
|
||||||
nexthops_active = 0;
|
nexthops_active = 0;
|
||||||
for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing))
|
for (ALL_NEXTHOPS_RO(match->nexthop, nexthop))
|
||||||
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
|
||||||
{
|
{
|
||||||
nexthops_active = 1;
|
nexthops_active = 1;
|
||||||
@ -830,7 +828,7 @@ rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate,
|
|||||||
inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
|
inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
|
||||||
inet_ntop (AF_INET, &sockunion2ip(qgate), qgate_buf, INET_ADDRSTRLEN);
|
inet_ntop (AF_INET, &sockunion2ip(qgate), qgate_buf, INET_ADDRSTRLEN);
|
||||||
zlog_debug ("%s: qgate == %s, %s == %s", __func__,
|
zlog_debug ("%s: qgate == %s, %s == %s", __func__,
|
||||||
qgate_buf, recursing ? "rgate" : "gate", gate_buf);
|
qgate_buf, nexthop->rparent ? "rgate" : "gate", gate_buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1025,13 +1023,12 @@ nexthop_active_update (struct route_node *rn, struct route_entry *re, int set)
|
|||||||
int
|
int
|
||||||
zebra_rib_labeled_unicast (struct route_entry *re)
|
zebra_rib_labeled_unicast (struct route_entry *re)
|
||||||
{
|
{
|
||||||
struct nexthop *nexthop = NULL, *tnexthop;
|
struct nexthop *nexthop = NULL;
|
||||||
int recursing;
|
|
||||||
|
|
||||||
if (re->type != ZEBRA_ROUTE_BGP)
|
if (re->type != ZEBRA_ROUTE_BGP)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
|
||||||
if (!nexthop->nh_label || !nexthop->nh_label->num_labels)
|
if (!nexthop->nh_label || !nexthop->nh_label->num_labels)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1045,9 +1042,8 @@ int
|
|||||||
rib_install_kernel (struct route_node *rn, struct route_entry *re, struct route_entry *old)
|
rib_install_kernel (struct route_node *rn, struct route_entry *re, struct route_entry *old)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct nexthop *nexthop, *tnexthop;
|
struct nexthop *nexthop;
|
||||||
rib_table_info_t *info = srcdest_rnode_table_info(rn);
|
rib_table_info_t *info = srcdest_rnode_table_info(rn);
|
||||||
int recursing;
|
|
||||||
struct prefix *p, *src_p;
|
struct prefix *p, *src_p;
|
||||||
struct zebra_vrf *zvrf = vrf_info_lookup (re->vrf_id);
|
struct zebra_vrf *zvrf = vrf_info_lookup (re->vrf_id);
|
||||||
|
|
||||||
@ -1055,7 +1051,7 @@ rib_install_kernel (struct route_node *rn, struct route_entry *re, struct route_
|
|||||||
|
|
||||||
if (info->safi != SAFI_UNICAST)
|
if (info->safi != SAFI_UNICAST)
|
||||||
{
|
{
|
||||||
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
|
||||||
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
|
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1071,7 +1067,7 @@ rib_install_kernel (struct route_node *rn, struct route_entry *re, struct route_
|
|||||||
/* If install succeeds, update FIB flag for nexthops. */
|
/* If install succeeds, update FIB flag for nexthops. */
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
|
||||||
{
|
{
|
||||||
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
||||||
continue;
|
continue;
|
||||||
@ -1091,9 +1087,8 @@ int
|
|||||||
rib_uninstall_kernel (struct route_node *rn, struct route_entry *re)
|
rib_uninstall_kernel (struct route_node *rn, struct route_entry *re)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct nexthop *nexthop, *tnexthop;
|
struct nexthop *nexthop;
|
||||||
rib_table_info_t *info = srcdest_rnode_table_info(rn);
|
rib_table_info_t *info = srcdest_rnode_table_info(rn);
|
||||||
int recursing;
|
|
||||||
struct prefix *p, *src_p;
|
struct prefix *p, *src_p;
|
||||||
struct zebra_vrf *zvrf = vrf_info_lookup (re->vrf_id);
|
struct zebra_vrf *zvrf = vrf_info_lookup (re->vrf_id);
|
||||||
|
|
||||||
@ -1101,7 +1096,7 @@ rib_uninstall_kernel (struct route_node *rn, struct route_entry *re)
|
|||||||
|
|
||||||
if (info->safi != SAFI_UNICAST)
|
if (info->safi != SAFI_UNICAST)
|
||||||
{
|
{
|
||||||
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
|
||||||
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
|
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1114,7 +1109,7 @@ rib_uninstall_kernel (struct route_node *rn, struct route_entry *re)
|
|||||||
ret = kernel_route_rib (p, src_p, re, NULL);
|
ret = kernel_route_rib (p, src_p, re, NULL);
|
||||||
zvrf->removals++;
|
zvrf->removals++;
|
||||||
|
|
||||||
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
|
||||||
UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
|
UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -1284,8 +1279,7 @@ static void
|
|||||||
rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
|
rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
|
||||||
struct route_entry *old, struct route_entry *new)
|
struct route_entry *old, struct route_entry *new)
|
||||||
{
|
{
|
||||||
struct nexthop *nexthop = NULL, *tnexthop;
|
struct nexthop *nexthop = NULL;
|
||||||
int recursing;
|
|
||||||
int nh_active = 0;
|
int nh_active = 0;
|
||||||
int installed = 1;
|
int installed = 1;
|
||||||
|
|
||||||
@ -1403,7 +1397,7 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
|
|||||||
{
|
{
|
||||||
int in_fib = 0;
|
int in_fib = 0;
|
||||||
|
|
||||||
for (ALL_NEXTHOPS_RO(new->nexthop, nexthop, tnexthop, recursing))
|
for (ALL_NEXTHOPS_RO(new->nexthop, nexthop))
|
||||||
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
|
||||||
{
|
{
|
||||||
in_fib = 1;
|
in_fib = 1;
|
||||||
@ -1634,13 +1628,11 @@ rib_process (struct route_node *rn)
|
|||||||
/* Redistribute SELECTED entry */
|
/* Redistribute SELECTED entry */
|
||||||
if (old_selected != new_selected || selected_changed)
|
if (old_selected != new_selected || selected_changed)
|
||||||
{
|
{
|
||||||
struct nexthop *nexthop, *tnexthop;
|
struct nexthop *nexthop;
|
||||||
int recursing;
|
|
||||||
|
|
||||||
/* Check if we have a FIB route for the destination, otherwise,
|
/* Check if we have a FIB route for the destination, otherwise,
|
||||||
* don't redistribute it */
|
* don't redistribute it */
|
||||||
for (ALL_NEXTHOPS_RO(new_fib ? new_fib->nexthop : NULL, nexthop,
|
for (ALL_NEXTHOPS_RO(new_fib ? new_fib->nexthop : NULL, nexthop))
|
||||||
tnexthop, recursing))
|
|
||||||
{
|
{
|
||||||
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
|
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
|
||||||
{
|
{
|
||||||
@ -2141,8 +2133,7 @@ void _route_entry_dump (const char * func,
|
|||||||
bool is_srcdst = src_p && src_p->prefixlen;
|
bool is_srcdst = src_p && src_p->prefixlen;
|
||||||
char straddr[PREFIX_STRLEN];
|
char straddr[PREFIX_STRLEN];
|
||||||
char srcaddr[PREFIX_STRLEN];
|
char srcaddr[PREFIX_STRLEN];
|
||||||
struct nexthop *nexthop, *tnexthop;
|
struct nexthop *nexthop;
|
||||||
int recursing;
|
|
||||||
|
|
||||||
zlog_debug ("%s: dumping RE entry %p for %s%s%s vrf %u", func, (const void *)re,
|
zlog_debug ("%s: dumping RE entry %p for %s%s%s vrf %u", func, (const void *)re,
|
||||||
prefix2str(pp, straddr, sizeof(straddr)),
|
prefix2str(pp, straddr, sizeof(straddr)),
|
||||||
@ -2177,14 +2168,14 @@ void _route_entry_dump (const char * func,
|
|||||||
re->nexthop_active_num
|
re->nexthop_active_num
|
||||||
);
|
);
|
||||||
|
|
||||||
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
|
||||||
{
|
{
|
||||||
inet_ntop (p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
|
inet_ntop (p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
|
||||||
zlog_debug
|
zlog_debug
|
||||||
(
|
(
|
||||||
"%s: %s %s with flags %s%s%s",
|
"%s: %s %s with flags %s%s%s",
|
||||||
func,
|
func,
|
||||||
(recursing ? " NH" : "NH"),
|
(nexthop->rparent ? " NH" : "NH"),
|
||||||
straddr,
|
straddr,
|
||||||
(CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
|
(CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""),
|
||||||
(CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
|
(CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""),
|
||||||
@ -2391,8 +2382,7 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
|
|||||||
struct route_entry *re;
|
struct route_entry *re;
|
||||||
struct route_entry *fib = NULL;
|
struct route_entry *fib = NULL;
|
||||||
struct route_entry *same = NULL;
|
struct route_entry *same = NULL;
|
||||||
struct nexthop *nexthop, *tnexthop;
|
struct nexthop *nexthop;
|
||||||
int recursing;
|
|
||||||
char buf2[INET6_ADDRSTRLEN];
|
char buf2[INET6_ADDRSTRLEN];
|
||||||
|
|
||||||
assert(!src_p || afi == AFI_IP6);
|
assert(!src_p || afi == AFI_IP6);
|
||||||
@ -2463,7 +2453,7 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
|
|||||||
same = re;
|
same = re;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
|
||||||
if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
|
if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
|
||||||
IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
|
IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate))
|
||||||
{
|
{
|
||||||
|
@ -420,12 +420,11 @@ zebra_rnh_eval_import_check_entry (vrf_id_t vrfid, int family, int force,
|
|||||||
struct zserv *client;
|
struct zserv *client;
|
||||||
char bufn[INET6_ADDRSTRLEN];
|
char bufn[INET6_ADDRSTRLEN];
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct nexthop *nexthop, *tnexthop;
|
struct nexthop *nexthop;
|
||||||
int recursing;
|
|
||||||
|
|
||||||
if (re && (rnh->state == NULL))
|
if (re && (rnh->state == NULL))
|
||||||
{
|
{
|
||||||
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
|
||||||
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
|
||||||
{
|
{
|
||||||
state_changed = 1;
|
state_changed = 1;
|
||||||
|
@ -648,8 +648,7 @@ static void
|
|||||||
vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
|
vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
|
||||||
{
|
{
|
||||||
struct route_entry *re;
|
struct route_entry *re;
|
||||||
struct nexthop *nexthop, *tnexthop;
|
struct nexthop *nexthop;
|
||||||
int recursing;
|
|
||||||
char buf[SRCDEST2STR_BUFFER];
|
char buf[SRCDEST2STR_BUFFER];
|
||||||
struct zebra_vrf *zvrf;
|
struct zebra_vrf *zvrf;
|
||||||
|
|
||||||
@ -720,13 +719,13 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
|
|||||||
vty_out (vty, " ago%s", VTY_NEWLINE);
|
vty_out (vty, " ago%s", VTY_NEWLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
|
||||||
{
|
{
|
||||||
char addrstr[32];
|
char addrstr[32];
|
||||||
|
|
||||||
vty_out (vty, " %c%s",
|
vty_out (vty, " %c%s",
|
||||||
CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ',
|
CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ',
|
||||||
recursing ? " " : "");
|
nexthop->rparent ? " " : "");
|
||||||
|
|
||||||
switch (nexthop->type)
|
switch (nexthop->type)
|
||||||
{
|
{
|
||||||
@ -806,8 +805,7 @@ static void
|
|||||||
vty_show_ip_route (struct vty *vty, struct route_node *rn, struct route_entry *re,
|
vty_show_ip_route (struct vty *vty, struct route_node *rn, struct route_entry *re,
|
||||||
json_object *json)
|
json_object *json)
|
||||||
{
|
{
|
||||||
struct nexthop *nexthop, *tnexthop;
|
struct nexthop *nexthop;
|
||||||
int recursing;
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
char buf[SRCDEST2STR_BUFFER];
|
char buf[SRCDEST2STR_BUFFER];
|
||||||
json_object *json_nexthops = NULL;
|
json_object *json_nexthops = NULL;
|
||||||
@ -868,7 +866,7 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct route_entry *r
|
|||||||
json_object_string_add(json_route, "uptime", buf);
|
json_object_string_add(json_route, "uptime", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
|
||||||
{
|
{
|
||||||
json_nexthop = json_object_new_object();
|
json_nexthop = json_object_new_object();
|
||||||
|
|
||||||
@ -962,7 +960,7 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct route_entry *r
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Nexthop information. */
|
/* Nexthop information. */
|
||||||
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop))
|
||||||
{
|
{
|
||||||
if (nexthop == re->nexthop)
|
if (nexthop == re->nexthop)
|
||||||
{
|
{
|
||||||
@ -985,9 +983,9 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct route_entry *r
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
vty_out (vty, " %c%*c",
|
vty_out (vty, " %c%*c",
|
||||||
CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
|
CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
|
||||||
? '*' : ' ',
|
? '*' : ' ',
|
||||||
len - 3 + (2 * recursing), ' ');
|
len - 3 + (2 * (nexthop->rparent ? 1 : 0)), ' ');
|
||||||
|
|
||||||
switch (nexthop->type)
|
switch (nexthop->type)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user