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.c200
1 files changed, 126 insertions, 74 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index d1d56f2cdb..ff30de18a3 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -120,6 +120,7 @@ _rnode_zlog(const char *_func, vrf_id_t vrf_id, struct route_node *rn,
char buf[SRCDEST2STR_BUFFER + sizeof(" (MRIB)")];
char msgbuf[512];
va_list ap;
+ uint32_t table = 0;
va_start(ap, msgfmt);
vsnprintf(msgbuf, sizeof(msgbuf), msgfmt, ap);
@@ -127,15 +128,24 @@ _rnode_zlog(const char *_func, vrf_id_t vrf_id, struct route_node *rn,
if (rn) {
struct rib_table_info *info = srcdest_rnode_table_info(rn);
+ rib_dest_t *dest = NULL;
+ struct route_entry *re = NULL;
+
srcdest_rnode2str(rn, buf, sizeof(buf));
if (info->safi == SAFI_MULTICAST)
strlcat(buf, " (MRIB)", sizeof(buf));
+
+ dest = rib_dest_from_rnode(rn);
+ if (dest)
+ re = re_list_first(&dest->routes);
+ if (re)
+ table = re->table;
} else {
snprintf(buf, sizeof(buf), "{(route_node *) NULL}");
}
- zlog(priority, "%s: %d:%s: %s", _func, vrf_id, buf, msgbuf);
+ zlog(priority, "%s: (%u:%u):%s: %s", _func, vrf_id, table, buf, msgbuf);
}
#define rnode_debug(node, vrf_id, ...) \
@@ -489,8 +499,8 @@ void rib_install_kernel(struct route_node *rn, struct route_entry *re,
srcdest_rnode2str(rn, str, sizeof(str));
flog_err(EC_ZEBRA_DP_INSTALL_FAIL,
- "%u:%s: Failed to enqueue dataplane install",
- re->vrf_id, str);
+ "%u:%u:%s: Failed to enqueue dataplane install",
+ re->vrf_id, re->table, str);
break;
}
case ZEBRA_DPLANE_REQUEST_SUCCESS:
@@ -758,9 +768,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("%s(%u):%s: Adding route rn %p, re %p (%s)",
- zvrf_name(zvrf), zvrf_id(zvrf), buf, rn, new,
- zebra_route_string(new->type));
+ zlog_debug("%s(%u:%u):%s: Adding route rn %p, re %p (%s)",
+ zvrf_name(zvrf), zvrf_id(zvrf), new->table, buf, rn,
+ new, zebra_route_string(new->type));
}
/* If labeled-unicast route, install transit LSP. */
@@ -781,9 +791,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("%s(%u):%s: Deleting route rn %p, re %p (%s)",
- zvrf_name(zvrf), zvrf_id(zvrf), buf, rn, old,
- zebra_route_string(old->type));
+ zlog_debug("%s(%u:%u):%s: Deleting route rn %p, re %p (%s)",
+ zvrf_name(zvrf), zvrf_id(zvrf), old->table, buf, rn,
+ old, zebra_route_string(old->type));
}
/* If labeled-unicast route, uninstall transit LSP. */
@@ -834,17 +844,17 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
srcdest_rnode2str(rn, buf, sizeof(buf));
if (new != old)
zlog_debug(
- "%s(%u):%s: Updating route rn %p, re %p (%s) old %p (%s)",
+ "%s(%u:%u):%s: Updating route rn %p, re %p (%s) old %p (%s)",
zvrf_name(zvrf), zvrf_id(zvrf),
- buf, rn, new,
+ new->table, buf, rn, new,
zebra_route_string(new->type),
old,
zebra_route_string(old->type));
else
zlog_debug(
- "%s(%u):%s: Updating route rn %p, re %p (%s)",
+ "%s(%u:%u):%s: Updating route rn %p, re %p (%s)",
zvrf_name(zvrf), zvrf_id(zvrf),
- buf, rn, new,
+ new->table, buf, rn, new,
zebra_route_string(new->type));
}
@@ -874,17 +884,17 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
srcdest_rnode2str(rn, buf, sizeof(buf));
if (new != old)
zlog_debug(
- "%s(%u):%s: Deleting route rn %p, re %p (%s) old %p (%s) - nexthop inactive",
+ "%s(%u:%u):%s: Deleting route rn %p, re %p (%s) old %p (%s) - nexthop inactive",
zvrf_name(zvrf), zvrf_id(zvrf),
- buf, rn, new,
+ new->table, buf, rn, new,
zebra_route_string(new->type),
old,
zebra_route_string(old->type));
else
zlog_debug(
- "%s(%u):%s: Deleting route rn %p, re %p (%s) - nexthop inactive",
+ "%s(%u:%u):%s: Deleting route rn %p, re %p (%s) - nexthop inactive",
zvrf_name(zvrf), zvrf_id(zvrf),
- buf, rn, new,
+ new->table, buf, rn, new,
zebra_route_string(new->type));
}
@@ -1018,24 +1028,29 @@ static void rib_process(struct route_node *rn)
if (IS_ZEBRA_DEBUG_RIB)
srcdest_rnode2str(rn, buf, sizeof(buf));
- if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug("%s(%u):%s: Processing rn %p", VRF_LOGNAME(vrf),
- vrf_id, buf, rn);
-
/*
* we can have rn's that have a NULL info pointer
* (dest). As such let's not let the deref happen
* additionally we know RNODE_FOREACH_RE_SAFE
* will not iterate so we are ok.
*/
- if (dest)
+ if (dest) {
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
+ struct route_entry *re = re_list_first(&dest->routes);
+
+ zlog_debug("%s(%u:%u):%s: Processing rn %p",
+ VRF_LOGNAME(vrf), vrf_id, re->table, buf,
+ rn);
+ }
+
old_fib = dest->selected_fib;
+ }
RNODE_FOREACH_RE_SAFE (rn, re, next) {
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
zlog_debug(
- "%s(%u):%s: Examine re %p (%s) status %x flags %x dist %d metric %d",
- VRF_LOGNAME(vrf), vrf_id, buf, re,
+ "%s(%u:%u):%s: Examine re %p (%s) status %x flags %x dist %d metric %d",
+ VRF_LOGNAME(vrf), vrf_id, re->table, buf, re,
zebra_route_string(re->type), re->status,
re->flags, re->distance, re->metric);
@@ -1131,10 +1146,20 @@ static void rib_process(struct route_node *rn)
*/
if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
+ struct route_entry *entry;
+
+ entry = old_selected
+ ? old_selected
+ : new_selected
+ ? new_selected
+ : old_fib ? old_fib
+ : new_fib ? new_fib : NULL;
+
zlog_debug(
- "%s(%u):%s: After processing: old_selected %p new_selected %p old_fib %p new_fib %p",
- VRF_LOGNAME(vrf), vrf_id, buf, (void *)old_selected,
- (void *)new_selected, (void *)old_fib, (void *)new_fib);
+ "%s(%u:%u):%s: After processing: old_selected %p new_selected %p old_fib %p new_fib %p",
+ VRF_LOGNAME(vrf), vrf_id, entry ? entry->table : 0, buf,
+ (void *)old_selected, (void *)new_selected,
+ (void *)old_fib, (void *)new_fib);
}
/* Buffer ROUTE_ENTRY_CHANGED here, because it will get cleared if
@@ -1456,8 +1481,8 @@ static bool rib_update_re_from_ctx(struct route_entry *re,
is_selected = (re == dest->selected_fib);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug("update_from_ctx: %s(%u):%s: %sSELECTED, re %p",
- VRF_LOGNAME(vrf), re->vrf_id, dest_str,
+ zlog_debug("update_from_ctx: %s(%u:%u):%s: %sSELECTED, re %p",
+ VRF_LOGNAME(vrf), re->vrf_id, re->table, dest_str,
(is_selected ? "" : "NOT "), re);
/* Update zebra's nexthop FIB flag for each nexthop that was installed.
@@ -1483,8 +1508,9 @@ static bool rib_update_re_from_ctx(struct route_entry *re,
if (matched) {
if (IS_ZEBRA_DEBUG_RIB)
zlog_debug(
- "%s(%u):%s update_from_ctx(): existing fib nhg, no change",
- VRF_LOGNAME(vrf), re->vrf_id, dest_str);
+ "%s(%u:%u):%s update_from_ctx(): existing fib nhg, no change",
+ VRF_LOGNAME(vrf), re->vrf_id, re->table,
+ dest_str);
goto check_backups;
} else if (CHECK_FLAG(re->status, ROUTE_ENTRY_USE_FIB_NHG)) {
@@ -1493,8 +1519,9 @@ static bool rib_update_re_from_ctx(struct route_entry *re,
*/
if (IS_ZEBRA_DEBUG_RIB)
zlog_debug(
- "%s(%u):%s update_from_ctx(): replacing fib nhg",
- VRF_LOGNAME(vrf), re->vrf_id, dest_str);
+ "%s(%u:%u):%s update_from_ctx(): replacing fib nhg",
+ VRF_LOGNAME(vrf), re->vrf_id, re->table,
+ dest_str);
nexthops_free(re->fib_ng.nexthop);
re->fib_ng.nexthop = NULL;
@@ -1504,8 +1531,9 @@ static bool rib_update_re_from_ctx(struct route_entry *re,
changed_p = true;
} else {
if (IS_ZEBRA_DEBUG_RIB)
- zlog_debug("%s(%u):%s update_from_ctx(): no fib nhg",
- VRF_LOGNAME(vrf), re->vrf_id, dest_str);
+ zlog_debug("%s(%u:%u):%s update_from_ctx(): no fib nhg",
+ VRF_LOGNAME(vrf), re->vrf_id, re->table,
+ dest_str);
}
/*
@@ -1532,9 +1560,9 @@ static bool rib_update_re_from_ctx(struct route_entry *re,
if (matched) {
if (IS_ZEBRA_DEBUG_RIB)
zlog_debug(
- "%s(%u):%s update_from_ctx(): rib nhg matched, changed '%s'",
- VRF_LOGNAME(vrf), re->vrf_id, dest_str,
- (changed_p ? "true" : "false"));
+ "%s(%u:%u):%s update_from_ctx(): rib nhg matched, changed '%s'",
+ VRF_LOGNAME(vrf), re->vrf_id, re->table,
+ dest_str, (changed_p ? "true" : "false"));
goto check_backups;
}
@@ -1545,8 +1573,8 @@ no_nexthops:
*/
if (IS_ZEBRA_DEBUG_RIB)
zlog_debug(
- "%s(%u):%s update_from_ctx(): changed %s, adding new fib nhg%s",
- VRF_LOGNAME(vrf), re->vrf_id, dest_str,
+ "%s(%u:%u):%s update_from_ctx(): changed %s, adding new fib nhg%s",
+ VRF_LOGNAME(vrf), re->vrf_id, re->table, dest_str,
(changed_p ? "true" : "false"),
ctxnhg->nexthop != NULL ? "" : " (empty)");
@@ -1722,9 +1750,10 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
zlog_debug(
- "%s(%u):%s Processing dplane result ctx %p, op %s result %s",
- VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), dest_str,
- ctx, dplane_op2str(op), dplane_res2str(status));
+ "%s(%u:%u):%s Processing dplane result ctx %p, op %s result %s",
+ VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
+ dplane_ctx_get_table(ctx), dest_str, ctx,
+ dplane_op2str(op), dplane_res2str(status));
/*
* Update is a bit of a special case, where we may have both old and new
@@ -1774,10 +1803,10 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
if (old_re->dplane_sequence != dplane_ctx_get_old_seq(ctx)) {
if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
zlog_debug(
- "%s(%u):%s Stale dplane result for old_re %p",
+ "%s(%u:%u):%s Stale dplane result for old_re %p",
VRF_LOGNAME(vrf),
- dplane_ctx_get_vrf(ctx), dest_str,
- old_re);
+ dplane_ctx_get_vrf(ctx), old_re->table,
+ dest_str, old_re);
} else
UNSET_FLAG(old_re->status, ROUTE_ENTRY_QUEUED);
}
@@ -1815,9 +1844,11 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
if (!fib_changed) {
if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
zlog_debug(
- "%s(%u):%s no fib change for re",
+ "%s(%u:%u):%s no fib change for re",
VRF_LOGNAME(vrf),
dplane_ctx_get_vrf(ctx),
+ dplane_ctx_get_table(
+ ctx),
dest_str);
}
@@ -1854,8 +1885,9 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
zsend_route_notify_owner(re, dest_pfx,
ZAPI_ROUTE_FAIL_INSTALL);
- zlog_warn("%s(%u):%s: Route install failed",
+ zlog_warn("%s(%u:%u):%s: Route install failed",
VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
+ dplane_ctx_get_table(ctx),
prefix2str(dest_pfx, dest_str,
sizeof(dest_str)));
}
@@ -1883,8 +1915,9 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
zsend_route_notify_owner_ctx(ctx,
ZAPI_ROUTE_REMOVE_FAIL);
- zlog_warn("%s(%u):%s: Route Deletion failure",
+ zlog_warn("%s(%u:%u):%s: Route Deletion failure",
VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
+ dplane_ctx_get_table(ctx),
prefix2str(dest_pfx, dest_str,
sizeof(dest_str)));
}
@@ -1981,9 +2014,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
if (rn == NULL) {
if (debug_p) {
zlog_debug(
- "Failed to process dplane notification: no routes for %s(%u):%s",
+ "Failed to process dplane notification: no routes for %s(%u:%u):%s",
VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
- dest_str);
+ dplane_ctx_get_table(ctx), dest_str);
}
goto done;
}
@@ -1992,9 +2025,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
srcdest_rnode_prefixes(rn, &dest_pfx, &src_pfx);
if (debug_p)
- zlog_debug("%s(%u):%s Processing dplane notif ctx %p",
- VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), dest_str,
- ctx);
+ zlog_debug("%s(%u:%u):%s Processing dplane notif ctx %p",
+ VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
+ dplane_ctx_get_table(ctx), dest_str, ctx);
/*
* Take a pass through the routes, look for matches with the context
@@ -2009,9 +2042,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
if (re == NULL) {
if (debug_p)
zlog_debug(
- "%s(%u):%s Unable to process dplane notification: no entry for type %s",
+ "%s(%u:%u):%s Unable to process dplane notification: no entry for type %s",
VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
- dest_str,
+ dplane_ctx_get_table(ctx), dest_str,
zebra_route_string(dplane_ctx_get_type(ctx)));
goto done;
@@ -2043,18 +2076,20 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
if (debug_p)
zlog_debug(
- "%s(%u):%s dplane notif, uninstalled type %s route",
+ "%s(%u:%u):%s dplane notif, uninstalled type %s route",
VRF_LOGNAME(vrf),
- dplane_ctx_get_vrf(ctx), dest_str,
+ dplane_ctx_get_vrf(ctx),
+ dplane_ctx_get_table(ctx), dest_str,
zebra_route_string(
dplane_ctx_get_type(ctx)));
} else {
/* At least report on the event. */
if (debug_p)
zlog_debug(
- "%s(%u):%s dplane notif, but type %s not selected_fib",
+ "%s(%u:%u):%s dplane notif, but type %s not selected_fib",
VRF_LOGNAME(vrf),
- dplane_ctx_get_vrf(ctx), dest_str,
+ dplane_ctx_get_vrf(ctx),
+ dplane_ctx_get_table(ctx), dest_str,
zebra_route_string(
dplane_ctx_get_type(ctx)));
}
@@ -2078,9 +2113,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
if (!fib_changed) {
if (debug_p)
zlog_debug(
- "%s(%u):%s dplane notification: rib_update returns FALSE",
+ "%s(%u:%u):%s dplane notification: rib_update returns FALSE",
VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
- dest_str);
+ dplane_ctx_get_table(ctx), dest_str);
}
/*
@@ -2095,9 +2130,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
if (start_count > 0 && end_count > 0) {
if (debug_p)
zlog_debug(
- "%s(%u):%s applied nexthop changes from dplane notification",
+ "%s(%u:%u):%s applied nexthop changes from dplane notification",
VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
- dest_str);
+ dplane_ctx_get_table(ctx), dest_str);
/* Changed nexthops - update kernel/others */
dplane_route_notif_update(rn, re,
@@ -2106,9 +2141,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
} else if (start_count == 0 && end_count > 0) {
if (debug_p)
zlog_debug(
- "%s(%u):%s installed transition from dplane notification",
+ "%s(%u:%u):%s installed transition from dplane notification",
VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
- dest_str);
+ dplane_ctx_get_table(ctx), dest_str);
/* We expect this to be the selected route, so we want
* to tell others about this transition.
@@ -2124,9 +2159,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
} else if (start_count > 0 && end_count == 0) {
if (debug_p)
zlog_debug(
- "%s(%u):%s un-installed transition from dplane notification",
+ "%s(%u:%u):%s un-installed transition from dplane notification",
VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
- dest_str);
+ dplane_ctx_get_table(ctx), dest_str);
/* Transition from _something_ installed to _nothing_
* installed.
@@ -2182,17 +2217,20 @@ static void process_subq_route(struct listnode *lnode, uint8_t qindex)
rnode = listgetdata(lnode);
dest = rib_dest_from_rnode(rnode);
- if (dest)
- zvrf = rib_dest_vrf(dest);
+ assert(dest);
+
+ zvrf = rib_dest_vrf(dest);
rib_process(rnode);
if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
+ struct route_entry *re = re_list_first(&dest->routes);
char buf[SRCDEST2STR_BUFFER];
srcdest_rnode2str(rnode, buf, sizeof(buf));
- zlog_debug("%s(%u):%s: rn %p dequeued from sub-queue %u",
- zvrf_name(zvrf), zvrf_id(zvrf), buf, rnode, qindex);
+ zlog_debug("%s(%u:%u):%s: rn %p dequeued from sub-queue %u",
+ zvrf_name(zvrf), zvrf_id(zvrf), re ? re->table : 0, buf,
+ rnode, qindex);
}
if (rnode->info)
@@ -3003,7 +3041,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
unsigned short instance, int flags, struct prefix *p,
struct prefix_ipv6 *src_p, const struct nexthop *nh,
uint32_t nhe_id, uint32_t table_id, uint32_t metric,
- uint8_t distance, bool fromkernel)
+ uint8_t distance, bool fromkernel, bool connected_down)
{
struct route_table *table;
struct route_node *rn;
@@ -3125,7 +3163,8 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
rn, fib,
zebra_route_string(fib->type));
}
- if (allow_delete) {
+ if (allow_delete
+ || CHECK_FLAG(dest->flags, RIB_ROUTE_ANY_QUEUED)) {
UNSET_FLAG(fib->status, ROUTE_ENTRY_INSTALLED);
/* Unset flags. */
for (rtnh = fib->nhe->nhg.nexthop; rtnh;
@@ -3210,6 +3249,19 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
rib_delnode(rn, same);
}
+ /*
+ * This is to force an immediate re-eval of this particular
+ * node via nexthop tracking. Why? Because there are scenarios
+ * where the interface is flapping and the normal queuing methodology
+ * will cause down/up events to very very rarely be combined into
+ * a non-event from nexthop tracking perspective. Leading
+ * to some fun timing situations with upper level routing protocol
+ * trying to and failing to install routes during this blip. Especially
+ * when zebra is under load.
+ */
+ if (connected_down)
+ zebra_rib_evaluate_rn_nexthops(rn,
+ zebra_router_get_next_sequence());
route_unlock_node(rn);
return;
}