]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Route feed marks only the relevant pending exports as done
authorMaria Matejka <mq@ucw.cz>
Fri, 31 Mar 2023 08:46:17 +0000 (10:46 +0200)
committerMaria Matejka <mq@ucw.cz>
Tue, 4 Apr 2023 15:00:58 +0000 (17:00 +0200)
nest/proto.c
nest/rt-show.c
nest/rt-table.c
nest/rt.h
proto/bgp/attrs.c
proto/bgp/bgp.h

index bdb905c98b1cdd808b9bdd6ad2d894b9b43d9209..e02e232d2564b2c816677c192be7aea3aff7cec7 100644 (file)
@@ -319,7 +319,7 @@ channel_export_one_roa(struct rt_export_request *req, const net_addr *net UNUSED
   /* TODO: use the information about what roa has changed */
   settle_kick(&s->settle, s->c->proto->loop);
 
-  rpe_mark_seen_all(req->hook, first, NULL);
+  rpe_mark_seen_all(req->hook, first, NULL, NULL);
 }
 
 static void
index 40202ef636bf203c474998594c979cce2890fc23..a5c7dc8f347dbd2cc0c83a2914778151fc841149 100644 (file)
@@ -211,7 +211,8 @@ rt_show_net(struct rt_show_data *d, const net_addr *n, const rte **feed, uint co
 
 static void
 rt_show_net_export_bulk(struct rt_export_request *req, const net_addr *n,
-    struct rt_pending_export *rpe UNUSED, const rte **feed, uint count)
+    struct rt_pending_export *first UNUSED, struct rt_pending_export *last UNUSED,
+    const rte **feed, uint count)
 {
   struct rt_show_data *d = SKIP_BACK(struct rt_show_data, req, req);
   return rt_show_net(d, n, feed, count);
index d52131c3c6a2951ce6aace07b78945d7f14aeb1d..8323080212d8cff80e41844277865fd581795552 100644 (file)
@@ -920,7 +920,8 @@ channel_rpe_mark_seen(struct rt_export_request *req, struct rt_pending_export *r
 }
 
 void
-rt_notify_accepted(struct rt_export_request *req, const net_addr *n, struct rt_pending_export *first,
+rt_notify_accepted(struct rt_export_request *req, const net_addr *n,
+    struct rt_pending_export *first, struct rt_pending_export *last,
     const rte **feed, uint count)
 {
   struct channel *c = SKIP_BACK(struct channel, out_req, req);
@@ -975,6 +976,8 @@ done:
        old_best = &rpe->old->rte;
       }
     }
+    if (rpe == last)
+      break;
   }
 
   /* Nothing to export */
@@ -1047,7 +1050,8 @@ rt_export_merged(struct channel *c, const rte **feed, uint count, linpool *pool,
 }
 
 void
-rt_notify_merged(struct rt_export_request *req, const net_addr *n, struct rt_pending_export *first,
+rt_notify_merged(struct rt_export_request *req, const net_addr *n,
+    struct rt_pending_export *first, struct rt_pending_export *last,
     const rte **feed, uint count)
 {
   struct channel *c = SKIP_BACK(struct channel, out_req, req);
@@ -1084,6 +1088,8 @@ rt_notify_merged(struct rt_export_request *req, const net_addr *n, struct rt_pen
        old_best = &rpe->old->rte;
       }
     }
+    if (rpe == last)
+      break;
   }
 
   /* Prepare new merged route */
@@ -1140,7 +1146,9 @@ rt_notify_any(struct rt_export_request *req, const net_addr *net, struct rt_pend
 }
 
 void
