From cdd8f17ed93b447ec5a92b3e183767b0dcd519b2 Mon Sep 17 00:00:00 2001 From: bisdhdh Date: Wed, 23 Oct 2019 03:19:42 +0530 Subject: [PATCH] bgpd: Fix for BGP core when connected routes are redistriubuted and GR is enabled. When GR with deferral is enabled and connected routes are distributed then in one race condition route node gets added in to both deferred queue and work queue. If deferred queue gets processed first then it ends up delete only flag while leaving the entry in the work queue as it is. When a new update comes for the same rotue node next time from peer then it hits assert. Assert check is added to ensure we dont add to work queue again while it is already present. So,Check before adding in to deferred queue if it is already present in work queue and bail if so. --- bgpd/bgp_fsm.c | 1 - bgpd/bgp_route.c | 9 +++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 0dbbaf0f3a51..3daafb556d7d 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -2227,7 +2227,6 @@ int bgp_gr_lookup_n_update_all_peer(struct bgp *bgp, for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - peer_old_state = PEER_INVALID; if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) zlog_debug( diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 63ee6d926dcc..44566d6be654 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -313,6 +313,15 @@ static int bgp_node_set_defer_flag(struct bgp_node *rn, bool delete) if (CHECK_FLAG(rn->flags, BGP_NODE_SELECT_DEFER) && (delete == false)) return 0; + if (CHECK_FLAG(rn->flags, BGP_NODE_PROCESS_SCHEDULED)) { + if (BGP_DEBUG(update, UPDATE_OUT)) { + prefix2str(&rn->p, buf, PREFIX2STR_BUFFER); + zlog_debug("Route %s is in workqueue and being processed, not deferred.", + buf); + } + return 0; + } + table = bgp_node_table(rn); if (table) { bgp = table->bgp;