Skip to content

Commit 6103bf8

Browse files
committed
bgpd: When calling bgp_process, prevent infinite loop
If we have this construct: for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) { ... bgp_process(); } This can induce an infinite loop. This happens because bgp_process will move the unsorted items to the top of the list for handling, as such it is necessary to hold the next pointer to the side to actually look at each possible bgp_path_info. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
1 parent 1c1d7f8 commit 6103bf8

File tree

2 files changed

+17
-13
lines changed

2 files changed

+17
-13
lines changed

bgpd/bgp_fsm.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ static void bgp_llgr_stale_timer_expire(struct event *thread)
663663
static void bgp_set_llgr_stale(struct peer *peer, afi_t afi, safi_t safi)
664664
{
665665
struct bgp_dest *dest;
666-
struct bgp_path_info *pi;
666+
struct bgp_path_info *pi, *next;
667667
struct bgp_table *table;
668668
struct attr attr;
669669

@@ -678,8 +678,8 @@ static void bgp_set_llgr_stale(struct peer *peer, afi_t afi, safi_t safi)
678678

679679
for (rm = bgp_table_top(table); rm;
680680
rm = bgp_route_next(rm))
681-
for (pi = bgp_dest_get_bgp_path_info(rm); pi;
682-
pi = pi->next) {
681+
for (pi = bgp_dest_get_bgp_path_info(rm);
682+
(pi != NULL) && (next = pi->next, 1); pi = next) {
683683
if (pi->peer != peer)
684684
continue;
685685

@@ -711,8 +711,8 @@ static void bgp_set_llgr_stale(struct peer *peer, afi_t afi, safi_t safi)
711711
} else {
712712
for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
713713
dest = bgp_route_next(dest))
714-
for (pi = bgp_dest_get_bgp_path_info(dest); pi;
715-
pi = pi->next) {
714+
for (pi = bgp_dest_get_bgp_path_info(dest);
715+
(pi != NULL) && (next = pi->next, 1); pi = next) {
716716
if (pi->peer != peer)
717717
continue;
718718

bgpd/bgp_route.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7730,7 +7730,7 @@ static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
77307730
{
77317731
struct bgp_table *table;
77327732
struct bgp_dest *dest;
7733-
struct bgp_path_info *pi;
7733+
struct bgp_path_info *pi, *next;
77347734

77357735
/* Do not install the aggregate route if BGP is in the
77367736
* process of termination.
@@ -7741,7 +7741,8 @@ static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
77417741

77427742
table = bgp->rib[afi][safi];
77437743
for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
7744-
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7744+
for (pi = bgp_dest_get_bgp_path_info(dest); (pi != NULL) && (next = pi->next, 1);
7745+
pi = next) {
77457746
if (pi->peer == bgp->peer_self
77467747
&& ((pi->type == ZEBRA_ROUTE_BGP
77477748
&& pi->sub_type == BGP_ROUTE_STATIC)
@@ -8246,7 +8247,7 @@ void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
82468247
struct bgp_table *table = bgp->rib[afi][safi];
82478248
const struct prefix *dest_p;
82488249
struct bgp_dest *dest, *top;
8249-
struct bgp_path_info *pi;
8250+
struct bgp_path_info *pi, *next;
82508251

82518252
/* We've found a different MED we must revert any suppressed routes. */
82528253
top = bgp_node_get(table, p);
@@ -8256,7 +8257,8 @@ void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
82568257
if (dest_p->prefixlen <= p->prefixlen)
82578258
continue;
82588259

8259-
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
8260+
for (pi = bgp_dest_get_bgp_path_info(dest); (pi != NULL) && (next = pi->next, 1);
8261+
pi = next) {
82608262
if (BGP_PATH_HOLDDOWN(pi))
82618263
continue;
82628264
if (pi->sub_type == BGP_ROUTE_AGGREGATE)
@@ -8331,7 +8333,7 @@ bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
83318333
struct community *community = NULL;
83328334
struct ecommunity *ecommunity = NULL;
83338335
struct lcommunity *lcommunity = NULL;
8334-
struct bgp_path_info *pi;
8336+
struct bgp_path_info *pi, *next;
83358337
uint8_t atomic_aggregate = 0;
83368338

83378339
/* If the bgp instance is being deleted or self peer is deleted
@@ -8381,7 +8383,8 @@ bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
83818383
if (!bgp_check_advertise(bgp, dest, safi))
83828384
continue;
83838385

8384-
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
8386+
for (pi = bgp_dest_get_bgp_path_info(dest); (pi != NULL) && (next = pi->next, 1);
8387+
pi = next) {
83858388
if (BGP_PATH_HOLDDOWN(pi))
83868389
continue;
83878390

@@ -8539,7 +8542,7 @@ void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
85398542
struct bgp_table *table;
85408543
struct bgp_dest *top;
85418544
struct bgp_dest *dest;
8542-
struct bgp_path_info *pi;
8545+
struct bgp_path_info *pi, *next;
85438546

85448547
table = bgp->rib[afi][safi];
85458548

@@ -8552,7 +8555,8 @@ void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
85528555
if (dest_p->prefixlen <= p->prefixlen)
85538556
continue;
85548557

8555-
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
8558+
for (pi = bgp_dest_get_bgp_path_info(dest); (pi != NULL) && (next = pi->next, 1);
8559+
pi = next) {
85568560
if (BGP_PATH_HOLDDOWN(pi))
85578561
continue;
85588562

0 commit comments

Comments
 (0)