struct rtable_config *config; /* Configuration of this table */ \
struct birdloop *loop; /* Service thread */ \
netindex_hash *netindex; /* Prefix index for this table */ \
+ event *nhu_event; /* Nexthop updater */ \
/* The complete rtable structure */
struct rtable_private {
#define RT_IS_LOCKED(tab) LOBJ_IS_LOCKED((tab), rtable)
#define RT_LOCKED(tab, tp) LOBJ_LOCKED((tab), tp, rtable, rtable)
+#define RT_LOCK(tab, tp) LOBJ_LOCK((tab), tp, rtable, rtable)
#define RT_LOCK_SIMPLE(tab) LOBJ_LOCK_SIMPLE((tab), rtable)
#define RT_UNLOCK_SIMPLE(tab) LOBJ_UNLOCK_SIMPLE((tab), rtable)
/* Flags for birdloop_flag() */
#define RTF_CLEANUP 1
-#define RTF_NHU 2
#define RTF_EXPORT 4
#define RTF_DELETE 8
static void rt_free_hostcache(struct rtable_private *tab);
static void rt_update_hostcache(void *tab);
-static void rt_next_hop_update(struct rtable_private *tab);
+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);
static inline void rt_flowspec_resolve_rte(rte *r, struct channel *c);
* NHU_RUNNING -> NHU_DIRTY
*/
if ((tab->nhu_state |= NHU_SCHEDULED) == NHU_SCHEDULED)
- birdloop_flag(tab->loop, RTF_NHU);
+ ev_send_loop(tab->loop, tab->nhu_event);
}
}
ASSERT_DIE(birdloop_inside(tab->loop));
rt_lock_table(tab);
- if (flags & RTF_NHU)
- rt_next_hop_update(tab);
-
if (flags & RTF_EXPORT)
rt_kick_export_settle(tab);
hmap_set(&t->id_map, 0);
t->fh = (struct birdloop_flag_handler) { .hook = rt_flag_handler, };
+ t->nhu_event = ev_new_init(p, rt_next_hop_update, t);
t->nhu_uncork_event = ev_new_init(p, rt_nhu_uncork, t);
t->prune_timer = tm_new_init(p, rt_prune_timer, t, 0, 0);
t->last_rt_change = t->gc_time = current_time();
tab->nhu_corked = 0;
rt_trace(tab, D_STATES, "Next hop updater uncorked");
- birdloop_flag(tab->loop, RTF_NHU);
+ ev_send_loop(tab->loop, tab->nhu_event);
}
}
static void
-rt_next_hop_update(struct rtable_private *tab)
+rt_next_hop_update(void *_tab)
{
+ RT_LOCK((rtable *) _tab, tab);
+
ASSERT_DIE(birdloop_inside(tab->loop));
if (tab->nhu_corked)
if (max_feed <= 0)
{
- birdloop_flag(tab->loop, RTF_NHU);
+ ev_send_loop(tab->loop, tab->nhu_event);
return;
}
* NHU_RUNNING -> NHU_CLEAN
*/
if ((tab->nhu_state &= NHU_SCHEDULED) == NHU_SCHEDULED)
- birdloop_flag(tab->loop, RTF_NHU);
+ ev_send_loop(tab->loop, tab->nhu_event);
}
void