summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Baldwin <carl@ecbaldwin.net>2021-12-29 14:32:33 -0700
committerCarl Baldwin <carl@ecbaldwin.net>2022-04-26 09:38:37 -0600
commit067ea16598a444b1ecfda5012f96acb038ba041e (patch)
treeb14c73b9f1352e34420e9c2ae44db28f6d5f2aa0
parentd45a846e5ca313e5ab132ef57c495cc0407b50d9 (diff)
bgpd: ensure that the node gets unlocked in all cases
The logic to unlock dest if iteration completed without iterating the entire node was flawed. Specifically, if iteration terminated due to `gr_deferred == 0` then the node would not get unlocked. This change takes into account the fact that dest will be NULL only in the case when the entire table was iterated and all nodes were already unlocked. In any other case, it needs to be unlocked. Signed-off-by: Carl Baldwin <carl@ecbaldwin.net>
-rw-r--r--bgpd/bgp_route.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 7e2cb5c70c..df844a4992 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -3171,7 +3171,8 @@ int bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
/* Process the route list */
for (dest = bgp_table_top(bgp->rib[afi][safi]);
- dest && bgp->gr_info[afi][safi].gr_deferred != 0;
+ dest && bgp->gr_info[afi][safi].gr_deferred != 0 &&
+ cnt < BGP_MAX_BEST_ROUTE_SELECT;
dest = bgp_route_next(dest)) {
if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
continue;
@@ -3180,10 +3181,13 @@ int bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
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;
- }
+ }
+ /* If iteration stopped before the entire table was traversed then the
+ * node needs to be unlocked.
+ */
+ if (dest) {
+ bgp_dest_unlock_node(dest);
+ dest = NULL;
}
/* Send EOR message when all routes are processed */