From: Katerina Kubecova Date: Tue, 25 Feb 2025 11:46:06 +0000 (+0100) Subject: Table export: fixed inconsistency in export_rejected_map X-Git-Tag: v3.0.2~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=63c08fc653bcfcad742aa83c11f783d3b68c0f9a;p=thirdparty%2Fbird.git Table export: fixed inconsistency in export_rejected_map When updates arrived in such an order that the first one was rejected and the second one got accepted, the export_rejected_map flag mistakenly stayed set, leaking the route ID. In the RA_OPTIMAL channel mode, there are consistency checks that at most one route for a net has been accepted or rejected. After some time, the leaked ID and bit in export_rejected_map caused spurious crashes in asserts later in channel_notify_basic(). Thanks to NIX-CZ and Maiyun Zhang for reporting this. --- diff --git a/nest/rt-table.c b/nest/rt-table.c index 3ce2e2100..d1ffd4021 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)