]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Table export: ignoring invalid routes before marking them in export maps
authorMaria Matejka <mq@ucw.cz>
Mon, 10 Mar 2025 19:20:32 +0000 (20:20 +0100)
committerKaterina Kubecova <katerina.kubecova@nic.cz>
Wed, 23 Apr 2025 14:17:50 +0000 (16:17 +0200)
Fast subsequent updates on filtered routes made the code crash because
no flags were set while ignoring them. And if these routes flapped, the
squashed export update crashed on a consistency check.

We ignore them unconditionally so we don't have to mark them at all and
we can convert them to NULL even before export maps are touched.

nest/rt-table.c

index b604596a922fbe098f3fffabf660309973bc69d0..5b438aa7f564bcbb7b37bd700aed1200a6215940 100644 (file)
@@ -1165,24 +1165,6 @@ rt_notify_basic(struct channel *c, const rte *new, const rte *old)
 {
   const rte *trte = new ?: old;
 
-  /* Have we exported the old route? */
-  if (old && !bmap_test(&c->export_accepted_map, old->id))
-    old = NULL;
-
-  /* Ignore invalid routes */
-  if (!rte_is_valid(new))
-    new = NULL;
-
-  if (!rte_is_valid(old))
-    old = NULL;
-
-  if (!new && !old)
-  {
-    channel_rte_trace_out(D_ROUTES, c, trte, "idempotent withdraw (filtered on import)");
-    c->export_stats.withdraws_ignored++;
-    return;
-  }
-
   /* Have we exported the old route? */
   if (old)
   {
@@ -1598,6 +1580,18 @@ channel_notify_basic(void *_channel)
              rt_export_processed(&c->out_req, rpe->it.seq);
            }
 
+          /* Have we exported the old route? */
+          if (old && !bmap_test(&c->export_accepted_map, old->id))
+            old = NULL;
+
+         /* Ignore invalid routes */
+         if (!rte_is_valid(new))
+           new = NULL;
+
+         if (!rte_is_valid(old))
+           old = NULL;
+
+         /* Update status map flags for id-only updates */
          if (new && old && rte_same(new, old))
          {
            channel_rte_trace_out(D_ROUTES, c, new, "already exported");
@@ -1620,7 +1614,7 @@ channel_notify_basic(void *_channel)
          }
          else if (!new && !old)
          {
-           channel_rte_trace_out(D_ROUTES, c, u->update->new, "idempotent withdraw (squash)");
+           channel_rte_trace_out(D_ROUTES, c, u->update->new, "idempotent withdraw");
            c->export_stats.withdraws_ignored++;
          }
          else