mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-03-11 17:08:46 +00:00
Safer cleanup of table auxiliary routines
This commit is contained in:
parent
dda37842dc
commit
67875e76d9
@ -371,7 +371,6 @@ extern uint rtable_max_id;
|
|||||||
struct network * _Atomic routes; /* Actual route objects in the table */ \
|
struct network * _Atomic routes; /* Actual route objects in the table */ \
|
||||||
_Atomic u32 routes_block_size; /* Size of the route object pointer block */ \
|
_Atomic u32 routes_block_size; /* Size of the route object pointer block */ \
|
||||||
struct f_trie * _Atomic trie; /* Trie of prefixes defined in fib */ \
|
struct f_trie * _Atomic trie; /* Trie of prefixes defined in fib */ \
|
||||||
event *nhu_event; /* Nexthop updater */ \
|
|
||||||
event *hcu_event; /* Hostcache updater */ \
|
event *hcu_event; /* Hostcache updater */ \
|
||||||
struct rt_exporter export_all; /* Route export journal for all routes */ \
|
struct rt_exporter export_all; /* Route export journal for all routes */ \
|
||||||
struct rt_exporter export_best; /* Route export journal for best routes */ \
|
struct rt_exporter export_best; /* Route export journal for best routes */ \
|
||||||
@ -422,6 +421,7 @@ struct rtable_private {
|
|||||||
struct rt_cork_threshold cork_threshold; /* Threshold for table cork */
|
struct rt_cork_threshold cork_threshold; /* Threshold for table cork */
|
||||||
u32 prune_index; /* Rtable prune FIB iterator */
|
u32 prune_index; /* Rtable prune FIB iterator */
|
||||||
u32 nhu_index; /* Next Hop Update FIB iterator */
|
u32 nhu_index; /* Next Hop Update FIB iterator */
|
||||||
|
event *nhu_event; /* Nexthop updater */
|
||||||
struct f_trie *trie_new; /* New prefix trie defined during pruning */
|
struct f_trie *trie_new; /* New prefix trie defined during pruning */
|
||||||
const struct f_trie *trie_old; /* Old prefix trie waiting to be freed */
|
const struct f_trie *trie_old; /* Old prefix trie waiting to be freed */
|
||||||
u32 trie_lock_count; /* Prefix trie locked by walks */
|
u32 trie_lock_count; /* Prefix trie locked by walks */
|
||||||
|
@ -4123,6 +4123,7 @@ rt_nhu_uncork(callback *cb)
|
|||||||
rt_trace(tab, D_STATES, "Next hop updater uncorked");
|
rt_trace(tab, D_STATES, "Next hop updater uncorked");
|
||||||
|
|
||||||
ev_send_loop(tab->loop, tab->nhu_event);
|
ev_send_loop(tab->loop, tab->nhu_event);
|
||||||
|
rt_unlock_table(tab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4143,6 +4144,7 @@ rt_next_hop_update(void *_tab)
|
|||||||
if (rt_cork_check(&tab->nhu_uncork))
|
if (rt_cork_check(&tab->nhu_uncork))
|
||||||
{
|
{
|
||||||
rt_trace(tab, D_STATES, "Next hop updater corked");
|
rt_trace(tab, D_STATES, "Next hop updater corked");
|
||||||
|
rt_lock_table(tab);
|
||||||
|
|
||||||
if (tab->nhu_state & NHU_RUNNING)
|
if (tab->nhu_state & NHU_RUNNING)
|
||||||
{
|
{
|
||||||
@ -4353,10 +4355,17 @@ rt_shutdown(void *tab_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
rtex_export_unsubscribe(&tab->best_req);
|
rtex_export_unsubscribe(&tab->best_req);
|
||||||
|
if (tab->hostcache)
|
||||||
|
rtex_export_unsubscribe(&tab->hostcache->req);
|
||||||
|
|
||||||
rt_exporter_shutdown(&tab->export_best, NULL);
|
rt_exporter_shutdown(&tab->export_best, NULL);
|
||||||
rt_exporter_shutdown(&tab->export_all, NULL);
|
rt_exporter_shutdown(&tab->export_all, NULL);
|
||||||
|
|
||||||
|
rfree(tab->hcu_event);
|
||||||
|
tab->hcu_event = NULL;
|
||||||
|
rfree(tab->nhu_event);
|
||||||
|
tab->nhu_event = NULL;
|
||||||
|
|
||||||
netindex_hash_delete(tab->netindex,
|
netindex_hash_delete(tab->netindex,
|
||||||
ev_new_init(tab->rp, rt_shutdown_finished, tab),
|
ev_new_init(tab->rp, rt_shutdown_finished, tab),
|
||||||
birdloop_event_list(tab->loop));
|
birdloop_event_list(tab->loop));
|
||||||
@ -4503,18 +4512,8 @@ rt_commit(struct config *new, struct config *old)
|
|||||||
{
|
{
|
||||||
DBG("\t%s: deleted\n", o->name);
|
DBG("\t%s: deleted\n", o->name);
|
||||||
OBSREF_SET(tab->deleted, old);
|
OBSREF_SET(tab->deleted, old);
|
||||||
rt_lock_table(tab);
|
|
||||||
|
|
||||||
rt_check_cork_low(tab);
|
rt_check_cork_low(tab);
|
||||||
|
rt_lock_table(tab);
|
||||||
if (tab->hcu_event)
|
|
||||||
{
|
|
||||||
if (ev_get_list(tab->hcu_event) == &rt_cork.queue)
|
|
||||||
ev_postpone(tab->hcu_event);
|
|
||||||
|
|
||||||
rtex_export_unsubscribe(&tab->hostcache->req);
|
|
||||||
}
|
|
||||||
|
|
||||||
rt_unlock_table(tab);
|
rt_unlock_table(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4601,17 +4600,23 @@ hc_resize(struct hostcache *hc, pool *p, unsigned new_order)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct hostentry *
|
static struct hostentry *
|
||||||
hc_new_hostentry(struct hostcache *hc, pool *p, ip_addr a, ip_addr ll, rtable *dep, unsigned k)
|
hc_new_hostentry(struct rtable_private *tab, ip_addr a, ip_addr ll, rtable *dep, unsigned k)
|
||||||
{
|
{
|
||||||
|
struct hostcache *hc = tab->hostcache;
|
||||||
|
pool *p = tab->rp;
|
||||||
struct hostentry *he = sl_alloc(hc->slab);
|
struct hostentry *he = sl_alloc(hc->slab);
|
||||||
|
|
||||||
*he = (struct hostentry) {
|
*he = (struct hostentry) {
|
||||||
.addr = a,
|
.addr = a,
|
||||||
.link = ll,
|
.link = ll,
|
||||||
.tab = dep,
|
.tab = dep,
|
||||||
|
.owner = RT_PUB(tab),
|
||||||
.hash_key = k,
|
.hash_key = k,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (EMPTY_LIST(hc->hostentries))
|
||||||
|
rt_lock_table(tab);
|
||||||
|
|
||||||
add_tail(&hc->hostentries, &he->ln);
|
add_tail(&hc->hostentries, &he->ln);
|
||||||
hc_insert(hc, he);
|
hc_insert(hc, he);
|
||||||
|
|
||||||
@ -4749,13 +4754,7 @@ rt_free_hostcache(struct rtable_private *tab)
|
|||||||
|
|
||||||
node *n;
|
node *n;
|
||||||
WALK_LIST(n, hc->hostentries)
|
WALK_LIST(n, hc->hostentries)
|
||||||
{
|
bug("Hostcache is not empty in table %s", tab->name);
|
||||||
SKIP_BACK_DECLARE(struct hostentry, he, ln, n);
|
|
||||||
ea_free(atomic_load_explicit(&he->src, memory_order_relaxed));
|
|
||||||
|
|
||||||
if (!lfuc_finished(&he->uc))
|
|
||||||
log(L_ERR "Hostcache is not empty in table %s", tab->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Freed automagically by the resource pool
|
/* Freed automagically by the resource pool
|
||||||
rfree(hc->slab);
|
rfree(hc->slab);
|
||||||
@ -4891,7 +4890,8 @@ done:
|
|||||||
static void
|
static void
|
||||||
rt_hcu_uncork(callback *cb)
|
rt_hcu_uncork(callback *cb)
|
||||||
{
|
{
|
||||||
SKIP_BACK_DECLARE(rtable, tab, priv.hcu_uncork.cb, cb);
|
RT_LOCK(SKIP_BACK(rtable, priv.hcu_uncork.cb, cb), tab);
|
||||||
|
|
||||||
ev_send_loop(tab->loop, tab->hcu_event);
|
ev_send_loop(tab->loop, tab->hcu_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4945,19 +4945,29 @@ rt_update_hostcache(void *data)
|
|||||||
lp_flush(hc->lp);
|
lp_flush(hc->lp);
|
||||||
hc->trie = f_new_trie(hc->lp, 0);
|
hc->trie = f_new_trie(hc->lp, 0);
|
||||||
|
|
||||||
|
uint finished = 0, updated = 0, kept = 0;
|
||||||
|
|
||||||
WALK_LIST_DELSAFE(n, x, hc->hostentries)
|
WALK_LIST_DELSAFE(n, x, hc->hostentries)
|
||||||
{
|
{
|
||||||
he = SKIP_BACK(struct hostentry, ln, n);
|
he = SKIP_BACK(struct hostentry, ln, n);
|
||||||
if (lfuc_finished(&he->uc))
|
if (lfuc_finished(&he->uc))
|
||||||
{
|
{
|
||||||
hc_delete_hostentry(hc, tab->rp, he);
|
hc_delete_hostentry(hc, tab->rp, he);
|
||||||
continue;
|
finished++;
|
||||||
}
|
}
|
||||||
|
else if (rt_update_hostentry(tab, he))
|
||||||
if (rt_update_hostentry(tab, he))
|
{
|
||||||
nhu_pending[he->tab->id] = he->tab;
|
nhu_pending[he->tab->id] = he->tab;
|
||||||
|
updated++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
kept++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (finished && !updated && !kept)
|
||||||
|
rt_unlock_table(tab);
|
||||||
|
|
||||||
|
} /* End of RT_LOCKED() */
|
||||||
|
|
||||||
for (uint i=0; i<rtable_max_id; i++)
|
for (uint i=0; i<rtable_max_id; i++)
|
||||||
if (nhu_pending[i])
|
if (nhu_pending[i])
|
||||||
@ -4992,8 +5002,7 @@ rt_get_hostentry(struct rtable_private *tab, ip_addr a, ip_addr ll, rtable *dep)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
he = hc_new_hostentry(hc, tab->rp, a, link, dep, k);
|
he = hc_new_hostentry(tab, a, link, dep, k);
|
||||||
he->owner = RT_PUB(tab);
|
|
||||||
rt_update_hostentry(tab, he);
|
rt_update_hostentry(tab, he);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user