Skip to content

Commit

Permalink
bgpd: Fix evpn bestpath calculation when path is not established
Browse files Browse the repository at this point in the history
If you have a bestpath list that looks something like this:

<local evpn mac route>
<learned from peer out swp60>
<learned from peer out swp57>

And a network event happens that causes the peer out swp60
to not be in an established state, yet we still have the
path_info for the destination for swp60, bestpath
will currently end up with this order:

<learned from peer out swp60>
<local evpn mac route>
<learned from peer out swp57>

This causes the local evpn mac route to be deleted in zebra( Wrong! ).

This is happening because swp60 is skipped in bestpath calculation and
not considered to be a path yet it stays at the front of the list.

Modify bestpath calculation such that when pulling the unsorted_list
together to pull path info's into that list when they are also
not in a established state.

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
  • Loading branch information
donaldsharp committed Dec 5, 2024
1 parent a43b11f commit 26715a0
Showing 1 changed file with 24 additions and 1 deletion.
25 changes: 24 additions & 1 deletion bgpd/bgp_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -3007,7 +3007,8 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,

old_select = NULL;
pi = bgp_dest_get_bgp_path_info(dest);
while (pi && CHECK_FLAG(pi->flags, BGP_PATH_UNSORTED)) {
while (pi && (CHECK_FLAG(pi->flags, BGP_PATH_UNSORTED) ||
(pi->peer != bgp->peer_self && !peer_established(pi->peer->connection)))) {
struct bgp_path_info *next = pi->next;

if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
Expand Down Expand Up @@ -3101,6 +3102,28 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
continue;
}

if (first->peer != bgp->peer_self && !peer_established(first->peer->connection)) {
if (debug)
zlog_debug("%s: %pBD(%s) pi %p from %s is not in established state",
__func__, dest, bgp->name_pretty, first,
first->peer->host);

/*
* Peer is not in established state we cannot sort this
* item yet. Let's wait, so hold this one to the side
*/
if (unsorted_holddown) {
first->next = unsorted_holddown;
unsorted_holddown->prev = first;
unsorted_holddown = first;
} else
unsorted_holddown = first;

UNSET_FLAG(first->flags, BGP_PATH_UNSORTED);

continue;
}

bgp_path_info_unset_flag(dest, first, BGP_PATH_DMED_CHECK);

worse = NULL;
Expand Down

0 comments on commit 26715a0

Please sign in to comment.