]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
WIP partial export consistency 281-mq-checker
authorMaria Matejka <mq@ucw.cz>
Thu, 21 Aug 2025 13:20:16 +0000 (15:20 +0200)
committerMaria Matejka <mq@ucw.cz>
Thu, 21 Aug 2025 13:20:16 +0000 (15:20 +0200)
nest/protocol.h
nest/rt-table.c

index 3199f9fa494bd43702bccc3f9dce5833528c06d6..8e4f6e291fd428d81c8357550b164ffaa60289b9 100644 (file)
@@ -625,8 +625,6 @@ struct channel {
   struct bmap imported_map;            /* Which nets were touched by our import */
   struct bmap export_accepted_map;     /* Keeps track which routes were really exported */
   struct bmap export_rejected_map;     /* Keeps track which routes were rejected by export filter */
-  event export_consistency_event;      /* Clears the export_log and checks the consistency
-                                          of export_rejected_map and export_accepted_map */
   struct channel_export_log *export_log;/* Keeps track what happened since last export_consistency_event */
 
   struct limit rx_limit;               /* Receive limit (for in_keep & RIK_REJECTED) */
index 780fbd906748123f602caecb2cde1b0b6f73c6d0..751989a2353d29661d8aa23dab30e09584e72cd0 100644 (file)
@@ -1097,6 +1097,69 @@ channel_rte_assert_dump(struct channel *c)
   }
 }
 
+static inline bool
+channel_check_export_consistency(struct channel *c)
+{
+  bool seen = 0;
+  if (!c->export_log || c->export_log->block_id < 20)
+    return 0;
+
+  struct rt_export_feeder cref = {
+    .name = tmp_sprintf("%s-consistency", c->out_req.name),
+    .trace_routes = c->out_req.trace_routes,
+  };
+
+  struct rt_exporter *rex = atomic_load_explicit(&c->out_req.feeder.exporter, memory_order_relaxed);
+  rt_feeder_subscribe(rex, &cref);
+
+  struct bmap seen, unseen;
+  bmap_init(&seen, c->proto->pool, 8);
+  bmap_init(&unseen, c->proto->pool, 8);
+
+  u32 failed_id = 0;
+
+  RT_FEED_WALK(&c->export_consistency_feeder, f)
+  {
+    for (uint i=0; i<f->count_routes; i++)
+    {
+      bool found =
+       bmap_test(&c->export_accepted_map, &f->block[i].id) ||
+       bmap_test(&c->export_rejected_map, &f->block[i].id);
+
+      if (found)
+       if (!bmap_test(&unseen, f->block[i].id) && !bmap_test(&seen, f->block[i].id))
+       {
+         bmap_set(&seen, f->block[i].id);
+         continue;
+       }
+         goto fail;
+       else
+      else
+       if (bmap_test(&seen, f->block[i].id))
+         goto fail;
+       else
+         bmap_set(&unseen, f->block[i].id);
+    }
+  }
+
+  for (uint max = MAX(
+       MAX(bmap_max(&seen), bmap_max(&unseen)), 
+       MAX(bmap_max(&c->export_accepted_map), bmap_max(&c->export_rejected_map))
+       ), i = 0; i < max; i++)
+    if (bmap_test(&c->export_accepted_map, &f->block[i].id
+
+cleanup:
+  bmap_free(&seen);
+  bmap_free(&unseen);
+  rt_feeder_unsubscribe(rex, &cref);
+  return 0;
+
+fail:
+  channel_rte_assert_dump(c);
+  bug("%s: Consistency check failed, duplicate route id %d in table",
+      c->out_req.name, f->block[i].id);
+}
+
 static inline void
 channel_rte_assert_rejected(struct channel *c, const rte *e, bool expected)
 {