]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Route flag REF_OBSOLETE
authorMaria Matejka <mq@ucw.cz>
Wed, 13 Mar 2024 12:46:16 +0000 (13:46 +0100)
committerMaria Matejka <mq@ucw.cz>
Sat, 6 Apr 2024 16:28:43 +0000 (18:28 +0200)
Marking routes obsolete when being removed from table, just to be sure.

lib/route.h
nest/rt-table.c

index 61f7f34280bf4a728272787a098285ba247271fa..37f0db3d432fc89251d2be7ab5ec7e32c11c4564 100644 (file)
@@ -26,11 +26,11 @@ struct rte_storage;
 
 #define RTE_IN_TABLE_WRITABLE \
   byte pflags;                         /* Protocol-specific flags; may change in-table (!) */ \
+  byte flags;                          /* Table-specific flags */ \
   u8 stale_cycle;                      /* Auxiliary value for route refresh; may change in-table (!) */ \
 
 typedef struct rte {
   RTE_IN_TABLE_WRITABLE;
-  byte flags;                          /* Table-specific flags */
   u8 generation;                       /* If this route import is based on other previously exported route,
                                           this value should be 1 + MAX(generation of the parent routes).
                                           Otherwise the route is independent and this value is zero. */
@@ -43,6 +43,7 @@ typedef struct rte {
 } rte;
 
 #define REF_FILTERED   2               /* Route is rejected by import filter */
+#define REF_OBSOLETE   16              /* Route is obsolete, pending propagation */
 #define REF_PENDING    32              /* Route has not propagated completely yet */
 
 /* Route is valid for propagation (may depend on other flags in the future), accepts NULL */
index 415aeee273b4887023fa78b3639c720d57fe5bbd..457e8ffb899996abe39d25cf1cfd2f8cb386bb4a 100644 (file)
@@ -516,7 +516,7 @@ rte_store(const rte *r, struct netindex *i, struct rtable_private *tab)
  * rte_free() deletes the given &rte from the routing table it's linked to.
  */
 
-void
+static void
 rte_free(struct rte_storage *e, struct rtable_private *tab)
 {
   struct netindex *i = RTE_GET_NETINDEX(&e->rte);
@@ -1120,6 +1120,9 @@ rte_export(struct rt_export_hook *hook, struct rt_pending_export *rpe)
   else
     hook->stats.withdraws_received++;
 
+  if (rpe->old)
+    ASSERT_DIE(rpe->old->flags & REF_OBSOLETE);
+
   if (hook->req->export_one)
     hook->req->export_one(hook->req, n, rpe);
   else if (hook->req->export_bulk)
@@ -1293,6 +1296,7 @@ rt_cleanup_export(struct lfjour *j, struct lfjour_item *i)
 
   if (rpe->old)
   {
+    ASSERT_DIE(rpe->old->flags & REF_OBSOLETE);
     hmap_clear(&tab->id_map, rpe->old->id);
     rte_free(SKIP_BACK(struct rte_storage, rte, rpe->old), tab);
   }
@@ -1528,6 +1532,10 @@ rte_recalculate(struct rtable_private *table, struct rt_import_hook *c, struct n
       return;
     }
 
+  /* Mark the old route as obsolete */
+  if (old)
+    SKIP_BACK(struct rte_storage, rte, old)->flags |= REF_OBSOLETE;
+
   /* If rejected by import limit, we need to pretend there is no route */
   if (req->preimport && (req->preimport(req, new, old) == 0))
   {
@@ -3404,7 +3412,10 @@ rt_next_hop_update_net(struct rtable_private *tab, struct netindex *ni, net *n)
 
     struct rte_storage *put;
     if (updates[i].new.attrs)
+    {
       put = updates[i].new_stored = rte_store(&updates[i].new, ni, tab);
+      updates[i].old->flags |= REF_OBSOLETE;
+    }
     else
       put = updates[i].old;