mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 01:31:55 +00:00
This also hits the cork, maybe this refactoring is too brutal at once
This commit is contained in:
parent
6223c4066c
commit
d3b4b36af5
10
lib/route.h
10
lib/route.h
@ -87,8 +87,8 @@ struct rte_owner {
|
||||
u32 hash_key;
|
||||
u32 uc;
|
||||
u32 debug;
|
||||
struct callback *prune_callback;
|
||||
event *stop;
|
||||
callback prune;
|
||||
callback *stop;
|
||||
};
|
||||
|
||||
extern DOMAIN(attrs) attrs_domain;
|
||||
@ -118,7 +118,7 @@ static inline void rt_lock_source(struct rte_src *src)
|
||||
|
||||
static inline void rt_unlock_source(struct rte_src *src)
|
||||
{
|
||||
lfuc_unlock(&src->uc, src->owner->prune_callback);
|
||||
lfuc_unlock(&src->uc, &src->owner->prune);
|
||||
}
|
||||
|
||||
#ifdef RT_SOURCE_DEBUG
|
||||
@ -129,8 +129,8 @@ static inline void rt_unlock_source(struct rte_src *src)
|
||||
#define rt_unlock_source(x) ( log(L_INFO "Unlock source %uG at %s:%d", (x)->global_id, __FILE__, __LINE__), _rt_unlock_source_internal(x) )
|
||||
#endif
|
||||
|
||||
void rt_init_sources(struct rte_owner *, const char *name, event_list *list);
|
||||
void rt_destroy_sources(struct rte_owner *, event *);
|
||||
void rt_init_sources(struct rte_owner *, const char *name, struct birdloop *loop);
|
||||
void rt_destroy_sources(struct rte_owner *, callback *);
|
||||
|
||||
void rt_dump_sources(struct rte_owner *);
|
||||
|
||||
|
@ -1239,7 +1239,7 @@ mpls_announce_fec(struct mpls_fec_map *m, struct mpls_fec *fec, ea_list *src)
|
||||
/* The same hostentry, but different dependent table */
|
||||
SKIP_BACK_DECLARE(struct hostentry_adata, head, ad, heea->u.ad);
|
||||
struct hostentry *he = head->he;
|
||||
ea_set_hostentry(&e.attrs, m->channel->table, he->owner, he->addr, he->link,
|
||||
ea_set_hostentry(&e.attrs, m->channel->table, he->owner->tab, he->addr, he->link,
|
||||
HOSTENTRY_LABEL_COUNT(head), head->labels);
|
||||
}
|
||||
else
|
||||
|
@ -395,7 +395,7 @@ neigh_unlink(neighbor *n)
|
||||
proto_neigh_rem_node(&p->neighbors, n);
|
||||
|
||||
if ((p->proto_state == PS_DOWN) && EMPTY_TLIST(proto_neigh, &p->neighbors))
|
||||
proto_send_event(p, p->event);
|
||||
callback_activate(&p->done);
|
||||
|
||||
n->proto = NULL;
|
||||
|
||||
|
22
nest/proto.c
22
nest/proto.c
@ -656,7 +656,7 @@ channel_check_stopped(struct channel *c)
|
||||
ASSERT_DIE(!rt_export_feed_active(&c->reimporter));
|
||||
|
||||
channel_set_state(c, CS_DOWN);
|
||||
proto_send_event(c->proto, c->proto->event);
|
||||
callback_activate(&c->proto->done);
|
||||
|
||||
break;
|
||||
case CS_PAUSE:
|
||||
@ -819,7 +819,7 @@ channel_do_down(struct channel *c)
|
||||
|
||||
/* Schedule protocol shutddown */
|
||||
if (proto_is_done(c->proto))
|
||||
proto_send_event(c->proto, c->proto->event);
|
||||
callback_activate(&c->proto->done);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1182,9 +1182,9 @@ proto_loop_stopped(void *ptr)
|
||||
|
||||
|
||||
static void
|
||||
proto_event(void *ptr)
|
||||
proto_event(callback *cb)
|
||||
{
|
||||
struct proto *p = ptr;
|
||||
SKIP_BACK_DECLARE(struct proto, p, done, cb);
|
||||
|
||||
if (p->do_stop)
|
||||
{
|
||||
@ -1249,7 +1249,7 @@ proto_init(struct proto_config *c, struct proto *after)
|
||||
p->vrf = c->vrf;
|
||||
proto_add_after(&global_proto_list, p, after);
|
||||
|
||||
p->event = ev_new_init(proto_pool, proto_event, p);
|
||||
callback_init(&p->done, proto_event, p->loop);
|
||||
|
||||
PD(p, "Initializing%s", p->disabled ? " [disabled]" : "");
|
||||
|
||||
@ -1269,6 +1269,8 @@ proto_start(struct proto *p)
|
||||
{
|
||||
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);
|
||||
ASSERT_DIE(!callback_is_active(&p->done));
|
||||
p->done.target = p->loop;
|
||||
}
|
||||
else
|
||||
p->pool = rp_newf(proto_pool, the_bird_domain.the_bird, "Protocol %s", p->cf->name);
|
||||
@ -1680,7 +1682,7 @@ proto_rethink_goal(struct proto *p)
|
||||
OBSREF_CLEAR(p->global_config);
|
||||
proto_remove_channels(p);
|
||||
proto_rem_node(&global_proto_list, p);
|
||||
rfree(p->event);
|
||||
callback_cancel(&p->done);
|
||||
mb_free(p->message);
|
||||
mb_free(p);
|
||||
if (!nc)
|
||||
@ -2181,7 +2183,7 @@ proto_do_start(struct proto *p)
|
||||
{
|
||||
p->active = 1;
|
||||
|
||||
rt_init_sources(&p->sources, p->name, proto_event_list(p));
|
||||
rt_init_sources(&p->sources, p->name, p->loop);
|
||||
if (!p->sources.class)
|
||||
p->sources.class = &default_rte_owner_class;
|
||||
|
||||
@ -2226,10 +2228,10 @@ proto_do_stop(struct proto *p)
|
||||
p->pool_up = NULL;
|
||||
|
||||
proto_stop_channels(p);
|
||||
rt_destroy_sources(&p->sources, p->event);
|
||||
rt_destroy_sources(&p->sources, &p->done);
|
||||
|
||||
p->do_stop = 1;
|
||||
proto_send_event(p, p->event);
|
||||
callback_activate(&p->done);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2239,7 +2241,7 @@ proto_do_down(struct proto *p)
|
||||
|
||||
/* Shutdown is finished in the protocol event */
|
||||
if (proto_is_done(p))
|
||||
proto_send_event(p, p->event);
|
||||
callback_activate(&p->done);
|
||||
}
|
||||
|
||||
|
||||
|
@ -141,7 +141,7 @@ struct proto {
|
||||
as the protocol enters the STOP / DOWN state */
|
||||
pool *pool_inloop; /* Pool containing local objects which need to be freed
|
||||
before the protocol's birdloop actually stops, like olocks */
|
||||
event *event; /* Protocol event */
|
||||
callback done; /* Protocol shutdown checker */
|
||||
timer *restart_timer; /* Timer to restart the protocol from limits */
|
||||
event *restart_event; /* Event to restart/shutdown the protocol from limits */
|
||||
struct birdloop *loop; /* BIRDloop running this protocol */
|
||||
|
15
nest/route.h
15
nest/route.h
@ -361,7 +361,7 @@ extern uint rtable_max_id;
|
||||
_Atomic u32 routes_block_size; /* Size of the route object pointer block */ \
|
||||
struct f_trie * _Atomic trie; /* Trie of prefixes defined in fib */ \
|
||||
event *nhu_event; /* Nexthop updater */ \
|
||||
event *hcu_event; /* Hostcache updater */ \
|
||||
callback shutdown_finished; /* Shutdown finisher */ \
|
||||
struct rt_exporter export_all; /* Route export journal for all routes */ \
|
||||
struct rt_exporter export_best; /* Route export journal for best routes */ \
|
||||
|
||||
@ -449,8 +449,10 @@ LOBJ_UNLOCK_CLEANUP(rtable, rtable);
|
||||
|
||||
extern struct rt_cork {
|
||||
_Atomic uint active;
|
||||
event_list queue;
|
||||
event run;
|
||||
struct rt_cork_callbacks {
|
||||
struct rt_cork_callbacks *_Atomic next;
|
||||
callback *uncork_block[0];
|
||||
} *_Atomic callbacks;
|
||||
} rt_cork;
|
||||
|
||||
static inline void rt_cork_acquire(void)
|
||||
@ -464,7 +466,7 @@ static inline void rt_cork_release(void)
|
||||
ev_send(&global_work_list, &rt_cork.run);
|
||||
}
|
||||
|
||||
static inline _Bool rt_cork_check(event *e)
|
||||
static inline _Bool rt_cork_check(callback *cb)
|
||||
{
|
||||
int corked = (atomic_load_explicit(&rt_cork.active, memory_order_acquire) > 0);
|
||||
if (corked)
|
||||
@ -641,7 +643,7 @@ struct hostentry {
|
||||
ip_addr link; /* (link-local) IP address of host, used as gw
|
||||
if host is directly attached */
|
||||
rtable *tab; /* Dependent table, part of key */
|
||||
rtable *owner; /* Nexthop owner table */
|
||||
struct hostcache *owner; /* Nexthop owner hostcache (use with care) */
|
||||
struct hostentry *next; /* Next in hash chain */
|
||||
unsigned hash_key; /* Hash key */
|
||||
u32 igp_metric; /* Chosen route IGP metric */
|
||||
@ -658,11 +660,14 @@ struct hostcache {
|
||||
unsigned hash_order, hash_shift;
|
||||
unsigned hash_max, hash_min;
|
||||
unsigned hash_items;
|
||||
u8 corked; /* Stuck by cork */
|
||||
linpool *lp; /* Linpool for trie */
|
||||
struct f_trie *trie; /* Trie of prefixes that might affect hostentries */
|
||||
list hostentries; /* List of all hostentries */
|
||||
struct rt_export_request req; /* Notifier */
|
||||
event source_event;
|
||||
callback update; /* Hostcache updater */
|
||||
callback uncork; /* Hostcache uncorker */
|
||||
};
|
||||
|
||||
struct rt_digestor {
|
||||
|
@ -150,7 +150,7 @@ static void
|
||||
ea_gen_hostentry_freed(const eattr *ea)
|
||||
{
|
||||
struct hostentry_adata *had = (struct hostentry_adata *) ea->u.ptr;
|
||||
lfuc_unlock(&had->he->uc, birdloop_event_list(had->he->owner->loop), had->he->owner->hcu_event);
|
||||
lfuc_unlock(&had->he->uc, &had->he->owner->update);
|
||||
}
|
||||
|
||||
struct ea_class ea_gen_hostentry = {
|
||||
@ -244,7 +244,7 @@ rt_get_source_o(struct rte_owner *p, u32 id)
|
||||
if (p->stop)
|
||||
bug("Stopping route owner asked for another source.");
|
||||
|
||||
ASSERT_DIE(birdloop_inside(p->list->loop));
|
||||
ASSERT_DIE(birdloop_inside(p->prune.target));
|
||||
|
||||
struct rte_src *src = rt_find_source(p, id);
|
||||
|
||||
@ -327,16 +327,10 @@ rt_find_source_global(u32 id)
|
||||
return src;
|
||||
}
|
||||
|
||||
static inline void
|
||||
rt_done_sources(struct rte_owner *o)
|
||||
{
|
||||
ev_send(o->list, o->stop);
|
||||
}
|
||||
|
||||
void
|
||||
rt_prune_sources(void *data)
|
||||
rt_prune_sources(callback *cb)
|
||||
{
|
||||
struct rte_owner *o = data;
|
||||
SKIP_BACK_DECLARE(struct rte_owner, o, prune, cb);
|
||||
|
||||
HASH_WALK_FILTER(o->hash, next, src, sp)
|
||||
{
|
||||
@ -365,13 +359,13 @@ rt_prune_sources(void *data)
|
||||
|
||||
if (o->stop && !o->uc)
|
||||
{
|
||||
rfree(o->prune);
|
||||
callback_cancel(&o->prune);
|
||||
RTA_UNLOCK;
|
||||
|
||||
if (o->debug & D_EVENTS)
|
||||
log(L_TRACE "%s: all rte_src's pruned, scheduling stop event", o->name);
|
||||
|
||||
rt_done_sources(o);
|
||||
callback_activate(o->stop);
|
||||
}
|
||||
else
|
||||
RTA_UNLOCK;
|
||||
@ -402,23 +396,22 @@ rt_dump_sources(struct rte_owner *o)
|
||||
}
|
||||
|
||||
void
|
||||
rt_init_sources(struct rte_owner *o, const char *name, event_list *list)
|
||||
rt_init_sources(struct rte_owner *o, const char *name, struct birdloop *loop)
|
||||
{
|
||||
RTA_LOCK;
|
||||
HASH_INIT(o->hash, rta_pool, RSH_INIT_ORDER);
|
||||
o->hash_key = random_u32();
|
||||
o->uc = 0;
|
||||
o->name = name;
|
||||
o->prune = ev_new_init(rta_pool, rt_prune_sources, o);
|
||||
callback_init(&o->prune, rt_prune_sources, loop);
|
||||
o->stop = NULL;
|
||||
o->list = list;
|
||||
RTA_UNLOCK;
|
||||
if (o->debug & D_EVENTS)
|
||||
log(L_TRACE "%s: initialized rte_src owner", o->name);
|
||||
}
|
||||
|
||||
void
|
||||
rt_destroy_sources(struct rte_owner *o, event *done)
|
||||
rt_destroy_sources(struct rte_owner *o, callback *done)
|
||||
{
|
||||
o->stop = done;
|
||||
|
||||
@ -427,11 +420,7 @@ rt_destroy_sources(struct rte_owner *o, event *done)
|
||||
if (o->debug & D_EVENTS)
|
||||
log(L_TRACE "%s: rte_src owner destroy requested, already clean, scheduling stop event", o->name);
|
||||
|
||||
RTA_LOCK;
|
||||
rfree(o->prune);
|
||||
RTA_UNLOCK;
|
||||
|
||||
rt_done_sources(o);
|
||||
callback_activate(o->stop);
|
||||
}
|
||||
else
|
||||
if (o->debug & D_EVENTS)
|
||||
@ -1386,9 +1375,9 @@ ea_show_hostentry(const struct adata *ad, byte *buf, uint size)
|
||||
uint s = 0;
|
||||
|
||||
if (ipa_nonzero(had->he->link) && !ipa_equal(had->he->link, had->he->addr))
|
||||
s = bsnprintf(buf, size, "via %I %I table %s", had->he->addr, had->he->link, had->he->owner->name);
|
||||
s = bsnprintf(buf, size, "via %I %I table %s", had->he->addr, had->he->link, had->he->owner->tab->name);
|
||||
else
|
||||
s = bsnprintf(buf, size, "via %I table %s", had->he->addr, had->he->owner->name);
|
||||
s = bsnprintf(buf, size, "via %I table %s", had->he->addr, had->he->owner->tab->name);
|
||||
|
||||
uint lc = HOSTENTRY_LABEL_COUNT(had);
|
||||
if (!lc)
|
||||
@ -1632,7 +1621,7 @@ static SPINHASH(struct ea_storage) rta_hash_table;
|
||||
#define RTAH_REHASH rta_rehash
|
||||
#define RTAH_PARAMS /8, *2, 2, 2, 12, 28
|
||||
|
||||
static void RTAH_REHASH(void *_ UNUSED) {
|
||||
static void RTAH_REHASH(callback *_ UNUSED) {
|
||||
int step;
|
||||
|
||||
RTA_LOCK;
|
||||
@ -1838,7 +1827,7 @@ rta_init(void)
|
||||
for (uint i=0; i<ARRAY_SIZE(ea_slab_sizes); i++)
|
||||
ea_slab[i] = sl_new(rta_pool, ea_slab_sizes[i]);
|
||||
|
||||
SPINHASH_INIT(rta_hash_table, RTAH, rta_pool, &global_work_list);
|
||||
SPINHASH_INIT(rta_hash_table, RTAH, rta_pool, &main_birdloop);
|
||||
|
||||
rte_src_init();
|
||||
ea_class_init();
|
||||
|
112
nest/rt-table.c
112
nest/rt-table.c
@ -129,8 +129,8 @@ struct rt_cork rt_cork;
|
||||
/* Data structures for export journal */
|
||||
|
||||
static void rt_free_hostcache(struct rtable_private *tab);
|
||||
static void rt_hcu_uncork(void *_tab);
|
||||
static void rt_update_hostcache(void *tab);
|
||||
static void rt_hcu_update(callback *);
|
||||
static void rt_hcu_uncork(callback *);
|
||||
static void rt_next_hop_update(void *_tab);
|
||||
static void rt_nhu_uncork(void *_tab);
|
||||
static inline void rt_next_hop_resolve_rte(rte *r);
|
||||
@ -3068,7 +3068,7 @@ rt_setup(pool *pp, struct rtable_config *cf)
|
||||
if (t->id >= rtable_max_id)
|
||||
rtable_max_id = t->id + 1;
|
||||
|
||||
t->netindex = netindex_hash_new(birdloop_pool(t->loop), birdloop_event_list(t->loop), cf->addr_type);
|
||||
t->netindex = netindex_hash_new(birdloop_pool(t->loop), t->loop, cf->addr_type);
|
||||
atomic_store_explicit(&t->routes, mb_allocz(p, RT_INITIAL_ROUTES_BLOCK_SIZE * sizeof(net)), memory_order_relaxed);
|
||||
atomic_store_explicit(&t->routes_block_size, RT_INITIAL_ROUTES_BLOCK_SIZE, memory_order_relaxed);
|
||||
|
||||
@ -4319,11 +4319,10 @@ rt_unlock_table_priv(struct rtable_private *r, const char *file, uint line)
|
||||
}
|
||||
|
||||
static void
|
||||
rt_shutdown_finished(void *tab_)
|
||||
rt_shutdown_finished(struct callback *cb)
|
||||
{
|
||||
rtable *t = tab_;
|
||||
RT_LOCK(t, tab);
|
||||
birdloop_stop_self(t->loop, rt_delete, t);
|
||||
RT_LOCK(SKIP_BACK(rtable, shutdown_finished, cb), tab);
|
||||
birdloop_stop_self(tab->loop, rt_delete, tab);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4332,6 +4331,8 @@ rt_shutdown(void *tab_)
|
||||
rtable *t = tab_;
|
||||
RT_LOCK(t, tab);
|
||||
|
||||
callback_init(&tab->shutdown_finished, rt_shutdown_finished, tab->loop);
|
||||
|
||||
if (tab->export_digest)
|
||||
{
|
||||
rtex_export_unsubscribe(&tab->export_digest->req);
|
||||
@ -4345,9 +4346,7 @@ rt_shutdown(void *tab_)
|
||||
rt_exporter_shutdown(&tab->export_best, NULL);
|
||||
rt_exporter_shutdown(&tab->export_all, NULL);
|
||||
|
||||
netindex_hash_delete(tab->netindex,
|
||||
ev_new_init(tab->rp, rt_shutdown_finished, tab),
|
||||
birdloop_event_list(tab->loop));
|
||||
netindex_hash_delete(tab->netindex, &tab->shutdown_finished);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4495,13 +4494,9 @@ rt_commit(struct config *new, struct config *old)
|
||||
|
||||
rt_check_cork_low(tab);
|
||||
|
||||
if (tab->hcu_event)
|
||||
{
|
||||
if (ev_get_list(tab->hcu_event) == &rt_cork.queue)
|
||||
ev_postpone(tab->hcu_event);
|
||||
|
||||
/* Stop the hostcache updater */
|
||||
if (rt_export_get_state(&tab->hostcache->req) != TES_DOWN)
|
||||
rtex_export_unsubscribe(&tab->hostcache->req);
|
||||
}
|
||||
|
||||
rt_unlock_table(tab);
|
||||
}
|
||||
@ -4637,6 +4632,9 @@ hc_notify_export(void *_hc)
|
||||
|
||||
RT_EXPORT_WALK(&hc->req, u)
|
||||
{
|
||||
if (callback_is_active(&hc->update))
|
||||
continue;
|
||||
|
||||
const net_addr *n = NULL;
|
||||
switch (u->kind)
|
||||
{
|
||||
@ -4676,9 +4674,6 @@ hc_notify_export(void *_hc)
|
||||
continue;
|
||||
|
||||
RT_LOCK(hc->tab, tab);
|
||||
if (ev_active(tab->hcu_event))
|
||||
continue;
|
||||
|
||||
if (!trie_match_net(hc->trie, n))
|
||||
{
|
||||
/* No interest in this update, mark seen only */
|
||||
@ -4693,12 +4688,12 @@ hc_notify_export(void *_hc)
|
||||
hc->req.name, n, NET_TO_INDEX(n)->index);
|
||||
|
||||
if ((rt_export_get_state(&hc->req) == TES_READY)
|
||||
&& !ev_active(tab->hcu_event))
|
||||
&& !callback_is_active(&hc->update))
|
||||
{
|
||||
if (hc->req.trace_routes & D_EVENTS)
|
||||
log(L_TRACE "%s requesting HCU", hc->req.name);
|
||||
|
||||
ev_send_loop(tab->loop, tab->hcu_event);
|
||||
callback_activate(&hc->update);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4722,12 +4717,11 @@ rt_init_hostcache(struct rtable_private *tab)
|
||||
hc->trie = f_new_trie(hc->lp, 0);
|
||||
|
||||
hc->tab = RT_PUB(tab);
|
||||
|
||||
tab->hcu_event = ev_new_init(tab->rp, rt_update_hostcache, tab);
|
||||
tab->hcu_uncork_event = ev_new_init(tab->rp, rt_hcu_uncork, tab);
|
||||
tab->hostcache = hc;
|
||||
|
||||
ev_send_loop(tab->loop, tab->hcu_event);
|
||||
rt_lock_table(tab);
|
||||
callback_init(&hc->update, rt_hcu_update, tab->loop);
|
||||
callback_activate(&hc->update);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4877,20 +4871,9 @@ done:
|
||||
}
|
||||
|
||||
static void
|
||||
rt_hcu_uncork(void *_tab)
|
||||
rt_update_hostcache(struct hostcache *hc, rtable **nhu_pending)
|
||||
{
|
||||
RT_LOCKED((rtable *) _tab, tab)
|
||||
ev_send_loop(tab->loop, tab->hcu_event);
|
||||
}
|
||||
|
||||
static void
|
||||
rt_update_hostcache(void *data)
|
||||
{
|
||||
rtable **nhu_pending;
|
||||
|
||||
RT_LOCKED((rtable *) data, tab)
|
||||
{
|
||||
struct hostcache *hc = tab->hostcache;
|
||||
RT_LOCK(hc->tab, tab);
|
||||
|
||||
/* Finish initialization */
|
||||
if (!hc->req.name)
|
||||
@ -4913,19 +4896,6 @@ rt_update_hostcache(void *data)
|
||||
rtex_export_subscribe(&tab->export_best, &hc->req);
|
||||
}
|
||||
|
||||
/* Shutdown shortcut */
|
||||
if (rt_export_get_state(&hc->req) == TES_DOWN)
|
||||
return;
|
||||
|
||||
if (rt_cork_check(tab->hcu_uncork_event))
|
||||
{
|
||||
rt_trace(tab, D_STATES, "Hostcache update corked");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Destination schedule map */
|
||||
nhu_pending = tmp_allocz(sizeof(rtable *) * rtable_max_id);
|
||||
|
||||
struct hostentry *he;
|
||||
node *n, *x;
|
||||
|
||||
@ -4947,12 +4917,52 @@ rt_update_hostcache(void *data)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rt_hcu_update(struct callback *cb)
|
||||
{
|
||||
SKIP_BACK_DECLARE(struct hostcache, hc, update, cb);
|
||||
|
||||
/* Still corked, do nothing */
|
||||
if (hc->corked)
|
||||
return;
|
||||
|
||||
/* Shutdown shortcut */
|
||||
if (hc->req.name && (rt_export_get_state(&hc->req) == TES_DOWN))
|
||||
{
|
||||
RT_LOCK(hc->tab, tab);
|
||||
rt_unlock_table(tab);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Cork check */
|
||||
if (rt_cork_check(&hc->uncork))
|
||||
{
|
||||
hc->corked = 1;
|
||||
rt_trace(tab, D_STATES, "Hostcache update corked");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Destination schedule map */
|
||||
rtable **nhu_pending = tmp_allocz(sizeof(rtable *) * rtable_max_id);
|
||||
|
||||
/* Find which destinations we have to ping */
|
||||
rt_update_hostcache(hc, &nhu_pending);
|
||||
|
||||
/* And do the pinging */
|
||||
for (uint i=0; i<rtable_max_id; i++)
|
||||
if (nhu_pending[i])
|
||||
RT_LOCKED(nhu_pending[i], dst)
|
||||
rt_schedule_nhu(dst);
|
||||
}
|
||||
|
||||
static void
|
||||
rt_hcu_uncork(struct callback *cb)
|
||||
{
|
||||
SKIP_BACK_DECLARE(struct hostcache, hc, uncork, cb);
|
||||
hc->corked = 0;
|
||||
callback_activate(&hc->update);
|
||||
}
|
||||
|
||||
static struct hostentry *
|
||||
rt_get_hostentry(struct rtable_private *tab, ip_addr a, ip_addr ll, rtable *dep)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user