diff options
Diffstat (limited to 'zebra/zebra_dplane.c')
| -rw-r--r-- | zebra/zebra_dplane.c | 82 |
1 files changed, 68 insertions, 14 deletions
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 5864471b64..63d55d061d 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -513,15 +513,26 @@ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx) { zebra_nhlfe_t *nhlfe; - /* Free allocated NHLFEs */ - frr_each_safe(nhlfe_list, &ctx->u.lsp.nhlfe_list, nhlfe) - zebra_mpls_nhlfe_del(nhlfe); + /* Unlink and free allocated NHLFEs */ + frr_each_safe(nhlfe_list, &ctx->u.lsp.nhlfe_list, nhlfe) { + nhlfe_list_del(&ctx->u.lsp.nhlfe_list, nhlfe); + zebra_mpls_nhlfe_free(nhlfe); + } + + /* Unlink and free allocated backup NHLFEs, if present */ + frr_each_safe(nhlfe_list, + &(ctx->u.lsp.backup_nhlfe_list), nhlfe) { + nhlfe_list_del(&ctx->u.lsp.backup_nhlfe_list, + nhlfe); + zebra_mpls_nhlfe_free(nhlfe); + } - /* Clear pointers in lsp struct, in case we're cacheing + /* Clear pointers in lsp struct, in case we're caching * free context structs. */ nhlfe_list_init(&ctx->u.lsp.nhlfe_list); ctx->u.lsp.best_nhlfe = NULL; + nhlfe_list_init(&ctx->u.lsp.backup_nhlfe_list); break; } @@ -1222,6 +1233,13 @@ const struct nhlfe_list_head *dplane_ctx_get_nhlfe_list( return &(ctx->u.lsp.nhlfe_list); } +const struct nhlfe_list_head *dplane_ctx_get_backup_nhlfe_list( + const struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + return &(ctx->u.lsp.backup_nhlfe_list); +} + zebra_nhlfe_t *dplane_ctx_add_nhlfe(struct zebra_dplane_ctx *ctx, enum lsp_types_t lsp_type, enum nexthop_types_t nh_type, @@ -1241,6 +1259,26 @@ zebra_nhlfe_t *dplane_ctx_add_nhlfe(struct zebra_dplane_ctx *ctx, return nhlfe; } +zebra_nhlfe_t *dplane_ctx_add_backup_nhlfe(struct zebra_dplane_ctx *ctx, + enum lsp_types_t lsp_type, + enum nexthop_types_t nh_type, + union g_addr *gate, + ifindex_t ifindex, + uint8_t num_labels, + mpls_label_t *out_labels) +{ + zebra_nhlfe_t *nhlfe; + + DPLANE_CTX_VALID(ctx); + + nhlfe = zebra_mpls_lsp_add_backup_nhlfe(&(ctx->u.lsp), + lsp_type, nh_type, gate, + ifindex, num_labels, + out_labels); + + return nhlfe; +} + const zebra_nhlfe_t * dplane_ctx_get_best_nhlfe(const struct zebra_dplane_ctx *ctx) { @@ -1728,6 +1766,7 @@ static int dplane_ctx_lsp_init(struct zebra_dplane_ctx *ctx, memset(&ctx->u.lsp, 0, sizeof(ctx->u.lsp)); nhlfe_list_init(&(ctx->u.lsp.nhlfe_list)); + nhlfe_list_init(&(ctx->u.lsp.backup_nhlfe_list)); ctx->u.lsp.ile = lsp->ile; ctx->u.lsp.addr_family = lsp->addr_family; ctx->u.lsp.num_ecmp = lsp->num_ecmp; @@ -1739,16 +1778,8 @@ static int dplane_ctx_lsp_init(struct zebra_dplane_ctx *ctx, if (nhlfe->nexthop == NULL) continue; - new_nhlfe = - zebra_mpls_lsp_add_nhlfe( - &(ctx->u.lsp), - nhlfe->type, - nhlfe->nexthop->type, - &(nhlfe->nexthop->gate), - nhlfe->nexthop->ifindex, - nhlfe->nexthop->nh_label->num_labels, - nhlfe->nexthop->nh_label->label); - + new_nhlfe = zebra_mpls_lsp_add_nh(&(ctx->u.lsp), nhlfe->type, + nhlfe->nexthop); if (new_nhlfe == NULL || new_nhlfe->nexthop == NULL) { ret = ENOMEM; break; @@ -1762,9 +1793,32 @@ static int dplane_ctx_lsp_init(struct zebra_dplane_ctx *ctx, ctx->u.lsp.best_nhlfe = new_nhlfe; } + if (ret != AOK) + goto done; + + /* Capture backup nhlfes/nexthops */ + frr_each(nhlfe_list, &lsp->backup_nhlfe_list, nhlfe) { + /* Not sure if this is meaningful... */ + if (nhlfe->nexthop == NULL) + continue; + + new_nhlfe = zebra_mpls_lsp_add_backup_nh(&(ctx->u.lsp), + nhlfe->type, + nhlfe->nexthop); + if (new_nhlfe == NULL || new_nhlfe->nexthop == NULL) { + ret = ENOMEM; + break; + } + + /* Need to copy flags too */ + new_nhlfe->flags = nhlfe->flags; + new_nhlfe->nexthop->flags = nhlfe->nexthop->flags; + } + /* On error the ctx will be cleaned-up, so we don't need to * deal with any allocated nhlfe or nexthop structs here. */ +done: return ret; } |
