mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-23 02:01:55 +00:00
Next hop updater has its own event
This commit is contained in:
parent
a61a04b5c8
commit
e2c6120636
117
nest/rt-table.c
117
nest/rt-table.c
@ -130,7 +130,7 @@ struct rt_export_block {
|
|||||||
|
|
||||||
static void rt_free_hostcache(rtable *tab);
|
static void rt_free_hostcache(rtable *tab);
|
||||||
static void rt_update_hostcache(void *tab);
|
static void rt_update_hostcache(void *tab);
|
||||||
static void rt_next_hop_update(rtable *tab);
|
static void rt_next_hop_update(void *tab);
|
||||||
static inline void rt_next_hop_resolve_rte(rte *r);
|
static inline void rt_next_hop_resolve_rte(rte *r);
|
||||||
static inline void rt_flowspec_resolve_rte(rte *r, struct channel *c);
|
static inline void rt_flowspec_resolve_rte(rte *r, struct channel *c);
|
||||||
static inline void rt_prune_table(rtable *tab);
|
static inline void rt_prune_table(rtable *tab);
|
||||||
@ -2309,14 +2309,26 @@ rt_dump_hooks_all(void)
|
|||||||
static inline void
|
static inline void
|
||||||
rt_schedule_nhu(rtable *tab)
|
rt_schedule_nhu(rtable *tab)
|
||||||
{
|
{
|
||||||
if (tab->nhu_state == NHU_CLEAN)
|
if (tab->nhu_corked)
|
||||||
ev_schedule(tab->rt_event);
|
{
|
||||||
|
if (!(tab->nhu_corked & NHU_SCHEDULED))
|
||||||
|
{
|
||||||
|
tab->nhu_corked |= NHU_SCHEDULED;
|
||||||
|
rt_lock_table(tab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!(tab->nhu_state & NHU_SCHEDULED))
|
||||||
|
{
|
||||||
|
rt_trace(tab, D_EVENTS, "Scheduling NHU");
|
||||||
|
rt_lock_table(tab);
|
||||||
|
|
||||||
/* state change:
|
/* state change:
|
||||||
* NHU_CLEAN -> NHU_SCHEDULED
|
* NHU_CLEAN -> NHU_SCHEDULED
|
||||||
* NHU_RUNNING -> NHU_DIRTY
|
* NHU_RUNNING -> NHU_DIRTY
|
||||||
*/
|
*/
|
||||||
tab->nhu_state |= NHU_SCHEDULED;
|
if ((tab->nhu_state |= NHU_SCHEDULED) == NHU_SCHEDULED)
|
||||||
|
ev_schedule(tab->nhu_event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2353,43 +2365,12 @@ rt_event(void *ptr)
|
|||||||
if (tab->export_used)
|
if (tab->export_used)
|
||||||
rt_export_cleanup(tab);
|
rt_export_cleanup(tab);
|
||||||
|
|
||||||
if (tab->nhu_corked || tab->nhu_state && rt_cork_check(tab->uncork_event))
|
|
||||||
{
|
|
||||||
if (!tab->nhu_corked)
|
|
||||||
{
|
|
||||||
rt_trace(tab, D_STATES, "Next hop updater corked");
|
|
||||||
if ((tab->nhu_state & NHU_RUNNING)
|
|
||||||
&& !EMPTY_LIST(tab->exporter.pending)
|
|
||||||
&& !tm_active(tab->exporter.export_timer))
|
|
||||||
tm_start(tab->exporter.export_timer, tab->config->export_settle_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
tab->nhu_corked |= tab->nhu_state;
|
|
||||||
tab->nhu_state = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tab->nhu_state)
|
|
||||||
rt_next_hop_update(tab);
|
|
||||||
|
|
||||||
if (tab->prune_state)
|
if (tab->prune_state)
|
||||||
rt_prune_table(tab);
|
rt_prune_table(tab);
|
||||||
|
|
||||||
rt_unlock_table(tab);
|
rt_unlock_table(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
rt_uncork_event(void *ptr)
|
|
||||||
{
|
|
||||||
rtable *tab = ptr;
|
|
||||||
|
|
||||||
tab->nhu_state |= tab->nhu_corked;
|
|
||||||
tab->nhu_corked = 0;
|
|
||||||
|
|
||||||
rt_trace(tab, D_STATES, "Next hop updater uncorked");
|
|
||||||
|
|
||||||
ev_schedule(tab->rt_event);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rt_prune_timer(timer *t)
|
rt_prune_timer(timer *t)
|
||||||
{
|
{
|
||||||
@ -2619,7 +2600,7 @@ rt_setup(pool *pp, struct rtable_config *cf)
|
|||||||
hmap_set(&t->id_map, 0);
|
hmap_set(&t->id_map, 0);
|
||||||
|
|
||||||
t->rt_event = ev_new_init(p, rt_event, t);
|
t->rt_event = ev_new_init(p, rt_event, t);
|
||||||
t->uncork_event = ev_new_init(p, rt_uncork_event, t);
|
t->nhu_event = ev_new_init(p, rt_next_hop_update, t);
|
||||||
t->prune_timer = tm_new_init(p, rt_prune_timer, t, 0, 0);
|
t->prune_timer = tm_new_init(p, rt_prune_timer, t, 0, 0);
|
||||||
t->last_rt_change = t->gc_time = current_time();
|
t->last_rt_change = t->gc_time = current_time();
|
||||||
|
|
||||||
@ -3563,29 +3544,56 @@ rt_next_hop_update_net(rtable *tab, net *n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rt_next_hop_update(rtable *tab)
|
rt_next_hop_update(void *_tab)
|
||||||
{
|
{
|
||||||
|
rtable *tab = _tab;
|
||||||
|
|
||||||
|
/* If called from an uncork hook, reset the state */
|
||||||
|
if (tab->nhu_corked)
|
||||||
|
{
|
||||||
|
ASSERT_DIE(tab->nhu_state == 0);
|
||||||
|
tab->nhu_state = tab->nhu_corked;
|
||||||
|
tab->nhu_corked = 0;
|
||||||
|
rt_trace(tab, D_STATES, "Next hop updater uncorked");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tab->nhu_state)
|
||||||
|
bug("Called NHU event for no reason in table %s", tab->name);
|
||||||
|
|
||||||
|
/* Check corkedness */
|
||||||
|
if (rt_cork_check(tab->nhu_event))
|
||||||
|
{
|
||||||
|
rt_trace(tab, D_STATES, "Next hop updater corked");
|
||||||
|
if ((tab->nhu_state & NHU_RUNNING)
|
||||||
|
&& !EMPTY_LIST(tab->exporter.pending)
|
||||||
|
&& !tm_active(tab->exporter.export_timer))
|
||||||
|
tm_start(tab->exporter.export_timer, tab->config->export_settle_time);
|
||||||
|
|
||||||
|
tab->nhu_corked = tab->nhu_state;
|
||||||
|
tab->nhu_state = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
struct fib_iterator *fit = &tab->nhu_fit;
|
struct fib_iterator *fit = &tab->nhu_fit;
|
||||||
int max_feed = 32;
|
int max_feed = 32;
|
||||||
|
|
||||||
if (tab->nhu_state == NHU_CLEAN)
|
/* Initialize a new run */
|
||||||
return;
|
|
||||||
|
|
||||||
if (tab->nhu_state == NHU_SCHEDULED)
|
if (tab->nhu_state == NHU_SCHEDULED)
|
||||||
{
|
{
|
||||||
FIB_ITERATE_INIT(fit, &tab->fib);
|
FIB_ITERATE_INIT(fit, &tab->fib);
|
||||||
tab->nhu_state = NHU_RUNNING;
|
tab->nhu_state = NHU_RUNNING;
|
||||||
|
|
||||||
if (tab->flowspec_trie)
|
if (tab->flowspec_trie)
|
||||||
rt_flowspec_reset_trie(tab);
|
rt_flowspec_reset_trie(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Walk the fib one net after another */
|
||||||
FIB_ITERATE_START(&tab->fib, fit, net, n)
|
FIB_ITERATE_START(&tab->fib, fit, net, n)
|
||||||
{
|
{
|
||||||
if (max_feed <= 0)
|
if (max_feed <= 0)
|
||||||
{
|
{
|
||||||
FIB_ITERATE_PUT(fit);
|
FIB_ITERATE_PUT(fit);
|
||||||
ev_schedule(tab->rt_event);
|
ev_schedule(tab->nhu_event);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lp_state lps;
|
lp_state lps;
|
||||||
@ -3595,6 +3603,7 @@ rt_next_hop_update(rtable *tab)
|
|||||||
}
|
}
|
||||||
FIB_ITERATE_END;
|
FIB_ITERATE_END;
|
||||||
|
|
||||||
|
/* Finished NHU, cleanup */
|
||||||
rt_trace(tab, D_EVENTS, "NHU done, scheduling export timer");
|
rt_trace(tab, D_EVENTS, "NHU done, scheduling export timer");
|
||||||
|
|
||||||
if (!tm_active(tab->exporter.export_timer))
|
if (!tm_active(tab->exporter.export_timer))
|
||||||
@ -3604,10 +3613,10 @@ rt_next_hop_update(rtable *tab)
|
|||||||
* NHU_DIRTY -> NHU_SCHEDULED
|
* NHU_DIRTY -> NHU_SCHEDULED
|
||||||
* NHU_RUNNING -> NHU_CLEAN
|
* NHU_RUNNING -> NHU_CLEAN
|
||||||
*/
|
*/
|
||||||
tab->nhu_state &= 1;
|
if ((tab->nhu_state &= NHU_SCHEDULED) == NHU_SCHEDULED)
|
||||||
|
ev_schedule(tab->nhu_event);
|
||||||
|
|
||||||
if (tab->nhu_state != NHU_CLEAN)
|
rt_unlock_table(tab);
|
||||||
ev_schedule(tab->rt_event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -117,7 +117,7 @@ typedef struct rtable {
|
|||||||
* obstacle from this routing table.
|
* obstacle from this routing table.
|
||||||
*/
|
*/
|
||||||
struct event *rt_event; /* Routing table event */
|
struct event *rt_event; /* Routing table event */
|
||||||
struct event *uncork_event; /* Called when uncork happens */
|
struct event *nhu_event; /* Specific event for next hop update */
|
||||||
struct timer *prune_timer; /* Timer for periodic pruning / GC */
|
struct timer *prune_timer; /* Timer for periodic pruning / GC */
|
||||||
btime last_rt_change; /* Last time when route changed */
|
btime last_rt_change; /* Last time when route changed */
|
||||||
btime gc_time; /* Time of last GC */
|
btime gc_time; /* Time of last GC */
|
||||||
|
Loading…
Reference in New Issue
Block a user