From: Donald Sharp Date: Thu, 5 Dec 2024 18:12:00 +0000 (-0500) Subject: bgpd: Fix evpn bestpath calculation when path is not established X-Git-Tag: docker/10.2.1~6^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=refs%2Fpull%2F17662%2Fhead;p=mirror%2Ffrr.git bgpd: Fix evpn bestpath calculation when path is not established If you have a bestpath list that looks something like this: 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: 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 (cherry picked from commit 9f88cb56dc0fe7a4ce864f672c6ca420fcd420c2) --- diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 3785d35954..0124b12cc3 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -2960,7 +2960,10 @@ 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 && + !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT) && + !peer_established(pi->peer->connection)))) { struct bgp_path_info *next = pi->next; if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) @@ -3054,6 +3057,30 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest, continue; } + if (first->peer && first->peer != bgp->peer_self && + !CHECK_FLAG(first->peer->sflags, PEER_STATUS_NSF_WAIT) && + !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;