diff options
Diffstat (limited to 'zebra/zebra_rib.c')
| -rw-r--r-- | zebra/zebra_rib.c | 379 |
1 files changed, 185 insertions, 194 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index aac0e628fe..e76ecc85a6 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -79,35 +79,35 @@ static const struct { uint8_t meta_q_map; } route_info[ZEBRA_ROUTE_MAX] = { [ZEBRA_ROUTE_NHG] = {ZEBRA_ROUTE_NHG, 255 /* Uneeded for nhg's */, 0}, - [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0, 5}, - [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0, 1}, + [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0, 6}, + [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0, 2}, [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0, 1}, - [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1, 2}, - [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120, 3}, - [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120, 3}, - [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110, 3}, - [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110, 3}, - [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115, 3}, - [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */, 4}, - [ZEBRA_ROUTE_PIM] = {ZEBRA_ROUTE_PIM, 255, 5}, - [ZEBRA_ROUTE_EIGRP] = {ZEBRA_ROUTE_EIGRP, 90, 3}, - [ZEBRA_ROUTE_NHRP] = {ZEBRA_ROUTE_NHRP, 10, 3}, - [ZEBRA_ROUTE_HSLS] = {ZEBRA_ROUTE_HSLS, 255, 5}, - [ZEBRA_ROUTE_OLSR] = {ZEBRA_ROUTE_OLSR, 255, 5}, - [ZEBRA_ROUTE_TABLE] = {ZEBRA_ROUTE_TABLE, 150, 2}, - [ZEBRA_ROUTE_LDP] = {ZEBRA_ROUTE_LDP, 150, 5}, - [ZEBRA_ROUTE_VNC] = {ZEBRA_ROUTE_VNC, 20, 4}, - [ZEBRA_ROUTE_VNC_DIRECT] = {ZEBRA_ROUTE_VNC_DIRECT, 20, 4}, - [ZEBRA_ROUTE_VNC_DIRECT_RH] = {ZEBRA_ROUTE_VNC_DIRECT_RH, 20, 4}, - [ZEBRA_ROUTE_BGP_DIRECT] = {ZEBRA_ROUTE_BGP_DIRECT, 20, 4}, - [ZEBRA_ROUTE_BGP_DIRECT_EXT] = {ZEBRA_ROUTE_BGP_DIRECT_EXT, 20, 4}, - [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 100, 3}, - [ZEBRA_ROUTE_SHARP] = {ZEBRA_ROUTE_SHARP, 150, 5}, - [ZEBRA_ROUTE_PBR] = {ZEBRA_ROUTE_PBR, 200, 5}, - [ZEBRA_ROUTE_BFD] = {ZEBRA_ROUTE_BFD, 255, 5}, - [ZEBRA_ROUTE_OPENFABRIC] = {ZEBRA_ROUTE_OPENFABRIC, 115, 3}, - [ZEBRA_ROUTE_VRRP] = {ZEBRA_ROUTE_VRRP, 255, 5}, - [ZEBRA_ROUTE_SRTE] = {ZEBRA_ROUTE_SRTE, 255, 5}, + [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1, 3}, + [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120, 4}, + [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120, 4}, + [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110, 4}, + [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110, 4}, + [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115, 4}, + [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */, 5}, + [ZEBRA_ROUTE_PIM] = {ZEBRA_ROUTE_PIM, 255, 6}, + [ZEBRA_ROUTE_EIGRP] = {ZEBRA_ROUTE_EIGRP, 90, 4}, + [ZEBRA_ROUTE_NHRP] = {ZEBRA_ROUTE_NHRP, 10, 4}, + [ZEBRA_ROUTE_HSLS] = {ZEBRA_ROUTE_HSLS, 255, 6}, + [ZEBRA_ROUTE_OLSR] = {ZEBRA_ROUTE_OLSR, 255, 6}, + [ZEBRA_ROUTE_TABLE] = {ZEBRA_ROUTE_TABLE, 150, 3}, + [ZEBRA_ROUTE_LDP] = {ZEBRA_ROUTE_LDP, 150, 6}, + [ZEBRA_ROUTE_VNC] = {ZEBRA_ROUTE_VNC, 20, 5}, + [ZEBRA_ROUTE_VNC_DIRECT] = {ZEBRA_ROUTE_VNC_DIRECT, 20, 5}, + [ZEBRA_ROUTE_VNC_DIRECT_RH] = {ZEBRA_ROUTE_VNC_DIRECT_RH, 20, 5}, + [ZEBRA_ROUTE_BGP_DIRECT] = {ZEBRA_ROUTE_BGP_DIRECT, 20, 5}, + [ZEBRA_ROUTE_BGP_DIRECT_EXT] = {ZEBRA_ROUTE_BGP_DIRECT_EXT, 20, 5}, + [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 100, 4}, + [ZEBRA_ROUTE_SHARP] = {ZEBRA_ROUTE_SHARP, 150, 6}, + [ZEBRA_ROUTE_PBR] = {ZEBRA_ROUTE_PBR, 200, 6}, + [ZEBRA_ROUTE_BFD] = {ZEBRA_ROUTE_BFD, 255, 6}, + [ZEBRA_ROUTE_OPENFABRIC] = {ZEBRA_ROUTE_OPENFABRIC, 115, 4}, + [ZEBRA_ROUTE_VRRP] = {ZEBRA_ROUTE_VRRP, 255, 6}, + [ZEBRA_ROUTE_SRTE] = {ZEBRA_ROUTE_SRTE, 255, 6}, /* Any new route type added to zebra, should be mirrored here */ /* no entry/default: 150 */ @@ -694,15 +694,13 @@ void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq) if (IS_ZEBRA_DEBUG_NHT_DETAILED) { char buf1[PREFIX_STRLEN]; - char buf2[PREFIX_STRLEN]; zlog_debug( - "%s(%u):%s has Nexthop(%s) Type: %s depending on it, evaluating %u:%u", + "%s(%u):%s has Nexthop(%pFX) Type: %s depending on it, evaluating %u:%u", zvrf_name(zvrf), zvrf_id(zvrf), srcdest_rnode2str(rn, buf1, sizeof(buf1)), - prefix2str(p, buf2, sizeof(buf2)), - rnh_type2str(rnh->type), seq, + p, rnh_type2str(rnh->type), seq, rnh->seqno); } @@ -921,11 +919,22 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf, zebra_route_string(new->type)); } - /* If labeled-unicast route, uninstall transit LSP. */ - if (zebra_rib_labeled_unicast(old)) - zebra_mpls_lsp_uninstall(zvrf, rn, old); + /* + * When we have gotten to this point + * the new route entry has no nexthops + * that are usable and as such we need + * to remove the old route, but only + * if we were the one who installed + * the old route + */ + if (!RIB_SYSTEM_ROUTE(old)) { + /* If labeled-unicast route, uninstall transit + * LSP. */ + if (zebra_rib_labeled_unicast(old)) + zebra_mpls_lsp_uninstall(zvrf, rn, old); - rib_uninstall_kernel(rn, old); + rib_uninstall_kernel(rn, old); + } } } else { /* @@ -1087,46 +1096,56 @@ static void rib_process(struct route_node *rn) if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)) continue; - /* Skip unreachable nexthop. */ - /* This first call to nexthop_active_update is merely to - * determine if there's any change to nexthops associated - * with this RIB entry. Now, rib_process() can be invoked due - * to an external event such as link down or due to - * next-hop-tracking evaluation. In the latter case, - * a decision has already been made that the NHs have changed. - * So, no need to invoke a potentially expensive call again. - * Further, since the change might be in a recursive NH which - * is not caught in the nexthop_active_update() code. Thus, we - * might miss changes to recursive NHs. + /* + * If the route entry has changed, verify/resolve + * the nexthops associated with the entry. + * + * In any event if we have nexthops that are not active + * then we cannot use this particular route entry so + * skip it. */ - if (CHECK_FLAG(re->status, ROUTE_ENTRY_CHANGED) - && !nexthop_active_update(rn, re)) { - if (re->type == ZEBRA_ROUTE_TABLE) { - /* XXX: HERE BE DRAGONS!!!!! - * In all honesty, I have not yet figured out - * what this part does or why the - * ROUTE_ENTRY_CHANGED test above is correct - * or why we need to delete a route here, and - * also not whether this concerns both selected - * and fib route, or only selected - * or only fib - * - * This entry was denied by the 'ip protocol - * table' route-map, we need to delete it */ - if (re != old_selected) { - if (IS_ZEBRA_DEBUG_RIB) - zlog_debug( - "%s: %s(%u):%s: imported via import-table but denied by the ip protocol table route-map", - __func__, - VRF_LOGNAME(vrf), - vrf_id, buf); - rib_unlink(rn, re); - } else - SET_FLAG(re->status, - ROUTE_ENTRY_REMOVED); - } + if (CHECK_FLAG(re->status, ROUTE_ENTRY_CHANGED)) { + if (!nexthop_active_update(rn, re)) { + if (re->type == ZEBRA_ROUTE_TABLE) { + /* XXX: HERE BE DRAGONS!!!!! + * In all honesty, I have not yet + * figured out what this part does or + * why the ROUTE_ENTRY_CHANGED test + * above is correct or why we need to + * delete a route here, and also not + * whether this concerns both selected + * and fib route, or only selected + * or only fib + * + * This entry was denied by the 'ip + * protocol + * table' route-map, we need to delete + * it */ + if (re != old_selected) { + if (IS_ZEBRA_DEBUG_RIB) + zlog_debug( + "%s: %s(%u):%s: imported via import-table but denied by the ip protocol table route-map", + __func__, + VRF_LOGNAME( + vrf), + vrf_id, buf); + rib_unlink(rn, re); + } else + SET_FLAG(re->status, + ROUTE_ENTRY_REMOVED); + } - continue; + continue; + } + } else { + /* + * If the re has not changed and the nhg we have is + * not usable, then we cannot use this route entry + * for consideration, as that the route will just + * not install if it is selected. + */ + if (!nexthop_group_active_nexthop_num(&re->nhe->nhg)) + continue; } /* Infinite distance. */ @@ -1357,8 +1376,6 @@ static void zebra_rib_fixup_system(struct route_node *rn) static bool rib_compare_routes(const struct route_entry *re1, const struct route_entry *re2) { - bool result = false; - if (re1->type != re2->type) return false; @@ -1372,17 +1389,14 @@ static bool rib_compare_routes(const struct route_entry *re1, re1->distance != re2->distance) return false; - /* Only connected routes need more checking, nexthop-by-nexthop */ + /* We support multiple connected routes: this supports multiple + * v6 link-locals, and we also support multiple addresses in the same + * subnet on a single interface. + */ if (re1->type != ZEBRA_ROUTE_CONNECT) return true; - /* Quick check if shared nhe */ - if (re1->nhe == re2->nhe) - return true; - - result = nexthop_group_equal_no_recurse(&re1->nhe->nhg, &re2->nhe->nhg); - - return result; + return false; } /* @@ -1481,7 +1495,6 @@ static bool rib_update_re_from_ctx(struct route_entry *re, struct route_node *rn, struct zebra_dplane_ctx *ctx) { - char dest_str[PREFIX_STRLEN] = ""; struct nexthop *nexthop; bool matched; const struct nexthop_group *ctxnhg; @@ -1493,19 +1506,13 @@ static bool rib_update_re_from_ctx(struct route_entry *re, vrf = vrf_lookup_by_id(re->vrf_id); - /* Note well: only capturing the prefix string if debug is enabled here; - * unconditional log messages will have to generate the string. - */ - if (IS_ZEBRA_DEBUG_RIB) - prefix2str(&(rn->p), dest_str, sizeof(dest_str)); - dest = rib_dest_from_rnode(rn); if (dest) is_selected = (re == dest->selected_fib); if (IS_ZEBRA_DEBUG_RIB_DETAILED) - zlog_debug("update_from_ctx: %s(%u:%u):%s: %sSELECTED, re %p", - VRF_LOGNAME(vrf), re->vrf_id, re->table, dest_str, + zlog_debug("update_from_ctx: %s(%u:%u):%pRN: %sSELECTED, re %p", + VRF_LOGNAME(vrf), re->vrf_id, re->table, rn, (is_selected ? "" : "NOT "), re); /* Update zebra's nexthop FIB flag for each nexthop that was installed. @@ -1531,9 +1538,8 @@ static bool rib_update_re_from_ctx(struct route_entry *re, if (matched) { if (IS_ZEBRA_DEBUG_RIB) zlog_debug( - "%s(%u:%u):%s update_from_ctx(): existing fib nhg, no change", - VRF_LOGNAME(vrf), re->vrf_id, re->table, - dest_str); + "%s(%u:%u):%pRN update_from_ctx(): existing fib nhg, no change", + VRF_LOGNAME(vrf), re->vrf_id, re->table, rn); goto check_backups; } else if (CHECK_FLAG(re->status, ROUTE_ENTRY_USE_FIB_NHG)) { @@ -1542,9 +1548,8 @@ static bool rib_update_re_from_ctx(struct route_entry *re, */ if (IS_ZEBRA_DEBUG_RIB) zlog_debug( - "%s(%u:%u):%s update_from_ctx(): replacing fib nhg", - VRF_LOGNAME(vrf), re->vrf_id, re->table, - dest_str); + "%s(%u:%u):%pRN update_from_ctx(): replacing fib nhg", + VRF_LOGNAME(vrf), re->vrf_id, re->table, rn); nexthops_free(re->fib_ng.nexthop); re->fib_ng.nexthop = NULL; @@ -1554,9 +1559,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:%u):%s update_from_ctx(): no fib nhg", - VRF_LOGNAME(vrf), re->vrf_id, re->table, - dest_str); + zlog_debug( + "%s(%u:%u):%pRN update_from_ctx(): no fib nhg", + VRF_LOGNAME(vrf), re->vrf_id, re->table, rn); } /* @@ -1583,9 +1588,9 @@ static bool rib_update_re_from_ctx(struct route_entry *re, if (matched) { if (IS_ZEBRA_DEBUG_RIB) zlog_debug( - "%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")); + "%s(%u:%u):%pRN update_from_ctx(): rib nhg matched, changed '%s'", + VRF_LOGNAME(vrf), re->vrf_id, re->table, rn, + (changed_p ? "true" : "false")); goto check_backups; } @@ -1596,8 +1601,8 @@ no_nexthops: */ if (IS_ZEBRA_DEBUG_RIB) zlog_debug( - "%s(%u:%u):%s update_from_ctx(): changed %s, adding new fib nhg%s", - VRF_LOGNAME(vrf), re->vrf_id, re->table, dest_str, + "%s(%u:%u):%pRN update_from_ctx(): changed %s, adding new fib nhg%s", + VRF_LOGNAME(vrf), re->vrf_id, re->table, rn, (changed_p ? "true" : "false"), ctxnhg->nexthop != NULL ? "" : " (empty)"); @@ -1631,8 +1636,8 @@ check_backups: if (matched) { if (IS_ZEBRA_DEBUG_RIB) zlog_debug( - "%s(%u):%s update_from_ctx(): existing fib backup nhg, no change", - VRF_LOGNAME(vrf), re->vrf_id, dest_str); + "%s(%u):%pRN update_from_ctx(): existing fib backup nhg, no change", + VRF_LOGNAME(vrf), re->vrf_id, rn); goto done; } else if (re->fib_backup_ng.nexthop) { @@ -1642,8 +1647,8 @@ check_backups: */ if (IS_ZEBRA_DEBUG_RIB) zlog_debug( - "%s(%u):%s update_from_ctx(): replacing fib backup nhg", - VRF_LOGNAME(vrf), re->vrf_id, dest_str); + "%s(%u):%pRN update_from_ctx(): replacing fib backup nhg", + VRF_LOGNAME(vrf), re->vrf_id, rn); nexthops_free(re->fib_backup_ng.nexthop); re->fib_backup_ng.nexthop = NULL; @@ -1651,8 +1656,9 @@ check_backups: changed_p = true; } else { if (IS_ZEBRA_DEBUG_RIB) - zlog_debug("%s(%u):%s update_from_ctx(): no fib backup nhg", - VRF_LOGNAME(vrf), re->vrf_id, dest_str); + zlog_debug( + "%s(%u):%pRN update_from_ctx(): no fib backup nhg", + VRF_LOGNAME(vrf), re->vrf_id, rn); } /* @@ -1671,9 +1677,10 @@ check_backups: goto done; if (IS_ZEBRA_DEBUG_RIB) - zlog_debug("%s(%u):%s update_from_ctx(): changed %s, adding new backup fib nhg", - VRF_LOGNAME(vrf), re->vrf_id, dest_str, - (changed_p ? "true" : "false")); + zlog_debug( + "%s(%u):%pRN update_from_ctx(): changed %s, adding new backup fib nhg", + VRF_LOGNAME(vrf), re->vrf_id, rn, + (changed_p ? "true" : "false")); copy_nexthops(&(re->fib_backup_ng.nexthop), ctxnhg->nexthop, NULL); @@ -1735,7 +1742,6 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) struct route_node *rn = NULL; struct route_entry *re = NULL, *old_re = NULL, *rib; bool is_update = false; - char dest_str[PREFIX_STRLEN] = ""; enum dplane_op_e op; enum zebra_dplane_result status; const struct prefix *dest_pfx, *src_pfx; @@ -1747,20 +1753,14 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) vrf = vrf_lookup_by_id(dplane_ctx_get_vrf(ctx)); dest_pfx = dplane_ctx_get_dest(ctx); - /* Note well: only capturing the prefix string if debug is enabled here; - * unconditional log messages will have to generate the string. - */ - if (IS_ZEBRA_DEBUG_DPLANE) - prefix2str(dest_pfx, dest_str, sizeof(dest_str)); - /* Locate rn and re(s) from ctx */ rn = rib_find_rn_from_ctx(ctx); if (rn == NULL) { if (IS_ZEBRA_DEBUG_DPLANE) { zlog_debug( - "Failed to process dplane results: no route for %s(%u):%s", + "Failed to process dplane results: no route for %s(%u):%pFX", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dest_str); + dest_pfx); } goto done; } @@ -1773,9 +1773,9 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) zlog_debug( - "%s(%u:%u):%s Processing dplane result ctx %p, op %s result %s", + "%s(%u:%u):%pFX 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_ctx_get_table(ctx), dest_pfx, ctx, dplane_op2str(op), dplane_res2str(status)); /* @@ -1815,9 +1815,9 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) if (re->dplane_sequence != seq) { if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) zlog_debug( - "%s(%u):%s Stale dplane result for re %p", + "%s(%u):%pFX Stale dplane result for re %p", VRF_LOGNAME(vrf), - dplane_ctx_get_vrf(ctx), dest_str, re); + dplane_ctx_get_vrf(ctx), dest_pfx, re); } else UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED); } @@ -1826,10 +1826,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:%u):%s Stale dplane result for old_re %p", + "%s(%u:%u):%pFX Stale dplane result for old_re %p", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), old_re->table, - dest_str, old_re); + dest_pfx, old_re); } else UNSET_FLAG(old_re->status, ROUTE_ENTRY_QUEUED); } @@ -1867,12 +1867,12 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) if (!fib_changed) { if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) zlog_debug( - "%s(%u:%u):%s no fib change for re", + "%s(%u:%u):%pFX no fib change for re", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), dplane_ctx_get_table( ctx), - dest_str); + dest_pfx); } /* Redistribute if this is the selected re */ @@ -1908,11 +1908,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:%u):%s: Route install failed", + zlog_warn("%s(%u:%u):%pFX: Route install failed", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), - prefix2str(dest_pfx, dest_str, - sizeof(dest_str))); + dplane_ctx_get_table(ctx), dest_pfx); } break; case DPLANE_OP_ROUTE_DELETE: @@ -1938,11 +1936,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:%u):%s: Route Deletion failure", + zlog_warn("%s(%u:%u):%pFX: Route Deletion failure", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), - prefix2str(dest_pfx, dest_str, - sizeof(dest_str))); + dplane_ctx_get_table(ctx), dest_pfx); } /* @@ -2017,7 +2013,6 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx) struct route_entry *re = NULL; struct vrf *vrf; struct nexthop *nexthop; - char dest_str[PREFIX_STRLEN] = ""; const struct prefix *dest_pfx, *src_pfx; rib_dest_t *dest; bool fib_changed = false; @@ -2026,20 +2021,14 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx) dest_pfx = dplane_ctx_get_dest(ctx); vrf = vrf_lookup_by_id(dplane_ctx_get_vrf(ctx)); - /* Note well: only capturing the prefix string if debug is enabled here; - * unconditional log messages will have to generate the string. - */ - if (debug_p) - prefix2str(dest_pfx, dest_str, sizeof(dest_str)); - /* Locate rn and re(s) from ctx */ rn = rib_find_rn_from_ctx(ctx); if (rn == NULL) { if (debug_p) { zlog_debug( - "Failed to process dplane notification: no routes for %s(%u:%u):%s", + "Failed to process dplane notification: no routes for %s(%u:%u):%pFX", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), dest_str); + dplane_ctx_get_table(ctx), dest_pfx); } goto done; } @@ -2048,9 +2037,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:%u):%s Processing dplane notif ctx %p", + zlog_debug("%s(%u:%u):%pFX Processing dplane notif ctx %p", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), dest_str, ctx); + dplane_ctx_get_table(ctx), dest_pfx, ctx); /* * Take a pass through the routes, look for matches with the context @@ -2065,9 +2054,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx) if (re == NULL) { if (debug_p) zlog_debug( - "%s(%u:%u):%s Unable to process dplane notification: no entry for type %s", + "%s(%u:%u):%pFX Unable to process dplane notification: no entry for type %s", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), dest_str, + dplane_ctx_get_table(ctx), dest_pfx, zebra_route_string(dplane_ctx_get_type(ctx))); goto done; @@ -2099,20 +2088,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:%u):%s dplane notif, uninstalled type %s route", + "%s(%u:%u):%pFX dplane notif, uninstalled type %s route", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), dest_str, + dplane_ctx_get_table(ctx), dest_pfx, zebra_route_string( dplane_ctx_get_type(ctx))); } else { /* At least report on the event. */ if (debug_p) zlog_debug( - "%s(%u:%u):%s dplane notif, but type %s not selected_fib", + "%s(%u:%u):%pFX dplane notif, but type %s not selected_fib", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), dest_str, + dplane_ctx_get_table(ctx), dest_pfx, zebra_route_string( dplane_ctx_get_type(ctx))); } @@ -2136,9 +2125,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx) if (!fib_changed) { if (debug_p) zlog_debug( - "%s(%u:%u):%s dplane notification: rib_update returns FALSE", + "%s(%u:%u):%pFX dplane notification: rib_update returns FALSE", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), dest_str); + dplane_ctx_get_table(ctx), dest_pfx); } /* @@ -2153,9 +2142,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:%u):%s applied nexthop changes from dplane notification", + "%s(%u:%u):%pFX applied nexthop changes from dplane notification", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), dest_str); + dplane_ctx_get_table(ctx), dest_pfx); /* Changed nexthops - update kernel/others */ dplane_route_notif_update(rn, re, @@ -2164,9 +2153,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:%u):%s installed transition from dplane notification", + "%s(%u:%u):%pFX installed transition from dplane notification", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), dest_str); + dplane_ctx_get_table(ctx), dest_pfx); /* We expect this to be the selected route, so we want * to tell others about this transition. @@ -2182,9 +2171,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:%u):%s un-installed transition from dplane notification", + "%s(%u:%u):%pFX un-installed transition from dplane notification", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), dest_str); + dplane_ctx_get_table(ctx), dest_pfx); /* Transition from _something_ installed to _nothing_ * installed. @@ -2247,9 +2236,18 @@ static void process_subq_route(struct listnode *lnode, uint8_t qindex) rib_process(rnode); if (IS_ZEBRA_DEBUG_RIB_DETAILED) { - struct route_entry *re = re_list_first(&dest->routes); + struct route_entry *re = NULL; char buf[SRCDEST2STR_BUFFER]; + /* + * rib_process may have freed the dest + * as part of the garbage collection. Let's + * prevent stupidity from happening. + */ + dest = rib_dest_from_rnode(rnode); + if (dest) + re = re_list_first(&dest->routes); + srcdest_rnode2str(rnode, buf, sizeof(buf)); zlog_debug("%s(%u:%u):%s: rn %p dequeued from sub-queue %u", zvrf_name(zvrf), zvrf_id(zvrf), re ? re->table : 0, buf, @@ -2264,7 +2262,7 @@ static void process_subq_route(struct listnode *lnode, uint8_t qindex) else { zlog_debug ("%s: called for route_node (%p, %d) with no ribs", - __func__, rnode, rnode->lock); + __func__, rnode, route_node_get_lock_count(rnode)); zlog_backtrace(LOG_DEBUG); } #endif @@ -2439,8 +2437,8 @@ int rib_queue_add(struct route_node *rn) /* Pointless to queue a route_node with no RIB entries to add or remove */ if (!rnode_to_ribs(rn)) { - zlog_debug("%s: called for route_node (%p, %d) with no ribs", - __func__, (void *)rn, rn->lock); + zlog_debug("%s: called for route_node (%p, %u) with no ribs", + __func__, (void *)rn, route_node_get_lock_count(rn)); zlog_backtrace(LOG_DEBUG); return -1; } @@ -2806,7 +2804,6 @@ void rib_lookup_and_dump(struct prefix_ipv4 *p, vrf_id_t vrf_id) struct route_node *rn; struct route_entry *re; struct vrf *vrf; - char prefix_buf[INET_ADDRSTRLEN]; vrf = vrf_lookup_by_id(vrf_id); @@ -2824,10 +2821,8 @@ void rib_lookup_and_dump(struct prefix_ipv4 *p, vrf_id_t vrf_id) /* No route for this prefix. */ if (!rn) { - zlog_debug("%s:%s(%u) lookup failed for %s", __func__, - VRF_LOGNAME(vrf), vrf_id, - prefix2str((struct prefix *)p, prefix_buf, - sizeof(prefix_buf))); + zlog_debug("%s:%s(%u) lookup failed for %pFX", __func__, + VRF_LOGNAME(vrf), vrf_id, (struct prefix *)p); return; } @@ -2886,14 +2881,13 @@ void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id) */ if (dest->selected_fib) { if (IS_ZEBRA_DEBUG_RIB) { - char buf[PREFIX_STRLEN]; struct vrf *vrf = vrf_lookup_by_id(dest->selected_fib->vrf_id); zlog_debug( - "%s(%u):%s: freeing way for connected prefix", + "%s(%u):%pFX: freeing way for connected prefix", VRF_LOGNAME(vrf), dest->selected_fib->vrf_id, - prefix2str(&rn->p, buf, sizeof(buf))); + &rn->p); route_entry_dump(&rn->p, NULL, dest->selected_fib); } rib_uninstall(rn, dest->selected_fib); @@ -2944,14 +2938,12 @@ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p, /* Lookup nhe from route information */ nhe = zebra_nhg_rib_find_nhe(re_nhe, afi); if (!nhe) { - char buf[PREFIX_STRLEN] = ""; char buf2[PREFIX_STRLEN] = ""; flog_err( EC_ZEBRA_TABLE_LOOKUP_FAILED, - "Zebra failed to find or create a nexthop hash entry for %s%s%s", - prefix2str(p, buf, sizeof(buf)), - src_p ? " from " : "", + "Zebra failed to find or create a nexthop hash entry for %pFX%s%s", + p, src_p ? " from " : "", src_p ? prefix2str(src_p, buf2, sizeof(buf2)) : ""); @@ -3061,7 +3053,7 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, } void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, - unsigned short instance, int flags, struct prefix *p, + unsigned short instance, uint32_t 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, bool connected_down) @@ -3091,19 +3083,17 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, /* Lookup route node. */ rn = srcdest_rnode_lookup(table, p, src_p); if (!rn) { - char dst_buf[PREFIX_STRLEN], src_buf[PREFIX_STRLEN]; - - prefix2str(p, dst_buf, sizeof(dst_buf)); - if (src_p && src_p->prefixlen) - prefix2str(src_p, src_buf, sizeof(src_buf)); - else - src_buf[0] = '\0'; - if (IS_ZEBRA_DEBUG_RIB) { + char src_buf[PREFIX_STRLEN]; struct vrf *vrf = vrf_lookup_by_id(vrf_id); - zlog_debug("%s[%d]:%s%s%s doesn't exist in rib", - vrf->name, table_id, dst_buf, + if (src_p && src_p->prefixlen) + prefix2str(src_p, src_buf, sizeof(src_buf)); + else + src_buf[0] = '\0'; + + zlog_debug("%s[%d]:%pFX%s%s doesn't exist in rib", + vrf->name, table_id, p, (src_buf[0] != '\0') ? " from " : "", src_buf); } @@ -3291,7 +3281,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, - unsigned short instance, int flags, struct prefix *p, + unsigned short instance, uint32_t flags, struct prefix *p, struct prefix_ipv6 *src_p, const struct nexthop *nh, uint32_t nhe_id, uint32_t table_id, uint32_t metric, uint32_t mtu, uint8_t distance, route_tag_t tag) @@ -3840,6 +3830,7 @@ static int rib_process_dplane_results(struct thread *thread) case DPLANE_OP_VTEP_ADD: case DPLANE_OP_VTEP_DELETE: case DPLANE_OP_NEIGH_DISCOVER: + case DPLANE_OP_BR_PORT_UPDATE: case DPLANE_OP_NONE: /* Don't expect this: just return the struct? */ dplane_ctx_fini(&ctx); |