-rt_feed_any(struct rt_export_request *req, const net_addr *net, struct rt_pending_export *rpe UNUSED, const rte **feed, uint count)
+rt_feed_any(struct rt_export_request *req, const net_addr *net,
+    struct rt_pending_export *first, struct rt_pending_export *last,
+    const rte **feed, uint count)
 {
   struct channel *c = SKIP_BACK(struct channel, out_req, req);
 
@@ -1150,6 +1158,13 @@ rt_feed_any(struct rt_export_request *req, const net_addr *net, struct rt_pendin
       rte n0 = *feed[i];
       rt_notify_basic(c, net, &n0, NULL);
     }
+
+  RPE_WALK(first, rpe, NULL)
+  {
+    channel_rpe_mark_seen(req, rpe);
+    if (rpe == last)
+      break;
+  }
 }
 
 void
@@ -1222,6 +1237,7 @@ rte_export(struct rt_table_export_hook *th, struct rt_pending_export *rpe)
   {
     net *net = SKIP_BACK(struct network, n.addr, (net_addr (*)[0]) n);
     RT_LOCK(tab);
+    struct rt_pending_export *last = net->last;
     uint count = rte_feed_count(net);
     const rte **feed = NULL;
     if (count)
@@ -1230,7 +1246,7 @@ rte_export(struct rt_table_export_hook *th, struct rt_pending_export *rpe)
       rte_feed_obtain(net, feed, count);
     }
     RT_UNLOCK(tab);
-    hook->req->export_bulk(hook->req, n, rpe, feed, count);
+    hook->req->export_bulk(hook->req, n, rpe, last, feed, count);
   }
   else
     bug("Export request must always provide an export method");
@@ -2620,7 +2636,7 @@ rt_flowspec_export_one(struct rt_export_request *req, const net_addr *net, struc
       || !trie_match_net(dst->flowspec_trie, net))
   {
     RT_UNLOCK(dst_pub);
-    rpe_mark_seen_all(req->hook, first, NULL);
+    rpe_mark_seen_all(req->hook, first, NULL, NULL);
     return;
   }
 
@@ -4205,7 +4221,10 @@ typedef struct {
     struct rt_pending_export *rpe;
     struct {
       const rte **feed;
-      uint *start;
+      struct rt_feed_block_aux {
+       struct rt_pending_export *first, *last;
+       uint start;
+      } *aux;
     };
   };
 } rt_feed_block;
@@ -4224,11 +4243,19 @@ rt_prepare_feed(struct rt_table_export_hook *c, net *n, rt_feed_block *b)
       if (!b->cnt)
       {
        b->feed = tmp_alloc(sizeof(rte *) * MAX(MAX_FEED_BLOCK, cnt));
-       b->start = tmp_alloc(sizeof(uint) * ((cnt >= MAX_FEED_BLOCK) ? 2 : (MAX_FEED_BLOCK + 2 - cnt)));
+
+       uint aux_block_size = (cnt >= MAX_FEED_BLOCK) ? 2 : (MAX_FEED_BLOCK + 2 - cnt);
+       b->aux = tmp_alloc(sizeof(struct rt_feed_block_aux) * aux_block_size);
       }
 
       rte_feed_obtain(n, &b->feed[b->cnt], cnt);
-      b->start[b->pos++] = b->cnt;
+
+      b->aux[b->pos++] = (struct rt_feed_block_aux) {
+       .start = b->cnt,
+       .first = n->first,
+       .last = n->last,
+      };
+
       b->cnt += cnt;
     }
     else if (b->pos == MAX_FEED_BLOCK)
@@ -4242,7 +4269,6 @@ rt_prepare_feed(struct rt_table_export_hook *c, net *n, rt_feed_block *b)
     }
   }
 
-  rpe_mark_seen_all(&c->h, n->first, NULL);
   return 1;
 }
 
@@ -4254,11 +4280,13 @@ rt_process_feed(struct rt_table_export_hook *c, rt_feed_block *b)
 
   if (c->h.req->export_bulk)
   {
-    b->start[b->pos] = b->cnt;
+    b->aux[b->pos].start =  b->cnt;
     for (uint p = 0; p < b->pos; p++)
     {
-      const rte **feed = &b->feed[b->start[p]];
-      c->h.req->export_bulk(c->h.req, feed[0]->net, NULL, feed, b->start[p+1] - b->start[p]);
+      struct rt_feed_block_aux *aux = &b->aux[p];
+      const rte **feed = &b->feed[aux->start];
+
+      c->h.req->export_bulk(c->h.req, feed[0]->net, aux->first, aux->last, feed, (aux+1)->start - aux->start);
     }
   }
   else
