summaryrefslogtreecommitdiff
path: root/proto/bgp/attrs.c
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2022-10-04 16:09:41 +0200
committerMaria Matejka <mq@ucw.cz>2022-10-04 16:09:41 +0200
commitf69ba3921a1842f9cac9b9fbd0a32800615da02e (patch)
tree25d3b5b4ef7ffc4fb9937d6f48806934f4da2b62 /proto/bgp/attrs.c
parenta414ba6b975a1187a59cac1f58bc68e5e4b7d37d (diff)
parentfb7fb6744582b2bb74b3b1e32696bd5534e93054 (diff)
Merge commit 'fb7fb674' into HEAD
Diffstat (limited to 'proto/bgp/attrs.c')
-rw-r--r--proto/bgp/attrs.c70
1 files changed, 45 insertions, 25 deletions
diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c
index 2543ee73..bfdd9ac5 100644
--- a/proto/bgp/attrs.c
+++ b/proto/bgp/attrs.c
@@ -1867,25 +1867,30 @@ bgp_free_pending_tx(struct bgp_channel *c)
* Prefix hash table exporter
*/
+struct bgp_out_export_hook {
+ struct rt_export_hook h;
+ u32 hash_iter; /* Iterator over hash */
+};
+
static void
bgp_out_table_feed(void *data)
{
- struct rt_export_hook *hook = data;
- struct bgp_channel *bc = SKIP_BACK(struct bgp_channel, prefix_exporter, hook->table);
+ struct bgp_out_export_hook *hook = data;
+ struct bgp_channel *bc = SKIP_BACK(struct bgp_channel, prefix_exporter, hook->h.table);
struct bgp_pending_tx *c = bc->ptx;
int max = 512;
- const net_addr *neq = (hook->req->addr_mode == TE_ADDR_EQUAL) ? hook->req->addr : NULL;
+ const net_addr *neq = (hook->h.req->addr_mode == TE_ADDR_EQUAL) ? hook->h.req->addr : NULL;
const net_addr *cand = NULL;
do {
HASH_WALK_ITER(c->prefix_hash, PXH, n, hook->hash_iter)
{
- switch (hook->req->addr_mode)
+ switch (hook->h.req->addr_mode)
{
case TE_ADDR_IN:
- if (!net_in_netX(n->net, hook->req->addr))
+ if (!net_in_netX(n->net, hook->h.req->addr))
continue;
/* fall through */
case TE_ADDR_NONE:
@@ -1897,7 +1902,7 @@ bgp_out_table_feed(void *data)
case TE_ADDR_FOR:
if (!neq)
{
- if (net_in_netX(hook->req->addr, n->net) && (!cand || (n->net->length > cand->length)))
+ if (net_in_netX(hook->h.req->addr, n->net) && (!cand || (n->net->length > cand->length)))
cand = n->net;
continue;
}
@@ -1942,13 +1947,13 @@ bgp_out_table_feed(void *data)
.new = &es, .new_best = &es,
};
- if (hook->req->export_bulk)
+ if (hook->h.req->export_bulk)
{
rte *feed = &es.rte;
- hook->req->export_bulk(hook->req, n->net, &rpe, &feed, 1);
+ hook->h.req->export_bulk(hook->h.req, n->net, &rpe, &feed, 1);
}
- else if (hook->req->export_one)
- hook->req->export_one(hook->req, n->net, &rpe);
+ else if (hook->h.req->export_one)
+ hook->h.req->export_one(hook->h.req, n->net, &rpe);
else
bug("No export method in export request");
}
@@ -1959,36 +1964,51 @@ bgp_out_table_feed(void *data)
} while (neq);
if (hook->hash_iter)
- ev_schedule_work(hook->event);
+ ev_schedule_work(&hook->h.event);
else
- rt_set_export_state(hook, TES_READY);
+ rt_set_export_state(&hook->h, TES_READY);
}
-static struct rt_export_hook *
-bgp_out_table_export_start(struct rt_exporter *re, struct rt_export_request *req UNUSED)
+static void
+bgp_out_table_export_start(struct rt_exporter *re, struct rt_export_request *req)
{
- struct bgp_channel *bc = SKIP_BACK(struct bgp_channel, prefix_exporter, re);
- pool *p = rp_new(bc->c.proto->pool, "Export hook");
- struct rt_export_hook *hook = mb_allocz(p, sizeof(struct rt_export_hook));
- hook->pool = p;
- hook->event = ev_new_init(p, bgp_out_table_feed, hook);
- hook->feed_type = TFT_HASH;
+ req->hook = rt_alloc_export(re, sizeof(struct bgp_out_export_hook));
+ req->hook->req = req;
- return hook;
+ struct bgp_out_export_hook *hook = SKIP_BACK(struct bgp_out_export_hook, h, req->hook);
+
+ hook->h.event.hook = bgp_out_table_feed;
+ rt_init_export(re, req->hook);
}
+static void
+bgp_out_table_export_done(void *data)
+{
+ struct bgp_out_export_hook *hook = data;
+ struct rt_export_request *req = hook->h.req;
+ void (*stopped)(struct rt_export_request *) = hook->h.stopped;
+
+ rt_export_stopped(&hook->h);
+ CALL(stopped, req);
+}
+
+static const struct rt_exporter_class bgp_out_table_export_class = {
+ .start = bgp_out_table_export_start,
+ .done = bgp_out_table_export_done,
+};
+
void
bgp_setup_out_table(struct bgp_channel *c)
{
ASSERT_DIE(c->c.out_table == NULL);
c->prefix_exporter = (struct rt_exporter) {
+ .class = &bgp_out_table_export_class,
.addr_type = c->c.table->addr_type,
- .start = bgp_out_table_export_start,
+ .rp = c->c.proto->pool,
};
- init_list(&c->prefix_exporter.hooks);
- init_list(&c->prefix_exporter.pending);
+ rt_exporter_init(&c->prefix_exporter);
c->c.out_table = &c->prefix_exporter;
}
@@ -2510,7 +2530,7 @@ use_deterministic_med(struct rte_storage *r)
}
int
-bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best)
+bgp_rte_recalculate(struct rtable_private *table, net *net, rte *new, rte *old, rte *old_best)
{
rte *key = new ? new : old;
u32 lpref = rt_get_preference(key);