diff --git a/nest/route.h b/nest/route.h index cc39cb92..e5811706 100644 --- a/nest/route.h +++ b/nest/route.h @@ -110,6 +110,7 @@ extern uint rtable_max_id; 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 { @@ -182,6 +183,7 @@ LOBJ_UNLOCK_CLEANUP(rtable, rtable); #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) @@ -192,7 +194,6 @@ LOBJ_UNLOCK_CLEANUP(rtable, rtable); /* Flags for birdloop_flag() */ #define RTF_CLEANUP 1 -#define RTF_NHU 2 #define RTF_EXPORT 4 #define RTF_DELETE 8 diff --git a/nest/rt-table.c b/nest/rt-table.c index b3809d24..8dcf8e1b 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -138,7 +138,7 @@ struct rt_export_block { 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); @@ -2479,7 +2479,7 @@ rt_schedule_nhu(struct rtable_private *tab) * 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); } } @@ -2516,9 +2516,6 @@ rt_flag_handler(struct birdloop_flag_handler *fh, u32 flags) 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); @@ -2845,6 +2842,7 @@ rt_setup(pool *pp, struct rtable_config *cf) 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(); @@ -3854,13 +3852,15 @@ rt_nhu_uncork(void *_tab) 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) @@ -3903,7 +3903,7 @@ rt_next_hop_update(struct rtable_private *tab) if (max_feed <= 0) { - birdloop_flag(tab->loop, RTF_NHU); + ev_send_loop(tab->loop, tab->nhu_event); return; } @@ -3920,7 +3920,7 @@ rt_next_hop_update(struct rtable_private *tab) * 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