mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-09 20:58:44 +00:00
Table export generalized to allow for exporting from non-tables
This commit is contained in:
parent
becab5072d
commit
050b4b4e5e
@ -498,7 +498,7 @@ channel_start_export(struct channel *c)
|
||||
}
|
||||
|
||||
DBG("%s.%s: Channel start export req=%p\n", c->proto->name, c->name, &c->out_req);
|
||||
rt_request_export(c->table, &c->out_req);
|
||||
rt_request_export(&c->table->exporter, &c->out_req);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -552,7 +552,7 @@ channel_export_stopped(struct rt_export_request *req)
|
||||
{
|
||||
c->refeeding = 1;
|
||||
c->refeed_pending = 0;
|
||||
rt_request_export(c->table, req);
|
||||
rt_request_export(&c->table->exporter, req);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -600,7 +600,7 @@ channel_schedule_reload(struct channel *c)
|
||||
{
|
||||
ASSERT(c->in_req.hook);
|
||||
|
||||
rt_request_export(c->table, &c->reload_req);
|
||||
rt_request_export(&c->table->exporter, &c->reload_req);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -139,7 +139,6 @@ const char *rt_import_state_name_array[TIS_MAX] = {
|
||||
|
||||
const char *rt_export_state_name_array[TES_MAX] = {
|
||||
[TES_DOWN] = "DOWN",
|
||||
[TES_HUNGRY] = "HUNGRY",
|
||||
[TES_FEEDING] = "FEEDING",
|
||||
[TES_READY] = "READY",
|
||||
[TES_STOP] = "STOP"
|
||||
@ -1183,7 +1182,7 @@ rte_announce(rtable *tab, net *net, struct rte_storage *new, struct rte_storage
|
||||
}
|
||||
|
||||
struct rt_export_hook *eh;
|
||||
WALK_LIST(eh, tab->exports)
|
||||
WALK_LIST(eh, tab->exporter.hooks)
|
||||
{
|
||||
if (eh->export_state == TES_STOP)
|
||||
continue;
|
||||
@ -1677,11 +1676,21 @@ rt_examine(rtable *t, net_addr *a, struct channel *c, const struct filter *filte
|
||||
return v > 0;
|
||||
}
|
||||
|
||||
static void
|
||||
rt_table_export_done(struct rt_export_hook *hook)
|
||||
{
|
||||
struct rt_exporter *re = hook->table;
|
||||
struct rtable *tab = SKIP_BACK(struct rtable, exporter, re);
|
||||
|
||||
rt_unlock_table(tab);
|
||||
DBG("Export hook %p in table %s finished uc=%u\n", hook, tab->name, tab->use_count);
|
||||
}
|
||||
|
||||
static void
|
||||
rt_export_stopped(void *data)
|
||||
{
|
||||
struct rt_export_hook *hook = data;
|
||||
rtable *tab = hook->table;
|
||||
struct rt_exporter *tab = hook->table;
|
||||
|
||||
/* Unlist */
|
||||
rem_node(&hook->n);
|
||||
@ -1689,14 +1698,13 @@ rt_export_stopped(void *data)
|
||||
/* Reporting the channel as stopped. */
|
||||
hook->stopped(hook->req);
|
||||
|
||||
/* Reporting the hook as finished. */
|
||||
tab->done(hook);
|
||||
|
||||
/* Freeing the hook together with its coroutine. */
|
||||
rfree(hook->pool);
|
||||
rt_unlock_table(tab);
|
||||
|
||||
DBG("Export hook %p in table %s finished uc=%u\n", hook, tab->name, tab->use_count);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
rt_set_import_state(struct rt_import_hook *hook, u8 state)
|
||||
{
|
||||
@ -1748,54 +1756,73 @@ rt_stop_import(struct rt_import_request *req, void (*stopped)(struct rt_import_r
|
||||
hook->stopped = stopped;
|
||||
}
|
||||
|
||||
void
|
||||
rt_request_export(rtable *tab, struct rt_export_request *req)
|
||||
static struct rt_export_hook *
|
||||
rt_table_export_start(struct rt_exporter *re, struct rt_export_request *req)
|
||||
{
|
||||
rtable *tab = SKIP_BACK(rtable, exporter, re);
|
||||
rt_lock_table(tab);
|
||||
|
||||
pool *p = rp_new(tab->rp, "Export hook");
|
||||
struct rt_export_hook *hook = req->hook = mb_allocz(p, sizeof(struct rt_export_hook));
|
||||
struct rt_export_hook *hook = mb_allocz(p, sizeof(struct rt_export_hook));
|
||||
hook->pool = p;
|
||||
hook->lp = lp_new_default(p);
|
||||
|
||||
hook->req = req;
|
||||
hook->table = tab;
|
||||
|
||||
/* stats zeroed by mb_allocz */
|
||||
|
||||
rt_set_export_state(hook, TES_HUNGRY);
|
||||
|
||||
hook->n = (node) {};
|
||||
add_tail(&tab->exports, &hook->n);
|
||||
|
||||
FIB_ITERATE_INIT(&hook->feed_fit, &tab->fib);
|
||||
|
||||
DBG("New export hook %p req %p in table %s uc=%u\n", hook, req, tab->name, tab->use_count);
|
||||
|
||||
hook->event = ev_new_init(p, rt_feed_channel, hook);
|
||||
|
||||
return hook;
|
||||
}
|
||||
|
||||
void
|
||||
rt_request_export(struct rt_exporter *re, struct rt_export_request *req)
|
||||
{
|
||||
struct rt_export_hook *hook = req->hook = re->start(re, req);
|
||||
|
||||
hook->req = req;
|
||||
hook->table = re;
|
||||
|
||||
hook->n = (node) {};
|
||||
add_tail(&re->hooks, &hook->n);
|
||||
|
||||
rt_set_export_state(hook, TES_FEEDING);
|
||||
|
||||
hook->event = ev_new_init(p, rt_feed_channel, hook);
|
||||
ev_schedule_work(hook->event);
|
||||
}
|
||||
|
||||
static void
|
||||
rt_table_export_stop(struct rt_export_hook *hook)
|
||||
{
|
||||
rtable *tab = SKIP_BACK(rtable, exporter, hook->table);
|
||||
|
||||
if (hook->export_state == TES_FEEDING)
|
||||
fit_get(&tab->fib, &hook->feed_fit);
|
||||
}
|
||||
|
||||
void
|
||||
rt_stop_export(struct rt_export_request *req, void (*stopped)(struct rt_export_request *))
|
||||
{
|
||||
ASSERT_DIE(req->hook);
|
||||
struct rt_export_hook *hook = req->hook;
|
||||
|
||||
rtable *tab = hook->table;
|
||||
|
||||
/* Stop feeding */
|
||||
/* Cancel the feeder event */
|
||||
ev_postpone(hook->event);
|
||||
|
||||
if (hook->export_state == TES_FEEDING)
|
||||
fit_get(&tab->fib, &hook->feed_fit);
|
||||
/* Stop feeding from the exporter */
|
||||
hook->table->stop(hook);
|
||||
|
||||
/* Reset the event as the stopped event */
|
||||
hook->event->hook = rt_export_stopped;
|
||||
hook->stopped = stopped;
|
||||
|
||||
/* Update export state */
|
||||
rt_set_export_state(hook, TES_STOP);
|
||||
|
||||
/* Run the stopped event */
|
||||
ev_schedule(hook->event);
|
||||
}
|
||||
|
||||
@ -1948,7 +1975,7 @@ rt_dump_hooks(rtable *tab)
|
||||
}
|
||||
|
||||
struct rt_export_hook *eh;
|
||||
WALK_LIST(eh, tab->exports)
|
||||
WALK_LIST(eh, tab->exporter.hooks)
|
||||
{
|
||||
eh->req->dump_req(eh->req);
|
||||
debug(" Export hook %p requested by %p:"
|
||||
@ -2252,10 +2279,17 @@ rt_setup(pool *pp, struct rtable_config *cf)
|
||||
|
||||
init_list(&t->flowspec_links);
|
||||
|
||||
t->exporter = (struct rt_exporter) {
|
||||
.start = rt_table_export_start,
|
||||
.stop = rt_table_export_stop,
|
||||
.done = rt_table_export_done,
|
||||
};
|
||||
init_list(&t->exporter.hooks);
|
||||
|
||||
if (!(t->internal = cf->internal))
|
||||
{
|
||||
init_list(&t->imports);
|
||||
init_list(&t->exports);
|
||||
|
||||
hmap_init(&t->id_map, p, 1024);
|
||||
hmap_set(&t->id_map, 0);
|
||||
|
||||
@ -3138,7 +3172,9 @@ rt_feed_channel(void *data)
|
||||
|
||||
ASSERT(c->export_state == TES_FEEDING);
|
||||
|
||||
FIB_ITERATE_START(&c->table->fib, fit, net, n)
|
||||
rtable *tab = SKIP_BACK(rtable, exporter, c->table);
|
||||
|
||||
FIB_ITERATE_START(&tab->fib, fit, net, n)
|
||||
{
|
||||
if (max_feed <= 0)
|
||||
{
|
||||
|
17
nest/rt.h
17
nest/rt.h
@ -56,6 +56,16 @@ struct rtable_config {
|
||||
btime max_settle_time; /* Maximum settle time for notifications */
|
||||
};
|
||||
|
||||
struct rt_export_hook;
|
||||
struct rt_export_request;
|
||||
|
||||
struct rt_exporter {
|
||||
list hooks; /* Registered route export hooks */
|
||||
struct rt_export_hook *(*start)(struct rt_exporter *, struct rt_export_request *);
|
||||
void (*stop)(struct rt_export_hook *);
|
||||
void (*done)(struct rt_export_hook *);
|
||||
};
|
||||
|
||||
typedef struct rtable {
|
||||
resource r;
|
||||
node n; /* Node in list of all tables */
|
||||
@ -69,7 +79,7 @@ typedef struct rtable {
|
||||
u32 rt_count; /* Number of routes in the table */
|
||||
|
||||
list imports; /* Registered route importers */
|
||||
list exports; /* Registered route exporters */
|
||||
struct rt_exporter exporter; /* Exporter API structure */
|
||||
|
||||
struct hmap id_map;
|
||||
struct hostcache *hostcache;
|
||||
@ -221,7 +231,7 @@ struct rt_export_request {
|
||||
|
||||
struct rt_export_hook {
|
||||
node n;
|
||||
rtable *table; /* The connected table */
|
||||
struct rt_exporter *table; /* The connected table */
|
||||
|
||||
pool *pool;
|
||||
linpool *lp;
|
||||
@ -255,14 +265,13 @@ struct rt_export_hook {
|
||||
#define TIS_MAX 6
|
||||
|
||||
#define TES_DOWN 0
|
||||
#define TES_HUNGRY 1
|
||||
#define TES_FEEDING 2
|
||||
#define TES_READY 3
|
||||
#define TES_STOP 4
|
||||
#define TES_MAX 5
|
||||
|
||||
void rt_request_import(rtable *tab, struct rt_import_request *req);
|
||||
void rt_request_export(rtable *tab, struct rt_export_request *req);
|
||||
void rt_request_export(struct rt_exporter *tab, struct rt_export_request *req);
|
||||
|
||||
void rt_stop_import(struct rt_import_request *, void (*stopped)(struct rt_import_request *));
|
||||
void rt_stop_export(struct rt_export_request *, void (*stopped)(struct rt_export_request *));
|
||||
|
Loading…
Reference in New Issue
Block a user