diff options
Diffstat (limited to 'nest')
-rw-r--r-- | nest/proto.c | 2 | ||||
-rw-r--r-- | nest/rt-show.c | 3 | ||||
-rw-r--r-- | nest/rt-table.c | 60 | ||||
-rw-r--r-- | nest/rt.h | 19 |
4 files changed, 61 insertions, 23 deletions
diff --git a/nest/proto.c b/nest/proto.c index bdb905c9..e02e232d 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -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 diff --git a/nest/rt-show.c b/nest/rt-show.c index 40202ef6..a5c7dc8f 100644 --- a/nest/rt-show.c +++ b/nest/rt-show.c @@ -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); diff --git a/nest/rt-table.c b/nest/rt-table.c index d52131c3..83230802 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -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; } @@ -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); |