return;
}
- int nlen = strlen(c->name) + strlen(c->proto->name) + 2;
- char *rn = mb_allocz(c->proto->pool, nlen);
- bsprintf(rn, "%s.%s", c->proto->name, c->name);
-
c->in_req = (struct rt_import_request) {
- .name = rn,
+ .name = mb_sprintf(c->proto->pool, "%s.%s", c->proto->name, c->name),
.trace_routes = c->debug | c->proto->debug,
.dump_req = channel_dump_import_req,
.log_state_change = channel_import_log_state_change,
}
ASSERT(c->channel_state == CS_UP);
- int nlen = strlen(c->name) + strlen(c->proto->name) + 2;
- char *rn = mb_allocz(c->proto->pool, nlen);
- bsprintf(rn, "%s.%s", c->proto->name, c->name);
c->out_req = (struct rt_export_request) {
- .name = rn,
+ .name = mb_sprintf(c->proto->pool, "%s.%s", c->proto->name, c->name),
.list = proto_work_list(c->proto),
.addr = c->out_subprefix,
.addr_mode = c->out_subprefix ? TE_ADDR_IN : TE_ADDR_NONE,
}
void
-rt_notify_accepted(struct rt_export_request *req, const net_addr *n, struct rt_pending_export *rpe,
+rt_notify_accepted(struct rt_export_request *req, const net_addr *n, struct rt_pending_export *first,
struct rte **feed, uint count)
{
struct channel *c = SKIP_BACK(struct channel, out_req, req);
done:
/* Check obsolete routes for previously exported */
- while (rpe)
+ RPE_WALK(first, rpe, NULL)
{
channel_rpe_mark_seen(req, rpe);
if (rpe->old)
old_best = &rpe->old->rte;
}
}
- rpe = rpe_next(rpe, NULL);
}
/* Nothing to export */
}
void
-rt_notify_merged(struct rt_export_request *req, const net_addr *n, struct rt_pending_export *rpe,
+rt_notify_merged(struct rt_export_request *req, const net_addr *n, struct rt_pending_export *first,
struct rte **feed, uint count)
{
struct channel *c = SKIP_BACK(struct channel, out_req, req);
}
/* Check obsolete routes for previously exported */
- while (rpe)
+ RPE_WALK(first, rpe, NULL)
{
channel_rpe_mark_seen(req, rpe);
if (rpe->old)
old_best = &rpe->old->rte;
}
}
- rpe = rpe_next(rpe, NULL);
}
/* Prepare new merged route */
}
void
-rt_notify_optimal(struct rt_export_request *req, const net_addr *net, struct rt_pending_export *rpe)
+rt_notify_optimal(struct rt_export_request *req, const net_addr *net, struct rt_pending_export *first)
{
struct channel *c = SKIP_BACK(struct channel, out_req, req);
- rte *o = RTE_VALID_OR_NULL(rpe->old_best);
- struct rte_storage *new_best = rpe->new_best;
+ rte *o = RTE_VALID_OR_NULL(first->old_best);
+ struct rte_storage *new_best = first->new_best;
- while (rpe)
+ RPE_WALK(first, rpe, NULL)
{
channel_rpe_mark_seen(req, rpe);
new_best = rpe->new_best;
- rpe = rpe_next(rpe, NULL);
}
rte n0 = RTE_COPY_VALID(new_best);
}
void
-rt_notify_any(struct rt_export_request *req, const net_addr *net, struct rt_pending_export *rpe)
+rt_notify_any(struct rt_export_request *req, const net_addr *net, struct rt_pending_export *first)
{
struct channel *c = SKIP_BACK(struct channel, out_req, req);
- rte *n = RTE_VALID_OR_NULL(rpe->new);
- rte *o = RTE_VALID_OR_NULL(rpe->old);
+ rte *n = RTE_VALID_OR_NULL(first->new);
+ rte *o = RTE_VALID_OR_NULL(first->old);
if (!n && !o)
{
- channel_rpe_mark_seen(req, rpe);
+ channel_rpe_mark_seen(req, first);
return;
}
struct rte_src *src = n ? n->src : o->src;
- struct rte_storage *new_latest = rpe->new;
+ struct rte_storage *new_latest = first->new;
- while (rpe)
+ RPE_WALK(first, rpe, src)
{
channel_rpe_mark_seen(req, rpe);
new_latest = rpe->new;
- rpe = rpe_next(rpe, src);
}
rte n0 = RTE_COPY_VALID(new_latest);
&net->last->next, &rpenull, rpe,
memory_order_relaxed,
memory_order_relaxed));
-
+
}
net->last = rpe;
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);
+
+ /* Free the hook before unlocking the table */
+ rfree(hook->pool);
+
+ /* Unlock the table; this may free it */
+ rt_unlock_table(tab);
}
static void
rem_node(&hook->n);
/* Report the channel as stopped. */
- hook->stopped(hook->req);
+ CALL(hook->stopped, hook->req);
/* Reporting the hook as finished. */
CALL(tab->done, hook);
-
- /* Free the hook. */
- rfree(hook->pool);
}
static inline void
hook->last_state_change = current_time();
hook->import_state = state;
- if (hook->req->log_state_change)
- hook->req->log_state_change(hook->req, state);
+ CALL(hook->req->log_state_change, hook->req, state);
}
void
hook->last_state_change = current_time();
atomic_store_explicit(&hook->export_state, state, memory_order_release);
- if (hook->req->log_state_change)
- hook->req->log_state_change(hook->req, state);
+ CALL(hook->req->log_state_change, hook->req, state);
}
void
net *net = SKIP_BACK(struct network, n.addr, (net_addr (*)[0]) n);
ASSERT_DIE(net->first == first);
-
+
if (first == net->last)
/* The only export here */
net->last = net->first = NULL;
ASSERT_DIE(pos < end);
struct rt_pending_export *next = NULL;
-
+
if (++pos < end)
next = &reb->export[pos];
else
count = 1;
}
- for (struct rt_pending_export *rpe = n->first; rpe; rpe = rpe_next(rpe, NULL))
- rpe_mark_seen(c, rpe);
-
+ rpe_mark_seen_all(c, n->first, NULL);
return count;
}