diff options
Diffstat (limited to 'zebra/zebra_rib.c')
| -rw-r--r-- | zebra/zebra_rib.c | 91 |
1 files changed, 90 insertions, 1 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 7a9d0c0ed6..32cfa4d04c 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -64,7 +64,12 @@ DEFINE_HOOK(rib_update, (struct route_node * rn, const char *reason), DEFINE_HOOK(rib_shutdown, (struct route_node * rn), (rn)); -/* Meta Q's specific names */ +/* + * Meta Q's specific names + * + * If you add something here ensure that you + * change MQ_SIZE as well over in rib.h + */ enum meta_queue_indexes { META_QUEUE_NHG, META_QUEUE_EVPN, @@ -76,6 +81,7 @@ enum meta_queue_indexes { META_QUEUE_NOTBGP, META_QUEUE_BGP, META_QUEUE_OTHER, + META_QUEUE_GR_RUN, }; /* Each route type's string and default distance value. */ @@ -250,6 +256,8 @@ static const char *subqueue2str(enum meta_queue_indexes index) return "BGP Routes"; case META_QUEUE_OTHER: return "Other Routes"; + case META_QUEUE_GR_RUN: + return "Graceful Restart"; } return "Unknown"; @@ -3089,6 +3097,23 @@ static void process_subq_early_route(struct listnode *lnode) process_subq_early_route_add(ere); } +struct meta_q_gr_run { + afi_t afi; + vrf_id_t vrf_id; + uint8_t proto; + uint8_t instance; +}; + +static void process_subq_gr_run(struct listnode *lnode) +{ + struct meta_q_gr_run *gr_run = listgetdata(lnode); + + zebra_gr_process_client(gr_run->afi, gr_run->vrf_id, gr_run->proto, + gr_run->instance); + + XFREE(MTYPE_WQ_WRAPPER, gr_run); +} + /* * Examine the specified subqueue; process one entry and return 1 if * there is a node, return 0 otherwise. @@ -3122,6 +3147,9 @@ static unsigned int process_subq(struct list *subq, case META_QUEUE_OTHER: process_subq_route(lnode, qindex); break; + case META_QUEUE_GR_RUN: + process_subq_gr_run(lnode); + break; } list_delete_node(subq, lnode); @@ -3727,6 +3755,20 @@ static void early_route_meta_queue_free(struct meta_queue *mq, struct list *l, } } +static void rib_meta_queue_gr_run_free(struct meta_queue *mq, struct list *l, + struct zebra_vrf *zvrf) +{ + struct meta_q_gr_run *gr_run; + struct listnode *node, *nnode; + + for (ALL_LIST_ELEMENTS(l, node, nnode, gr_run)) { + if (zvrf && zvrf->vrf->vrf_id != gr_run->vrf_id) + continue; + + XFREE(MTYPE_WQ_WRAPPER, gr_run); + } +} + void meta_queue_free(struct meta_queue *mq, struct zebra_vrf *zvrf) { enum meta_queue_indexes i; @@ -3754,6 +3796,9 @@ void meta_queue_free(struct meta_queue *mq, struct zebra_vrf *zvrf) case META_QUEUE_OTHER: rib_meta_queue_free(mq, mq->subq[i], zvrf); break; + case META_QUEUE_GR_RUN: + rib_meta_queue_gr_run_free(mq, mq->subq[i], zvrf); + break; } if (!zvrf) list_delete(&mq->subq[i]); @@ -4094,6 +4139,17 @@ void _route_entry_dump(const char *func, union prefixconstptr pp, zlog_debug("%s: dump complete", straddr); } +static int rib_meta_queue_gr_run_add(struct meta_queue *mq, void *data) +{ + listnode_add(mq->subq[META_QUEUE_GR_RUN], data); + mq->size++; + + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug("Graceful Run adding"); + + return 0; +} + static int rib_meta_queue_early_route_add(struct meta_queue *mq, void *data) { struct zebra_early_route *ere = data; @@ -4110,6 +4166,20 @@ static int rib_meta_queue_early_route_add(struct meta_queue *mq, void *data) return 0; } +int rib_add_gr_run(afi_t afi, vrf_id_t vrf_id, uint8_t proto, uint8_t instance) +{ + struct meta_q_gr_run *gr_run; + + gr_run = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(*gr_run)); + + gr_run->afi = afi; + gr_run->proto = proto; + gr_run->vrf_id = vrf_id; + gr_run->instance = instance; + + return mq_add_handler(gr_run, rib_meta_queue_gr_run_add); +} + struct route_entry *zebra_rib_route_entry_new(vrf_id_t vrf_id, int type, uint8_t instance, uint32_t flags, uint32_t nhe_id, @@ -4410,6 +4480,22 @@ static void rib_update_handler(struct event *thread) */ static struct event *t_rib_update_threads[RIB_UPDATE_MAX]; +void rib_update_finish(void) +{ + int i; + + for (i = RIB_UPDATE_KERNEL; i < RIB_UPDATE_MAX; i++) { + if (event_is_scheduled(t_rib_update_threads[i])) { + struct rib_update_ctx *ctx; + + ctx = EVENT_ARG(t_rib_update_threads[i]); + + rib_update_ctx_fini(&ctx); + EVENT_OFF(t_rib_update_threads[i]); + } + } +} + /* Schedule a RIB update event for all vrfs */ void rib_update(enum rib_update_event event) { @@ -4418,6 +4504,9 @@ void rib_update(enum rib_update_event event) if (event_is_scheduled(t_rib_update_threads[event])) return; + if (zebra_router_in_shutdown()) + return; + ctx = rib_update_ctx_init(0, event); event_add_event(zrouter.master, rib_update_handler, ctx, 0, |
