diff options
Diffstat (limited to 'zebra/zebra_dplane.c')
| -rw-r--r-- | zebra/zebra_dplane.c | 89 |
1 files changed, 76 insertions, 13 deletions
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index e34b6f23ff..0cc7139d6b 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -204,6 +204,7 @@ struct dplane_ctx_rule { /* Filter criteria */ uint32_t filter_bm; uint32_t fwmark; + uint8_t dsfield; struct prefix src_ip; struct prefix dst_ip; }; @@ -1676,6 +1677,20 @@ uint32_t dplane_ctx_rule_get_old_fwmark(const struct zebra_dplane_ctx *ctx) return ctx->u.rule.old.fwmark; } +uint8_t dplane_ctx_rule_get_dsfield(const struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + return ctx->u.rule.new.dsfield; +} + +uint8_t dplane_ctx_rule_get_old_dsfield(const struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + return ctx->u.rule.old.dsfield; +} + const struct prefix * dplane_ctx_rule_get_src_ip(const struct zebra_dplane_ctx *ctx) { @@ -2001,10 +2016,19 @@ int dplane_ctx_lsp_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, break; } - /* Need to copy flags too */ + /* Need to copy flags and backup info too */ new_nhlfe->flags = nhlfe->flags; new_nhlfe->nexthop->flags = nhlfe->nexthop->flags; + if (CHECK_FLAG(new_nhlfe->nexthop->flags, + NEXTHOP_FLAG_HAS_BACKUP)) { + new_nhlfe->nexthop->backup_num = + nhlfe->nexthop->backup_num; + memcpy(new_nhlfe->nexthop->backup_idx, + nhlfe->nexthop->backup_idx, + new_nhlfe->nexthop->backup_num); + } + if (nhlfe == lsp->best_nhlfe) ctx->u.lsp.best_nhlfe = new_nhlfe; } @@ -2104,8 +2128,15 @@ static int dplane_ctx_pw_init(struct zebra_dplane_ctx *ctx, if (re) { nhg = rib_get_fib_nhg(re); - copy_nexthops(&(ctx->u.pw.nhg.nexthop), - nhg->nexthop, NULL); + if (nhg && nhg->nexthop) + copy_nexthops(&(ctx->u.pw.nhg.nexthop), + nhg->nexthop, NULL); + + /* Include any installed backup nexthops */ + nhg = rib_get_fib_backup_nhg(re); + if (nhg && nhg->nexthop) + copy_nexthops(&(ctx->u.pw.nhg.nexthop), + nhg->nexthop, NULL); } route_unlock_node(rn); } @@ -2129,6 +2160,7 @@ static void dplane_ctx_rule_init_single(struct dplane_ctx_rule *dplane_rule, dplane_rule->filter_bm = rule->rule.filter.filter_bm; dplane_rule->fwmark = rule->rule.filter.fwmark; + dplane_rule->dsfield = rule->rule.filter.dsfield; prefix_copy(&(dplane_rule->dst_ip), &rule->rule.filter.dst_ip); prefix_copy(&(dplane_rule->src_ip), &rule->rule.filter.src_ip); } @@ -2461,6 +2493,7 @@ dplane_route_notif_update(struct route_node *rn, enum zebra_dplane_result ret = ZEBRA_DPLANE_REQUEST_FAILURE; struct zebra_dplane_ctx *new_ctx = NULL; struct nexthop *nexthop; + struct nexthop_group *nhg; if (rn == NULL || re == NULL) goto done; @@ -2482,8 +2515,17 @@ dplane_route_notif_update(struct route_node *rn, nexthops_free(new_ctx->u.rinfo.zd_ng.nexthop); new_ctx->u.rinfo.zd_ng.nexthop = NULL; - copy_nexthops(&(new_ctx->u.rinfo.zd_ng.nexthop), - (rib_get_fib_nhg(re))->nexthop, NULL); + nhg = rib_get_fib_nhg(re); + if (nhg && nhg->nexthop) + copy_nexthops(&(new_ctx->u.rinfo.zd_ng.nexthop), + nhg->nexthop, NULL); + + /* Check for installed backup nexthops also */ + nhg = rib_get_fib_backup_nhg(re); + if (nhg && nhg->nexthop) { + copy_nexthops(&(new_ctx->u.rinfo.zd_ng.nexthop), + nhg->nexthop, NULL); + } for (ALL_NEXTHOPS(new_ctx->u.rinfo.zd_ng, nexthop)) UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); @@ -2583,6 +2625,8 @@ dplane_lsp_notif_update(zebra_lsp_t *lsp, enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE; int ret = EINVAL; struct zebra_dplane_ctx *ctx = NULL; + struct nhlfe_list_head *head; + zebra_nhlfe_t *nhlfe, *new_nhlfe; /* Obtain context block */ ctx = dplane_ctx_alloc(); @@ -2591,10 +2635,27 @@ dplane_lsp_notif_update(zebra_lsp_t *lsp, goto done; } + /* Copy info from zebra LSP */ ret = dplane_ctx_lsp_init(ctx, op, lsp); if (ret != AOK) goto done; + /* Add any installed backup nhlfes */ + head = &(ctx->u.lsp.backup_nhlfe_list); + frr_each(nhlfe_list, head, nhlfe) { + + if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED) && + CHECK_FLAG(nhlfe->nexthop->flags, NEXTHOP_FLAG_FIB)) { + new_nhlfe = zebra_mpls_lsp_add_nh(&(ctx->u.lsp), + nhlfe->type, + nhlfe->nexthop); + + /* Need to copy flags too */ + new_nhlfe->flags = nhlfe->flags; + new_nhlfe->nexthop->flags = nhlfe->nexthop->flags; + } + } + /* Capture info about the source of the notification */ dplane_ctx_set_notif_provider( ctx, @@ -3261,8 +3322,7 @@ int dplane_show_provs_helper(struct vty *vty, bool detailed) out_max = atomic_load_explicit(&prov->dp_out_max, memory_order_relaxed); - vty_out(vty, "%s (%u): in: %"PRIu64", q_max: %"PRIu64", " - "out: %"PRIu64", q_max: %"PRIu64"\n", + vty_out(vty, "%s (%u): in: %"PRIu64", q_max: %"PRIu64", out: %"PRIu64", q_max: %"PRIu64"\n", prov->dp_name, prov->dp_id, in, in_max, out, out_max); DPLANE_LOCK(); @@ -4003,19 +4063,19 @@ bool dplane_is_in_shutdown(void) */ void zebra_dplane_pre_finish(void) { - struct zebra_dplane_provider *dp; + struct zebra_dplane_provider *prov; if (IS_ZEBRA_DEBUG_DPLANE) - zlog_debug("Zebra dataplane pre-fini called"); + zlog_debug("Zebra dataplane pre-finish called"); zdplane_info.dg_is_shutdown = true; /* Notify provider(s) of pending shutdown. */ - TAILQ_FOREACH(dp, &zdplane_info.dg_providers_q, dp_prov_link) { - if (dp->dp_fini == NULL) + TAILQ_FOREACH(prov, &zdplane_info.dg_providers_q, dp_prov_link) { + if (prov->dp_fini == NULL) continue; - dp->dp_fini(dp, true); + prov->dp_fini(prov, true /* early */); } } @@ -4337,7 +4397,10 @@ void zebra_dplane_shutdown(void) zdplane_info.dg_pthread = NULL; zdplane_info.dg_master = NULL; - /* Notify provider(s) of final shutdown. */ + /* Notify provider(s) of final shutdown. + * Note that this call is in the main pthread, so providers must + * be prepared for that. + */ TAILQ_FOREACH(dp, &zdplane_info.dg_providers_q, dp_prov_link) { if (dp->dp_fini == NULL) continue; |
