diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index c0b6acc2d0..8a237e329e 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -371,14 +371,12 @@ static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete) */ if (set_flag && table) { if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) { + if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) + bgp->gr_info[afi][safi].gr_deferred++; SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER); - if (dest->rt_node == NULL) - dest->rt_node = listnode_add( - bgp->gr_info[afi][safi].route_list, - dest); if (BGP_DEBUG(update, UPDATE_OUT)) - zlog_debug("DEFER route %pBD, dest %p, node %p", - dest, dest, dest->rt_node); + zlog_debug("DEFER route %pBD, dest %p", dest, + dest); return 0; } } @@ -2920,37 +2918,39 @@ int bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi) struct bgp_dest *dest; int cnt = 0; struct afi_safi_info *thread_info; - struct listnode *node = NULL, *nnode = NULL; - if (bgp->gr_info[afi][safi].t_route_select) + if (bgp->gr_info[afi][safi].t_route_select) { + struct thread *t = bgp->gr_info[afi][safi].t_route_select; + + thread_info = THREAD_ARG(t); + XFREE(MTYPE_TMP, thread_info); BGP_TIMER_OFF(bgp->gr_info[afi][safi].t_route_select); + } if (BGP_DEBUG(update, UPDATE_OUT)) { zlog_debug("%s: processing route for %s : cnt %d", __func__, get_afi_safi_str(afi, safi, false), - listcount(bgp->gr_info[afi][safi].route_list)); + bgp->gr_info[afi][safi].gr_deferred); } /* Process the route list */ - node = listhead(bgp->gr_info[afi][safi].route_list); - while (node) { - dest = listgetdata(node); - nnode = node->next; - list_delete_node(bgp->gr_info[afi][safi].route_list, node); - dest->rt_node = NULL; + for (dest = bgp_table_top(bgp->rib[afi][safi]); dest; + dest = bgp_route_next(dest)) { + if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) + continue; - if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) { - UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER); - bgp_process_main_one(bgp, dest, afi, safi); - cnt++; - if (cnt >= BGP_MAX_BEST_ROUTE_SELECT) - break; + UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER); + bgp->gr_info[afi][safi].gr_deferred--; + bgp_process_main_one(bgp, dest, afi, safi); + cnt++; + if (cnt >= BGP_MAX_BEST_ROUTE_SELECT) { + bgp_dest_unlock_node(dest); + break; } - node = nnode; } /* Send EOR message when all routes are processed */ - if (list_isempty(bgp->gr_info[afi][safi].route_list)) { + if (bgp->gr_info[afi][safi].gr_deferred) { bgp_send_delayed_eor(bgp); /* Send route processing complete message to RIB */ bgp_zebra_update(afi, safi, bgp->vrf_id, @@ -3287,13 +3287,7 @@ void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi, if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) { UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER); bgp = pi->peer->bgp; - if ((dest->rt_node) - && (bgp->gr_info[afi][safi].route_list)) { - list_delete_node(bgp->gr_info[afi][safi] - .route_list, - dest->rt_node); - dest->rt_node = NULL; - } + bgp->gr_info[afi][safi].gr_deferred--; } } } diff --git a/bgpd/bgp_table.c b/bgpd/bgp_table.c index 70e226b01b..022a6413e2 100644 --- a/bgpd/bgp_table.c +++ b/bgpd/bgp_table.c @@ -154,13 +154,8 @@ void bgp_delete_listnode(struct bgp_node *node) if (bgp && rn && rn->lock == 1) { /* Delete the route from the selection pending list */ - if ((node->rt_node) - && (bgp->gr_info[afi][safi].route_list)) { - list_delete_node( - bgp->gr_info[afi][safi].route_list, - node->rt_node); - node->rt_node = NULL; - } + bgp->gr_info[afi][safi].gr_deferred--; + UNSET_FLAG(node->flags, BGP_NODE_SELECT_DEFER); } } } diff --git a/bgpd/bgp_table.h b/bgpd/bgp_table.h index 9dd27628ce..4e9abf863d 100644 --- a/bgpd/bgp_table.h +++ b/bgpd/bgp_table.h @@ -102,8 +102,7 @@ struct bgp_node { #define BGP_NODE_LABEL_CHANGED (1 << 2) #define BGP_NODE_REGISTERED_FOR_LABEL (1 << 3) #define BGP_NODE_SELECT_DEFER (1 << 4) - /* list node pointer */ - struct listnode *rt_node; + struct bgp_addpath_node_data tx_addpath; enum bgp_path_selection_reason reason; diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index cf16378de1..0095a1cab0 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3022,7 +3022,7 @@ static struct bgp *bgp_create(as_t *as, const char *name, bgp->gr_info[afi][safi].eor_received = 0; bgp->gr_info[afi][safi].t_select_deferral = NULL; bgp->gr_info[afi][safi].t_route_select = NULL; - bgp->gr_info[afi][safi].route_list = list_new(); + bgp->gr_info[afi][safi].gr_deferred = 0; } bgp->v_update_delay = bm->v_update_delay; @@ -3394,14 +3394,21 @@ int bgp_delete(struct bgp *bgp) /* Delete the graceful restart info */ FOREACH_AFI_SAFI (afi, safi) { + struct thread *t; + gr_info = &bgp->gr_info[afi][safi]; if (!gr_info) continue; BGP_TIMER_OFF(gr_info->t_select_deferral); + + t = gr_info->t_route_select; + if (t) { + void *info = THREAD_ARG(t); + + XFREE(MTYPE_TMP, info); + } BGP_TIMER_OFF(gr_info->t_route_select); - if (gr_info->route_list) - list_delete(&gr_info->route_list); } if (BGP_DEBUG(zebra, ZEBRA)) { diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 74828e91df..480a3ad129 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -265,8 +265,8 @@ struct graceful_restart_info { uint32_t eor_received; /* Deferral Timer */ struct thread *t_select_deferral; - /* Route list */ - struct list *route_list; + /* Routes Deferred */ + uint32_t gr_deferred; /* Best route select */ struct thread *t_route_select; /* AFI, SAFI enabled */