summaryrefslogtreecommitdiff
path: root/zebra/zebra_rib.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_rib.c')
-rw-r--r--zebra/zebra_rib.c157
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);