From: Katerina Kubecova Date: Tue, 25 Feb 2025 11:46:06 +0000 (+0100) Subject: rt-table: fixed rt_notify_basic - old route is now cleared in case it was previously... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=69f7bd87565f5116028eef1a599b2dd8133d110c;p=thirdparty%2Fbird.git rt-table: fixed rt_notify_basic - old route is now cleared in case it was previously rejected. The problem manifested in RA_OPTIMAL channel mode. In this mode, we need only one route of a net to be in accepted table or to be in rejected table, but not in both. When there was a route in accepted map and we were addind another route of the same net, we added the new route, removed the old route and everything was ok. But when the first route was in rejected map, we just added the new route. That caused inconsistency - there were two routes of the same net in the maps (in accepted and rejected or both in rejected). This was causing a crashes in assert in channel_notify_basic. --- diff --git a/nest/rt-table.c b/nest/rt-table.c index a2082e620..07600d9fb 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -1197,8 +1197,18 @@ rt_notify_basic(struct channel *c, const rte *new, const rte *old) } /* Have we exported the old route? */ - if (old && !bmap_test(&c->export_accepted_map, old->id)) - old = NULL; + if (old) + /* If the old route exists, it is either in rejected or in accepted map. + * If it is in rejcted map, we clear it right now, if it is in accepted map, + * we get rid of it in do_rt_notify. */ + if (bmap_test(&c->export_rejected_map, old->id)) + { + ASSERT_DIE(!bmap_test(&c->export_accepted_map, old->id)); + bmap_clear(&c->export_rejected_map, old->id); + old = NULL; + } + else + ASSERT_DIE(bmap_test(&c->export_accepted_map, old->id)); /* Withdraw to withdraw. */ if (!np && !old)