From 35ff820a3b92aece3d54dc2783b19f3a6f2bcbad Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Wed, 13 Mar 2024 13:46:16 +0100 Subject: [PATCH] Route flag REF_OBSOLETE Marking routes obsolete when being removed from table, just to be sure. --- lib/route.h | 3 ++- nest/rt-table.c | 13 ++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/route.h b/lib/route.h index 07ef898f..ff19416d 100644 --- a/lib/route.h +++ b/lib/route.h @@ -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 */ diff --git a/nest/rt-table.c b/nest/rt-table.c index b70911ea..d374bb0b 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -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); @@ -1117,6 +1117,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) @@ -1290,6 +1293,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); } @@ -1525,6 +1529,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)) { @@ -3401,7 +3409,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;