@@ -4403,7 +4431,9 @@ rt_feed_for(void *data)
  *     Import table
  */
 
-void channel_reload_export_bulk(struct rt_export_request *req, const net_addr *net, struct rt_pending_export *rpe UNUSED, const rte **feed, uint count)
+void channel_reload_export_bulk(struct rt_export_request *req, const net_addr *net,
+    struct rt_pending_export *first, struct rt_pending_export *last,
+    const rte **feed, uint count)
 {
   struct channel *c = SKIP_BACK(struct channel, reload_req, req);
 
@@ -4420,6 +4450,8 @@ void channel_reload_export_bulk(struct rt_export_request *req, const net_addr *n
       /* And reload the route */
       rte_update(c, net, &new, new.src);
     }
+
+  rpe_mark_seen_all(req->hook, first, last, NULL);
 }
 
 
@@ -4548,7 +4580,7 @@ hc_notify_export_one(struct rt_export_request *req, const net_addr *net, struct
   RT_LOCKED((rtable *) hc->update.data, tab)
     if (ev_active(&hc->update) || !trie_match_net(hc->trie, net))
     {
-      rpe_mark_seen_all(req->hook, first, NULL);
+      rpe_mark_seen_all(req->hook, first, NULL, NULL);
       interested = 0;
     }
 
index 857ed2caceb488c02497d42d59734f4802f9d132..01372b8c1d528d1e0ec4f39422618aadbccb00ae 100644 (file)
--- a/nest/rt.h
+++ b/nest/rt.h
@@ -303,7 +303,9 @@ struct rt_export_request {
    *      and for RA_ANY, both are set to accomodate for feeding all routes but receiving single changes
    */
   void (*export_one)(struct rt_export_request *req, const net_addr *net, struct rt_pending_export *rpe);
-  void (*export_bulk)(struct rt_export_request *req, const net_addr *net, struct rt_pending_export *rpe, const rte **feed, uint count);
+  void (*export_bulk)(struct rt_export_request *req, const net_addr *net,
+      struct rt_pending_export *rpe, struct rt_pending_export *last,
+      const rte **feed, uint count);
 
   void (*dump_req)(struct rt_export_request *req);
   void (*log_state_change)(struct rt_export_request *req, u8);
@@ -422,8 +424,11 @@ struct rt_pending_export *rpe_next(struct rt_pending_export *rpe, struct rte_src
 /* Mark the pending export processed */
 void rpe_mark_seen(struct rt_export_hook *hook, struct rt_pending_export *rpe);
 
-#define rpe_mark_seen_all(hook, first, src) \
-  RPE_WALK((first), _rpe, (src)) rpe_mark_seen((hook), _rpe)
+#define rpe_mark_seen_all(hook, first, last, src) do { \
+  RPE_WALK((first), _rpe, (src)) { \
+    rpe_mark_seen((hook), _rpe); \
+    if (_rpe == last) break; \
+  }} while (0)
 
 /* Get pending export seen status */
 int rpe_get_seen(struct rt_export_hook *hook, struct rt_pending_export *rpe);
@@ -444,13 +449,13 @@ void rt_exporter_init(struct rt_exporter *re);
 
 int channel_preimport(struct rt_import_request *req, rte *new, rte *old);
 
-void channel_reload_export_bulk(struct rt_export_request *req, const net_addr *net, struct rt_pending_export *rpe, const rte **feed, uint count);
+void channel_reload_export_bulk(struct rt_export_request *req, const net_addr *net, struct rt_pending_export *first, struct rt_pending_export *last, const rte **feed, uint count);
 
 void rt_notify_optimal(struct rt_export_request *req, const net_addr *net, struct rt_pending_export *rpe);
 void rt_notify_any(struct rt_export_request *req, const net_addr *net, struct rt_pending_export *rpe);
-void rt_feed_any(struct rt_export_request *req, const net_addr *net, struct rt_pending_export *rpe, const rte **feed, uint count);
-void rt_notify_accepted(struct rt_export_request *req, const net_addr *net, struct rt_pending_export *rpe, const rte **feed, uint count);
-void rt_notify_merged(struct rt_export_request *req, const net_addr *net, struct rt_pending_export *rpe, const rte **feed, uint count);
+void rt_feed_any(struct rt_export_request *req, const net_addr *net, struct rt_pending_export *first, struct rt_pending_export *last, const rte **feed, uint count);
+void rt_notify_accepted(struct rt_export_request *req, const net_addr *net, struct rt_pending_export *first, struct rt_pending_export *last, const rte **feed, uint count);
+void rt_notify_merged(struct rt_export_request *req, const net_addr *net, struct rt_pending_export *first, struct rt_pending_export *last, const rte **feed, uint count);
 
 
 
index f60970781a7568f2814c5578523f9c81c123dcd4..2f72719faba9695c454a371a15ddaf28cbf1bed4 100644 (file)
@@ -1959,7 +1959,7 @@ bgp_out_table_feed(void *data)
       if (hook->h.req->export_bulk)
       {
        const rte *feed = &es.rte;
-       hook->h.req->export_bulk(hook->h.req, n->net, &rpe, &feed, 1);
+       hook->h.req->export_bulk(hook->h.req, n->net, &rpe, &rpe, &feed, 1);
       }
       else if (hook->h.req->export_one)
        hook->h.req->export_one(hook->h.req, n->net, &rpe);
@@ -2657,7 +2657,9 @@ bgp_rte_recalculate(struct rtable_private *table, net *net, rte *new, rte *old,
 }
 
 void
-bgp_rte_modify_stale(struct rt_export_request *req, const net_addr *n, struct rt_pending_export *rpe UNUSED, const rte **feed, uint count)
+bgp_rte_modify_stale(struct rt_export_request *req, const net_addr *n,
+    struct rt_pending_export *first, struct rt_pending_export *last,
+    const rte **feed, uint count)
 {
   struct bgp_channel *c = SKIP_BACK(struct bgp_channel, stale_feed, req);
   struct rt_import_hook *irh = c->c.in_req.hook;
@@ -2705,6 +2707,8 @@ bgp_rte_modify_stale(struct rt_export_request *req, const net_addr *n, struct rt
     /* Restore the memory state */
     lp_restore(tmp_linpool, &tmpp);
   }
+
+  rpe_mark_seen_all(req->hook, first, last, NULL);
 }
 
 
index 1a55fef6421c34d5eaf26c81b58dace0ffcdd680..b9c1192c03e09fd2043de60480b8134feb4b866b 100644 (file)
@@ -618,7 +618,7 @@ void bgp_done_prefix(struct bgp_channel *c, struct bgp_prefix *px, struct bgp_bu
 int bgp_rte_better(const rte *, const rte *);
 int bgp_rte_mergable(const rte *pri, const rte *sec);
 int bgp_rte_recalculate(struct rtable_private *table, net *net, rte *new, rte *old, rte *old_best);
-void bgp_rte_modify_stale(struct rt_export_request *req, const net_addr *n, struct rt_pending_export *rpe UNUSED, const rte **feed, uint count);
+void bgp_rte_modify_stale(struct rt_export_request *req, const net_addr *n, struct rt_pending_export *first, struct rt_pending_export *last, const rte **feed, uint count);
 u32 bgp_rte_igp_metric(const rte *);
 void bgp_rt_notify(struct proto *P, struct channel *C, const net_addr *n, rte *new, const rte *old);
 int bgp_preexport(struct channel *, struct rte *);