]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Channel feeding request respects the subnet tries
authorMaria Matejka <mq@ucw.cz>
Wed, 4 Oct 2023 08:39:46 +0000 (10:39 +0200)
committerMaria Matejka <mq@ucw.cz>
Thu, 2 Nov 2023 13:37:27 +0000 (14:37 +0100)
nest/proto.c
nest/protocol.h

index 03f502f7c007093d0016169e2bb11fa1523efc24..9eebb1107cd6a6a2bd984cde41a8884b63a437bf 100644 (file)
@@ -357,6 +357,12 @@ channel_roa_in_changed(struct settle *se)
   channel_request_reload(c);
 }
 
+static void
+channel_roa_out_reload_done(struct channel_feeding_request *req)
+{
+  rfree(req->trie->lp);
+}
+
 static void
 channel_roa_out_changed(struct settle *se)
 {
@@ -365,25 +371,15 @@ channel_roa_out_changed(struct settle *se)
 
   CD(c, "Feeding triggered by RPKI change");
 
-  /* TODO feed by trie */
-
-  /* Refeed already pending */
-  if ((s->cfr[0].state == CFRS_PENDING) || (s->cfr[1].state == CFRS_PENDING))
-    return;
+  struct channel_feeding_request *cfr = lp_alloc(s->trie->lp, sizeof *cfr);
+  *cfr = (struct channel_feeding_request) {
+    .type = CFRT_AUXILIARY,
+    .trie = s->trie,
+    .done = channel_roa_out_reload_done,
+  };
+  channel_request_feeding(c, cfr);
 
-  /* First refeed inactive */
-  if (s->cfr[0].state == CFRS_INACTIVE)
-  {
-    s->cfr[0].type = CFRT_AUXILIARY;
-    channel_request_feeding(c, &s->cfr[0]);
-  }
-  else
-  {
-    /* Second refeed MUST be inactive */
-    ASSERT_DIE(s->cfr[1].state == CFRS_INACTIVE);
-    s->cfr[1].type = CFRT_AUXILIARY;
-    channel_request_feeding(c, &s->cfr[1]);
-  }
+  s->trie = f_new_trie(lp_new(c->proto->pool), 0);
 }
 
 static void
index 7d0041f5162d80fffe2d4036d020a96b19f398d2..227201dc83e715bd1285f0d9fc8cbf87b75180c4 100644 (file)
@@ -678,6 +678,7 @@ static inline void channel_close(struct channel *c) { channel_set_state(c, CS_ST
 struct channel_feeding_request {
   struct channel_feeding_request *next;                        /* Next in request chain */
   void (*done)(struct channel_feeding_request *);      /* Called when refeed finishes */
+  struct f_trie *trie;                                 /* Reload only matching nets */
   PACKED enum channel_feeding_request_type {
     CFRT_DIRECT = 1,                                   /* Refeed by export restart */
     CFRT_AUXILIARY,                                    /* Refeed by auxiliary request */
@@ -694,12 +695,29 @@ void channel_request_feeding(struct channel *c, struct channel_feeding_request *
 void channel_request_feeding_dynamic(struct channel *c, enum channel_feeding_request_type);
 
 static inline int channel_net_is_refeeding(struct channel *c, const net_addr *n)
-{ return (c->refeeding && c->refeed_trie && !trie_match_net(c->refeed_trie, n)); }
+{
+  /* Not refeeding if not refeeding at all */
+  if (!c->refeeding || !c->refeed_trie)
+    return 0;
+
+  /* Not refeeding if already refed */
+  if (trie_match_net(c->refeed_trie, n))
+    return 0;
+
+  /* Refeeding if matching any request */
+  for (struct channel_feeding_request *cfr = c->refeeding; cfr; cfr = cfr->next)
+    if (!cfr->trie || trie_match_net(cfr->trie, n))
+      return 1;
+
+  /* Not matching any request */
+  return 0;
+}
 static inline void channel_net_mark_refed(struct channel *c, const net_addr *n)
 {
   ASSERT_DIE(c->refeeding && c->refeed_trie);
   trie_add_prefix(c->refeed_trie, n, n->pxlen, n->pxlen);
 }
+
 void *channel_config_new(const struct channel_class *cc, const char *name, uint net_type, struct proto_config *proto);
 void *channel_config_get(const struct channel_class *cc, const char *name, uint net_type, struct proto_config *proto);
 int channel_reconfigure(struct channel *c, struct channel_config *cf);