]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: When calling bgp_process, prevent infinite loop 17641/head
authorDonald Sharp <sharpd@nvidia.com>
Thu, 12 Dec 2024 20:08:35 +0000 (15:08 -0500)
committerDonald Sharp <sharpd@nvidia.com>
Thu, 12 Dec 2024 20:08:35 +0000 (15:08 -0500)
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>
bgpd/bgp_fsm.c
bgpd/bgp_route.c

index cadef399742387c39745151c4306e5c13c132ad0..6ad8a2e8de70a6d6ae4238c861fea2e0ac144587 100644 (file)
@@ -662,7 +662,7 @@ static void bgp_llgr_stale_timer_expire(struct event *thread)
 static void bgp_set_llgr_stale(struct peer *peer, afi_t afi, safi_t safi)
 {
        struct bgp_dest *dest;
-       struct bgp_path_info *pi;
+       struct bgp_path_info *pi, *next;
        struct bgp_table *table;
        struct attr attr;
 
@@ -677,8 +677,8 @@ static void bgp_set_llgr_stale(struct peer *peer, afi_t afi, safi_t safi)
 
                        for (rm = bgp_table_top(table); rm;
                             rm = bgp_route_next(rm))
-                               for (pi = bgp_dest_get_bgp_path_info(rm); pi;
-                                    pi = pi->next) {
+                               for (pi = bgp_dest_get_bgp_path_info(rm);
+                                    (pi != NULL) && (next = pi->next, 1); pi = next) {
                                        if (pi->peer != peer)
                                                continue;
 
@@ -709,8 +709,8 @@ static void bgp_set_llgr_stale(struct peer *peer, afi_t afi, safi_t safi)
        } else {
                for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
                     dest = bgp_route_next(dest))
-                       for (pi = bgp_dest_get_bgp_path_info(dest); pi;
-                            pi = pi->next) {
+                       for (pi = bgp_dest_get_bgp_path_info(dest);
+                            (pi != NULL) && (next = pi->next, 1); pi = next) {
                                if (pi->peer != peer)
                                        continue;
 
index 55368e9ebcc9f3c467add0f9613aaf2622f9150b..c123c232307c766b5acfbf6f0fec71bf8c2ceac1 100644 (file)
@@ -7410,7 +7410,7 @@ static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
 {
        struct bgp_table *table;
        struct bgp_dest *dest;
-       struct bgp_path_info *pi;
+       struct bgp_path_info *pi, *next;
 
        /* Do not install the aggregate route if BGP is in the
         * process of termination.
@@ -7421,7 +7421,8 @@ static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
 
        table = bgp->rib[afi][safi];
        for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
-               for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
+               for (pi = bgp_dest_get_bgp_path_info(dest); (pi != NULL) && (next = pi->next, 1);
+                    pi = next) {
                        if (pi->peer == bgp->peer_self
                            && ((pi->type == ZEBRA_ROUTE_BGP
                                 && pi->sub_type == BGP_ROUTE_STATIC)
@@ -7921,7 +7922,7 @@ void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
        struct bgp_table *table = bgp->rib[afi][safi];
        const struct prefix *dest_p;
        struct bgp_dest *dest, *top;
-       struct bgp_path_info *pi;
+       struct bgp_path_info *pi, *next;
 
        /* We've found a different MED we must revert any suppressed routes. */
        top = bgp_node_get(table, p);
@@ -7931,7 +7932,8 @@ void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
                if (dest_p->prefixlen <= p->prefixlen)
                        continue;
 
-               for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
+               for (pi = bgp_dest_get_bgp_path_info(dest); (pi != NULL) && (next = pi->next, 1);
+                    pi = next) {
                        if (BGP_PATH_HOLDDOWN(pi))
                                continue;
                        if (pi->sub_type == BGP_ROUTE_AGGREGATE)
@@ -8006,7 +8008,7 @@ bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
        struct community *community = NULL;
        struct ecommunity *ecommunity = NULL;
        struct lcommunity *lcommunity = NULL;
-       struct bgp_path_info *pi;
+       struct bgp_path_info *pi, *next;
        uint8_t atomic_aggregate = 0;
 
        /* If the bgp instance is being deleted or self peer is deleted
@@ -8056,7 +8058,8 @@ bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
                if (!bgp_check_advertise(bgp, dest, safi))
                        continue;
 
-               for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
+               for (pi = bgp_dest_get_bgp_path_info(dest); (pi != NULL) && (next = pi->next, 1);
+                    pi = next) {
                        if (BGP_PATH_HOLDDOWN(pi))
                                continue;
 
@@ -8213,7 +8216,7 @@ void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
        struct bgp_table *table;
        struct bgp_dest *top;
        struct bgp_dest *dest;
-       struct bgp_path_info *pi;
+       struct bgp_path_info *pi, *next;
 
        table = bgp->rib[afi][safi];
 
@@ -8226,7 +8229,8 @@ void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
                if (dest_p->prefixlen <= p->prefixlen)
                        continue;
 
-               for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
+               for (pi = bgp_dest_get_bgp_path_info(dest); (pi != NULL) && (next = pi->next, 1);
+                    pi = next) {
                        if (BGP_PATH_HOLDDOWN(pi))
                                continue;