diff options
Diffstat (limited to 'zebra/zebra_rib.c')
| -rw-r--r-- | zebra/zebra_rib.c | 157 |
1 files changed, 96 insertions, 61 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 3445136d1f..8afcc2b685 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -163,7 +163,7 @@ int is_zebra_valid_kernel_table(uint32_t table_id) int is_zebra_main_routing_table(uint32_t table_id) { if ((table_id == RT_TABLE_MAIN) - || (table_id == zebrad.rtm_table_default)) + || (table_id == zrouter.rtm_table_default)) return 1; return 0; } @@ -437,6 +437,14 @@ static int nexthop_active(afi_t afi, struct route_entry *re, if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_EVPN_RVTEP)) return 1; + /* + * If the kernel has sent us a route, then + * by golly gee whiz it's a good route. + */ + if (re->type == ZEBRA_ROUTE_KERNEL || + re->type == ZEBRA_ROUTE_SYSTEM) + return 1; + /* Skip nexthops that have been filtered out due to route-map */ /* The nexthops are specific to this route and so the same */ /* nexthop for a different route may not have this flag set */ @@ -600,6 +608,9 @@ static int nexthop_active(afi_t afi, struct route_entry *re, if (!CHECK_FLAG(match->status, ROUTE_ENTRY_INSTALLED)) continue; + if (CHECK_FLAG(newhop->flags, + NEXTHOP_FLAG_RECURSIVE)) + continue; if (set) { SET_FLAG(nexthop->flags, @@ -1078,7 +1089,7 @@ void rib_install_kernel(struct route_node *rn, struct route_entry *re, hook_call(rib_update, rn, "installing in kernel"); /* Send add or update */ - if (old && (old != re)) + if (old) ret = dplane_route_update(rn, re, old); else ret = dplane_route_add(rn, re); @@ -1266,8 +1277,9 @@ static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn, if (IS_ZEBRA_DEBUG_RIB) { char buf[SRCDEST2STR_BUFFER]; srcdest_rnode2str(rn, buf, sizeof(buf)); - zlog_debug("%u:%s: Adding route rn %p, re %p (type %d)", - zvrf_id(zvrf), buf, rn, new, new->type); + zlog_debug("%u:%s: Adding route rn %p, re %p (%s)", + zvrf_id(zvrf), buf, rn, new, + zebra_route_string(new->type)); } /* If labeled-unicast route, install transit LSP. */ @@ -1292,8 +1304,9 @@ static void rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn, if (IS_ZEBRA_DEBUG_RIB) { char buf[SRCDEST2STR_BUFFER]; srcdest_rnode2str(rn, buf, sizeof(buf)); - zlog_debug("%u:%s: Deleting route rn %p, re %p (type %d)", - zvrf_id(zvrf), buf, rn, old, old->type); + zlog_debug("%u:%s: Deleting route rn %p, re %p (%s)", + zvrf_id(zvrf), buf, rn, old, + zebra_route_string(old->type)); } /* If labeled-unicast route, uninstall transit LSP. */ @@ -1360,15 +1373,16 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf, srcdest_rnode2str(rn, buf, sizeof(buf)); if (new != old) zlog_debug( - "%u:%s: Updating route rn %p, re %p (type %d) " - "old %p (type %d)", + "%u:%s: Updating route rn %p, re %p (%s) old %p (%s)", zvrf_id(zvrf), buf, rn, new, - new->type, old, old->type); + zebra_route_string(new->type), + old, + zebra_route_string(old->type)); else zlog_debug( - "%u:%s: Updating route rn %p, re %p (type %d)", + "%u:%s: Updating route rn %p, re %p (%s)", zvrf_id(zvrf), buf, rn, new, - new->type); + zebra_route_string(new->type)); } /* If labeled-unicast route, uninstall transit LSP. */ @@ -1430,15 +1444,16 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf, srcdest_rnode2str(rn, buf, sizeof(buf)); if (new != old) zlog_debug( - "%u:%s: Deleting route rn %p, re %p (type %d) " - "old %p (type %d) - nexthop inactive", + "%u:%s: Deleting route rn %p, re %p (%s) old %p (%s) - nexthop inactive", zvrf_id(zvrf), buf, rn, new, - new->type, old, old->type); + zebra_route_string(new->type), + old, + zebra_route_string(old->type)); else zlog_debug( - "%u:%s: Deleting route rn %p, re %p (type %d) - nexthop inactive", + "%u:%s: Deleting route rn %p, re %p (%s) - nexthop inactive", zvrf_id(zvrf), buf, rn, new, - new->type); + zebra_route_string(new->type)); } /* If labeled-unicast route, uninstall transit LSP. */ @@ -1583,10 +1598,10 @@ static void rib_process(struct route_node *rn) RNODE_FOREACH_RE_SAFE (rn, re, next) { if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug( - "%u:%s: Examine re %p (type %d) status %x flags %x " - "dist %d metric %d", - vrf_id, buf, re, re->type, re->status, - re->flags, re->distance, re->metric); + "%u:%s: Examine re %p (%s) status %x flags %x dist %d metric %d", + vrf_id, buf, re, zebra_route_string(re->type), + re->status, re->flags, re->distance, + re->metric); UNSET_FLAG(re->status, ROUTE_ENTRY_NEXTHOPS_CHANGED); @@ -2140,14 +2155,6 @@ static void do_nht_processing(void) } } -/* - * All meta queues have been processed. Trigger next-hop evaluation. - */ -static void meta_queue_process_complete(struct work_queue *dummy) -{ - do_nht_processing(); -} - /* Dispatch the meta queue by picking, processing and unlocking the next RN from * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and * data @@ -2168,8 +2175,8 @@ static wq_item_status meta_queue_process(struct work_queue *dummy, void *data) queue_len, queue_limit); /* Ensure that the meta-queue is actually enqueued */ - if (work_queue_empty(zebrad.ribq)) - work_queue_add(zebrad.ribq, zebrad.mq); + if (work_queue_empty(zrouter.ribq)) + work_queue_add(zrouter.ribq, zrouter.mq); return WQ_QUEUE_BLOCKED; } @@ -2258,7 +2265,7 @@ void rib_queue_add(struct route_node *rn) return; } - if (zebrad.ribq == NULL) { + if (zrouter.ribq == NULL) { flog_err(EC_ZEBRA_WQ_NONEXISTENT, "%s: work_queue does not exist!", __func__); return; @@ -2272,10 +2279,10 @@ void rib_queue_add(struct route_node *rn) * holder, if necessary, then push the work into it in any case. * This semantics was introduced after 0.99.9 release. */ - if (work_queue_empty(zebrad.ribq)) - work_queue_add(zebrad.ribq, zebrad.mq); + if (work_queue_empty(zrouter.ribq)) + work_queue_add(zrouter.ribq, zrouter.mq); - rib_meta_queue_add(zebrad.mq, rn); + rib_meta_queue_add(zrouter.mq, rn); return; } @@ -2309,27 +2316,25 @@ void meta_queue_free(struct meta_queue *mq) } /* initialise zebra rib work queue */ -static void rib_queue_init(struct zebra_t *zebra) +static void rib_queue_init(void) { - assert(zebra); - - if (!(zebra->ribq = - work_queue_new(zebra->master, "route_node processing"))) { + if (!(zrouter.ribq = work_queue_new(zrouter.master, + "route_node processing"))) { flog_err(EC_ZEBRA_WQ_NONEXISTENT, "%s: could not initialise work queue!", __func__); return; } /* fill in the work queue spec */ - zebra->ribq->spec.workfunc = &meta_queue_process; - zebra->ribq->spec.errorfunc = NULL; - zebra->ribq->spec.completion_func = &meta_queue_process_complete; + zrouter.ribq->spec.workfunc = &meta_queue_process; + zrouter.ribq->spec.errorfunc = NULL; + zrouter.ribq->spec.completion_func = NULL; /* XXX: TODO: These should be runtime configurable via vty */ - zebra->ribq->spec.max_retries = 3; - zebra->ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME; - zebra->ribq->spec.retry = ZEBRA_RIB_PROCESS_RETRY_TIME; + zrouter.ribq->spec.max_retries = 3; + zrouter.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME; + zrouter.ribq->spec.retry = ZEBRA_RIB_PROCESS_RETRY_TIME; - if (!(zebra->mq = meta_queue_new())) { + if (!(zrouter.mq = meta_queue_new())) { flog_err(EC_ZEBRA_WQ_NONEXISTENT, "%s: could not initialise meta queue!", __func__); return; @@ -2484,9 +2489,9 @@ void rib_delnode(struct route_node *rn, struct route_entry *re) if (IS_ZEBRA_DEBUG_RIB) { char buf[SRCDEST2STR_BUFFER]; srcdest_rnode2str(rn, buf, sizeof(buf)); - zlog_debug( - "%u:%s: Freeing route rn %p, re %p (type %d)", - re->vrf_id, buf, rn, re, re->type); + zlog_debug("%u:%s: Freeing route rn %p, re %p (%s)", + re->vrf_id, buf, rn, re, + zebra_route_string(re->type)); } rib_unlink(rn, re); @@ -2746,10 +2751,9 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, /* Link new re to node.*/ if (IS_ZEBRA_DEBUG_RIB) { - rnode_debug( - rn, re->vrf_id, - "Inserting route rn %p, re %p (type %d) existing %p", - (void *)rn, (void *)re, re->type, (void *)same); + rnode_debug(rn, re->vrf_id, + "Inserting route rn %p, re %p (%s) existing %p", + rn, re, zebra_route_string(re->type), same); if (IS_ZEBRA_DEBUG_RIB_DETAILED) route_entry_dump(p, src_p, re); @@ -2873,10 +2877,10 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, */ if (fib && CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE)) { if (IS_ZEBRA_DEBUG_RIB) { - rnode_debug( - rn, vrf_id, - "rn %p, re %p (type %d) was deleted from kernel, adding", - rn, fib, fib->type); + rnode_debug(rn, vrf_id, + "rn %p, re %p (%s) was deleted from kernel, adding", + rn, fib, + zebra_route_string(fib->type)); } if (allow_delete) { UNSET_FLAG(fib->status, ROUTE_ENTRY_INSTALLED); @@ -3225,6 +3229,34 @@ void rib_close_table(struct route_table *table) } /* + * Handler for async dataplane results after a pseudowire installation + */ +static int handle_pw_result(struct zebra_dplane_ctx *ctx) +{ + int ret = 0; + struct zebra_pw *pw; + struct zebra_vrf *vrf; + + /* The pseudowire code assumes success - we act on an error + * result for installation attempts here. + */ + if (dplane_ctx_get_op(ctx) != DPLANE_OP_PW_INSTALL) + goto done; + + if (dplane_ctx_get_status(ctx) != ZEBRA_DPLANE_REQUEST_SUCCESS) { + vrf = zebra_vrf_lookup_by_id(dplane_ctx_get_vrf(ctx)); + pw = zebra_pw_find(vrf, dplane_ctx_get_pw_ifname(ctx)); + if (pw) + zebra_pw_install_failure(pw); + } + +done: + + return ret; +} + + +/* * Handle results from the dataplane system. Dequeue update context * structs, dispatch to appropriate internal handlers. */ @@ -3235,8 +3267,6 @@ static int rib_process_dplane_results(struct thread *thread) /* Dequeue a list of completed updates with one lock/unlock cycle */ - /* TODO -- dequeue a list with one lock/unlock cycle? */ - do { TAILQ_INIT(&ctxlist); @@ -3269,6 +3299,11 @@ static int rib_process_dplane_results(struct thread *thread) zebra_mpls_lsp_dplane_result(ctx); break; + case DPLANE_OP_PW_INSTALL: + case DPLANE_OP_PW_UNINSTALL: + handle_pw_result(ctx); + break; + default: /* Don't expect this: just return the struct? */ dplane_ctx_fini(&ctx); @@ -3302,7 +3337,7 @@ static int rib_dplane_results(struct dplane_ctx_q *ctxlist) pthread_mutex_unlock(&dplane_mutex); /* Ensure event is signalled to zebra main pthread */ - thread_add_event(zebrad.master, rib_process_dplane_results, NULL, 0, + thread_add_event(zrouter.master, rib_process_dplane_results, NULL, 0, &t_dplane); return 0; @@ -3311,7 +3346,7 @@ static int rib_dplane_results(struct dplane_ctx_q *ctxlist) /* Routing information base initialize. */ void rib_init(void) { - rib_queue_init(&zebrad); + rib_queue_init(); /* Init dataplane, and register for results */ pthread_mutex_init(&dplane_mutex, NULL); |
