summaryrefslogtreecommitdiff
path: root/nest/proto.c
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2023-04-24 10:39:13 +0200
committerMaria Matejka <mq@ucw.cz>2023-04-24 10:39:13 +0200
commitfa8848aca3f0473412f3ae6288d71dee8458bcfa (patch)
tree20aa1c64f866079684f4923f857021baff4d2b53 /nest/proto.c
parent942d3cbcdd548a73ecc1915a97e297e9bf0bb5e6 (diff)
parent22f54eaee6c6dbe12ad7bb0ee1da09e3e026b970 (diff)
Merge branch 'mq-resource-locking' into thread-next
Diffstat (limited to 'nest/proto.c')
-rw-r--r--nest/proto.c74
1 files changed, 40 insertions, 34 deletions
diff --git a/nest/proto.c b/nest/proto.c
index cd6a3faa..32183c9d 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -23,7 +23,7 @@
#include "filter/f-inst.h"
pool *proto_pool;
-list STATIC_LIST_INIT(proto_list);
+static TLIST_LIST(proto) global_proto_list;
static list STATIC_LIST_INIT(protocol_list);
@@ -367,6 +367,7 @@ channel_roa_subscribe(struct channel *c, rtable *tab, int dir)
.name = mb_sprintf(c->proto->pool, "%s.%s.roa-%s.%s",
c->proto->name, c->name, dir ? "in" : "out", tab->name),
.list = proto_work_list(c->proto),
+ .pool = c->proto->pool,
.trace_routes = c->debug | c->proto->debug,
.dump_req = channel_dump_roa_req,
.export_one = channel_export_one_roa,
@@ -495,6 +496,7 @@ channel_start_export(struct channel *c)
c->out_req = (struct rt_export_request) {
.name = mb_sprintf(c->proto->pool, "%s.%s", c->proto->name, c->name),
.list = proto_work_list(c->proto),
+ .pool = c->proto->pool,
.addr = c->out_subprefix,
.addr_mode = c->out_subprefix ? TE_ADDR_IN : TE_ADDR_NONE,
.trace_routes = c->debug | c->proto->debug,
@@ -685,6 +687,7 @@ channel_setup_in_table(struct channel *c)
c->reload_req = (struct rt_export_request) {
.name = mb_sprintf(c->proto->pool, "%s.%s.import", c->proto->name, c->name),
.list = proto_work_list(c->proto),
+ .pool = c->proto->pool,
.trace_routes = c->debug | c->proto->debug,
.export_bulk = channel_reload_export_bulk,
.dump_req = channel_reload_dump_req,
@@ -1116,8 +1119,11 @@ proto_cleanup(struct proto *p)
{
CALL(p->proto->cleanup, p);
- rfree(p->pool);
- p->pool = NULL;
+ if (p->pool)
+ {
+ rp_free(p->pool);
+ p->pool = NULL;
+ }
p->active = 0;
proto_log_state_change(p);
@@ -1129,13 +1135,14 @@ proto_loop_stopped(void *ptr)
{
struct proto *p = ptr;
- birdloop_enter(&main_birdloop);
+ ASSERT_DIE(birdloop_inside(&main_birdloop));
+ ASSERT_DIE(p->loop != &main_birdloop);
+ p->pool = NULL; /* is freed by birdloop_free() */
birdloop_free(p->loop);
p->loop = &main_birdloop;
- proto_cleanup(p);
- birdloop_leave(&main_birdloop);
+ proto_cleanup(p);
}
static void
@@ -1190,7 +1197,7 @@ proto_new(struct proto_config *cf)
}
static struct proto *
-proto_init(struct proto_config *c, node *n)
+proto_init(struct proto_config *c, struct proto *after)
{
struct protocol *pr = c->protocol;
struct proto *p = pr->init(c);
@@ -1199,7 +1206,7 @@ proto_init(struct proto_config *c, node *n)
p->proto_state = PS_DOWN;
p->last_state_change = current_time();
p->vrf = c->vrf;
- insert_node(&p->n, n);
+ proto_add_after(&global_proto_list, p, after);
p->event = ev_new_init(proto_pool, proto_event, p);
@@ -1214,13 +1221,16 @@ proto_start(struct proto *p)
DBG("Kicking %s up\n", p->name);
PD(p, "Starting");
- p->pool = rp_newf(proto_pool, "Protocol %s", p->cf->name);
-
if (graceful_restart_state == GRS_INIT)
p->gr_recovery = 1;
if (p->cf->loop_order != DOMAIN_ORDER(the_bird))
- p->loop = birdloop_new(p->pool, p->cf->loop_order, p->pool->name, p->cf->loop_max_latency);
+ {
+ p->loop = birdloop_new(proto_pool, p->cf->loop_order, p->cf->loop_max_latency, "Protocol %s", p->cf->name);
+ p->pool = birdloop_pool(p->loop);
+ }
+ else
+ p->pool = rp_newf(proto_pool, the_bird_domain.the_bird, "Protocol %s", p->cf->name);
p->iface_sub.target = proto_event_list(p);
@@ -1430,8 +1440,6 @@ protos_commit(struct config *new, struct config *old, int force_reconfig, int ty
struct proto_config *oc, *nc;
struct symbol *sym;
struct proto *p;
- node *n;
-
DBG("protos_commit:\n");
if (old)
@@ -1518,8 +1526,8 @@ protos_commit(struct config *new, struct config *old, int force_reconfig, int ty
}
struct proto *first_dev_proto = NULL;
+ struct proto *after = NULL;
- n = NODE &(proto_list.head);
WALK_LIST(nc, new->protos)
if (!nc->proto)
{
@@ -1527,14 +1535,14 @@ protos_commit(struct config *new, struct config *old, int force_reconfig, int ty
if (old)
log(L_INFO "Adding protocol %s", nc->name);
- p = proto_init(nc, n);
- n = NODE p;
+ p = proto_init(nc, after);
+ after = p;
if (p->proto == &proto_unix_iface)
first_dev_proto = p;
}
else
- n = NODE nc->proto;
+ after = nc->proto;
DBG("Protocol start\n");
@@ -1552,7 +1560,7 @@ protos_commit(struct config *new, struct config *old, int force_reconfig, int ty
}
/* Start all new protocols */
- WALK_LIST_DELSAFE(p, n, proto_list)
+ WALK_TLIST_DELSAFE(proto, p, &global_proto_list)
proto_rethink_goal(p);
}
@@ -1574,18 +1582,19 @@ proto_rethink_goal(struct proto *p)
if (p->reconfiguring && !p->active)
{
struct proto_config *nc = p->cf_new;
- node *n = p->n.prev;
+ struct proto *after = p->n.prev;
+
DBG("%s has shut down for reconfiguration\n", p->name);
p->cf->proto = NULL;
config_del_obstacle(p->cf->global);
proto_remove_channels(p);
- rem_node(&p->n);
+ proto_rem_node(&global_proto_list, p);
rfree(p->event);
mb_free(p->message);
mb_free(p);
if (!nc)
return;
- p = proto_init(nc, n);
+ p = proto_init(nc, after);
}
/* Determine what state we want to reach */
@@ -1601,7 +1610,7 @@ proto_rethink_goal(struct proto *p)
struct proto *
proto_spawn(struct proto_config *cf, uint disabled)
{
- struct proto *p = proto_init(cf, TAIL(proto_list));
+ struct proto *p = proto_init(cf, global_proto_list.last);
p->disabled = disabled;
proto_rethink_goal(p);
return p;
@@ -1697,8 +1706,7 @@ graceful_restart_done(timer *t UNUSED)
log(L_INFO "Graceful restart done");
graceful_restart_state = GRS_DONE;
- struct proto *p;
- WALK_LIST(p, proto_list)
+ WALK_TLIST(proto, p, &global_proto_list)
{
if (!p->gr_recovery)
continue;
@@ -1794,8 +1802,7 @@ protos_dump_all(void)
{
debug("Protocols:\n");
- struct proto *p;
- WALK_LIST(p, proto_list) PROTO_LOCKED_FROM_MAIN(p)
+ WALK_TLIST(proto, p, &global_proto_list) PROTO_LOCKED_FROM_MAIN(p)
{
#define DPF(x) (p->x ? " " #x : "")
debug(" protocol %s (%p) state %s with %d active channels flags: %s%s%s%s\n",
@@ -1854,7 +1861,7 @@ protos_build(void)
{
protos_build_gen();
- proto_pool = rp_new(&root_pool, "Protocols");
+ proto_pool = rp_new(&root_pool, the_bird_domain.the_bird, "Protocols");
}
@@ -2481,10 +2488,9 @@ proto_apply_cmd_symbol(const struct symbol *s, void (* cmd)(struct proto *, uint
static void
proto_apply_cmd_patt(const char *patt, void (* cmd)(struct proto *, uintptr_t, int), uintptr_t arg)
{
- struct proto *p;
int cnt = 0;
- WALK_LIST(p, proto_list)
+ WALK_TLIST(proto, p, &global_proto_list)
if (!patt || patmatch(patt, p->name))
PROTO_LOCKED_FROM_MAIN(p)
cmd(p, arg, cnt++);
@@ -2511,7 +2517,7 @@ proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, uintptr_t, in
struct proto *
proto_get_named(struct symbol *sym, struct protocol *pr)
{
- struct proto *p, *q;
+ struct proto *p;
if (sym)
{
@@ -2525,7 +2531,7 @@ proto_get_named(struct symbol *sym, struct protocol *pr)
else
{
p = NULL;
- WALK_LIST(q, proto_list)
+ WALK_TLIST(proto, q, &global_proto_list)
if ((q->proto == pr) && (q->proto_state != PS_DOWN))
{
if (p)
@@ -2562,9 +2568,9 @@ proto_iterate_named(struct symbol *sym, struct protocol *proto, struct proto *ol
}
else
{
- for (struct proto *p = !old ? HEAD(proto_list) : NODE_NEXT(old);
- NODE_VALID(p);
- p = NODE_NEXT(p))
+ for (struct proto *p = old ? old->n.next : global_proto_list.first;
+ p;
+ p = p->n.next)
{
if ((p->proto == proto) && (p->proto_state != PS_DOWN))
{