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