From: Maria Matejka Date: Fri, 14 Nov 2025 19:11:59 +0000 (+0100) Subject: Channel: Fix race condition of a new feed with an update in the table X-Git-Tag: v3.2.0~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e6c699d29dd7d82f887cf38f59c36ee268e6293b;p=thirdparty%2Fbird.git Channel: Fix race condition of a new feed with an update in the table In case an update arrived while another thread feeding anew, there was a race condition causing the old route to be counted against the export limit despite never reached. In long run, this caused limit counter underflow and a hard assertion failure. --- diff --git a/nest/rt-table.c b/nest/rt-table.c index 8cb052bf5..9141ddc6c 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -1463,6 +1463,9 @@ channel_notify_any(void *_channel) if (old) { + /* There are more old routes but these we should have + * never seen these newer old routes because we haven't + * seen the appropriate journal items */ EXPORT_FLAG_EXPECT(c, oo, accepted, 0); EXPORT_FLAG_EXPECT(c, oo, rejected, 0); oo->src = NULL; @@ -1471,6 +1474,15 @@ channel_notify_any(void *_channel) old = oo; } + /* Check whether the old route was actually seen because this may + * an initial feed. */ + bool oacc = old && bmap_test(&c->export_accepted_map, old->id); + bool orej = old && bmap_test(&c->export_rejected_map, old->id); + + /* Not seen */ + if (!oacc && !orej) + old = NULL; + /* Invalid routes become withdraws */ if (!rte_is_valid(new)) new = NULL;