]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
BGP: fixed deterministic med crashes
authorMaria Matejka <mq@ucw.cz>
Tue, 7 Jan 2025 10:08:04 +0000 (11:08 +0100)
committerMaria Matejka <mq@ucw.cz>
Thu, 9 Jan 2025 09:08:27 +0000 (10:08 +0100)
There were several places of forgotten NULL checks.

Thanks to Alarig Le Lay <alarig@swordarmor.fr> for reporting:
https://trubka.network.cz/pipermail/bird-users/2024-December/017990.html

nest/rt-table.c
proto/bgp/attrs.c

index 05191d7437ebed5fe3b93c3c68f53ec0b0af4e36..fc6d0d4e04bcbdaf4251a757cddc5bc98db35e04 100644 (file)
@@ -2024,12 +2024,22 @@ rte_recalculate(struct rtable_private *table, struct rt_import_hook *c, struct n
        do_recalculate:
          /* Add the new route to the list right behind the old one */
          if (new_stored)
+         {
+           /* There is the same piece of code several lines farther. Needs refactoring.
+            * The old_stored check is needed because of the possible jump from deterministic med */
+           if (old_stored)
            {
              atomic_store_explicit(&new_stored->next, atomic_load_explicit(&old_stored->next, memory_order_relaxed), memory_order_release);
              atomic_store_explicit(&old_stored->next, new_stored, memory_order_release);
-
-             table->rt_count++;
            }
+           else
+           {
+             atomic_store_explicit(&new_stored->next, NULL, memory_order_release);
+             atomic_store_explicit(last_ptr, new_stored, memory_order_release);
+           }
+
+           table->rt_count++;
+         }
 
          /* Find a new optimal route (if there is any) */
          struct rte_storage * _Atomic *bp = &local_sentinel.next;
index 5dc06be51bcea74d68d4327ad9c60d127402db1d..db654234343e3af0eb63c11ee0926c0672e6b262 100644 (file)
@@ -2689,10 +2689,10 @@ bgp_rte_recalculate(struct rtable_private *table, net *net,
     struct rte_storage *new_stored, struct rte_storage *old_stored, struct rte_storage *old_best_stored)
 {
   struct rte_storage *key_stored = new_stored ? new_stored : old_stored;
-  const struct rte *new = &new_stored->rte,
-                  *old = &old_stored->rte,
-                  *old_best = &old_best_stored->rte,
-                  *key = &key_stored->rte;
+  const struct rte *new = RTE_OR_NULL(new_stored),
+                  *old = RTE_OR_NULL(old_stored),
+                  *old_best = RTE_OR_NULL(old_best_stored),
+                  *key = RTE_OR_NULL(key_stored);
 
   u32 lpref = rt_get_preference(key);
   u32 lasn = bgp_get_neighbor(key);