Commit 4e6a1b50ef for frr
commit 4e6a1b50ef26d73edd296d7999c32231bb320083
Author: Justin Iurman <justin.iurman@6wind.com>
Date: Fri Oct 30 22:18:12 2026 +0100
zebra: only drop the routes of the closing client from the early queue
When a client goes away, rib_score_proto() first purges its routes still
in the early route queue. The check meant to keep the routes of the
other clients only keeps a route whose type and instance both differ
from the closing client's. Any other queued route is freed and never
processed: the routes of the other daemons with the same instance (0 for
most of them), kernel and connected routes, and the routes of the other
instances of the same protocol.
Both adds and deletes are lost silently: a route is missing, or a stale
one stays in the RIB and in the kernel. For instance, a daemon going
away while bgpd routes are still in the early queue loses some of them.
It also happens every time a zserv_client_close hook queues a route
change of another type, since the purge runs right after the hooks.
Keep a queued route if either its type or its instance differs.
Fixes: e53fa582bc ("zebra: Fix removal of routes on MetaQ when client goes down")
Signed-off-by: Justin Iurman <justin.iurman@6wind.com>
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index b0044bef94..de586dd228 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -3953,7 +3953,7 @@ static void early_route_meta_queue_free(struct meta_queue *mq, struct list *l,
continue;
if (proto != ZEBRA_ROUTE_ALL &&
- (proto != ere->re->type && instance != ere->re->instance))
+ (proto != ere->re->type || instance != ere->re->instance))
continue;
early_route_memory_free(ere);