]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Incorporate withdrawals to the trie
authorIgor Putovny <igor.putovny@nic.cz>
Fri, 24 Jan 2025 16:10:19 +0000 (17:10 +0100)
committerIgor Putovny <igor.putovny@nic.cz>
Fri, 24 Jan 2025 16:10:19 +0000 (17:10 +0100)
proto/aggregator/aggregator.c

index 0caa98b5e4d7b9d98e447503405f0ba0c814ef19..fc073aa145ba06e8de9b57522687b9a7558348d8 100644 (file)
@@ -974,6 +974,62 @@ trie_receive_update(struct aggregator_proto *p, struct aggregator_route *old, st
   print_prefixes(p->root, new_uptr->n.type);
 }
 
+static void
+trie_receive_withdraw(struct aggregator_proto *p, struct aggregator_route *old)
+{
+  assert(p != NULL);
+  assert(old != NULL);
+
+  log("before update");
+  dump_trie(p->root);
+
+  union net_addr_union *uptr = (net_addr_union *)old->rte.net->n.addr;
+  struct trie_node *updated_node = NULL;
+
+  if (NET_IP4 == uptr->n.type)
+  {
+    struct net_addr_ip4 *addr = &uptr->ip4;
+    updated_node = trie_remove_prefix_ip4(p->root, addr);
+  }
+  else if (NET_IP6 == uptr->n.type)
+  {
+    struct net_addr_ip6 *addr = &uptr->ip6;
+    updated_node = trie_remove_prefix_ip6(p->root, addr);
+  }
+
+  assert(updated_node != NULL);
+  dump_trie(p->root);
+
+  struct trie_node *node = updated_node;
+
+  while (1)
+  {
+    if (IN_FIB == node->status)
+      break;
+
+    node = node->parent;
+  }
+
+  log("deaggregate");
+  deaggregate(node);
+  dump_trie(p->root);
+
+  log("second pass");
+  second_pass(node);
+  dump_trie(p->root);
+
+  log("merge buckets above");
+  struct trie_node *highest_node = merge_buckets_above(node);
+  dump_trie(p->root);
+  assert(highest_node != NULL);
+
+  log("third pass");
+  third_pass(p, highest_node);
+  dump_trie(p->root);
+
+  print_prefixes(p->root, uptr->n.type);
+}
+
 static void
 dump_trie_helper(const struct trie_node *node, struct net_addr_ip4 *addr, struct buffer *buf)
 {
@@ -2056,6 +2112,7 @@ aggregator_rt_notify(struct proto *P, struct channel *src_ch, net *net, rte *new
       else if (old && !new)
       {
         log("rt notify: withdraw");
+        trie_receive_withdraw(p, old_route);
       }
     }
   }