From c56c16eb2c5c1cd6075c5a01335b5942514ef9d6 Mon Sep 17 00:00:00 2001 From: Mark Stapp Date: Wed, 24 Mar 2021 15:01:50 -0400 Subject: [PATCH 1/3] zebra: fix some issues in recursive backup nexthop code Fix a couple of small things in the code that captures backup nexthops during recursive resolution. Signed-off-by: Mark Stapp --- zebra/zebra_nhg.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index 7edf022892..4763d77413 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -1814,9 +1814,6 @@ static int resolve_backup_nexthops(const struct nexthop *nexthop, assert(nexthop->backup_num <= NEXTHOP_MAX_BACKUPS); - if (resolve_nhe->backup_info->nhe == NULL) - resolve_nhe->backup_info->nhe = zebra_nhg_alloc(); - /* Locate backups from the original nexthop's backup index and nhe */ for (i = 0; i < nexthop->backup_num; i++) { idx = nexthop->backup_idx[i]; @@ -1832,6 +1829,8 @@ static int resolve_backup_nexthops(const struct nexthop *nexthop, map->map[j].new_idx; resolved->backup_num++; + SET_FLAG(resolved->flags, NEXTHOP_FLAG_HAS_BACKUP); + if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug("%s: found map idx orig %d, new %d", __func__, map->map[j].orig_idx, @@ -1856,6 +1855,9 @@ static int resolve_backup_nexthops(const struct nexthop *nexthop, if (bnh == NULL) continue; + if (resolve_nhe->backup_info == NULL) + resolve_nhe->backup_info = zebra_nhg_backup_alloc(); + /* Update backup info in the resolving nexthop and its nhe */ newnh = nexthop_dup_no_recurse(bnh, NULL); @@ -1871,6 +1873,7 @@ static int resolve_backup_nexthops(const struct nexthop *nexthop, } nh->next = newnh; + j++; } else /* First one */ resolve_nhe->backup_info->nhe->nhg.nexthop = newnh; @@ -1879,6 +1882,8 @@ static int resolve_backup_nexthops(const struct nexthop *nexthop, resolved->backup_idx[resolved->backup_num] = j; resolved->backup_num++; + SET_FLAG(resolved->flags, NEXTHOP_FLAG_HAS_BACKUP); + if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug("%s: added idx orig %d, new %d", __func__, idx, j); From a082cd9a5107cef5e51783228c7259b472d35424 Mon Sep 17 00:00:00 2001 From: Mark Stapp Date: Thu, 1 Apr 2021 11:56:30 -0400 Subject: [PATCH 2/3] zebra: include inner labels with recursive backups When capturing backup nexthops with recursive resolution, ensure that inner labels from the recursive nexthop are included in each backup (as they are with the resolving primary nexthops). Signed-off-by: Mark Stapp --- zebra/zebra_nhg.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index 4763d77413..1354f68131 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -1811,6 +1811,8 @@ static int resolve_backup_nexthops(const struct nexthop *nexthop, int i, j, idx; const struct nexthop *bnh; struct nexthop *nh, *newnh; + mpls_label_t labels[MPLS_MAX_LABELS]; + uint8_t num_labels; assert(nexthop->backup_num <= NEXTHOP_MAX_BACKUPS); @@ -1861,6 +1863,40 @@ static int resolve_backup_nexthops(const struct nexthop *nexthop, /* Update backup info in the resolving nexthop and its nhe */ newnh = nexthop_dup_no_recurse(bnh, NULL); + /* We may need some special handling for mpls labels: the new + * backup needs to carry the recursive nexthop's labels, + * if any: they may be vrf labels e.g. + * The original/inner labels are in the stack of 'resolve_nhe', + * if that is longer than the stack in 'nexthop'. + */ + if (newnh->nh_label && resolved->nh_label && + nexthop->nh_label) { + if (resolved->nh_label->num_labels > + nexthop->nh_label->num_labels) { + /* Prepare new label stack */ + num_labels = 0; + for (j = 0; j < newnh->nh_label->num_labels; + j++) { + labels[j] = newnh->nh_label->label[j]; + num_labels++; + } + + /* Include inner labels */ + for (j = nexthop->nh_label->num_labels; + j < resolved->nh_label->num_labels; + j++) { + labels[num_labels] = + resolved->nh_label->label[j]; + num_labels++; + } + + /* Replace existing label stack in the backup */ + nexthop_del_labels(newnh); + nexthop_add_labels(newnh, bnh->nh_label_type, + num_labels, labels); + } + } + /* Need to compute the new backup index in the new * backup list, and add to map struct. */ From 8283551d3c8b45264492be1f416fce11f35e177a Mon Sep 17 00:00:00 2001 From: Mark Stapp Date: Thu, 25 Mar 2021 12:03:00 -0400 Subject: [PATCH 3/3] zebra: handle TE policy changes in LSP async notifs Handle SR-TE policy changes in the LSP async notification handler, as we do in the normal LSP dplane results handler. Signed-off-by: Mark Stapp --- zebra/zebra_mpls.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 6d42957b24..a923782bfe 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -2018,6 +2018,7 @@ void zebra_mpls_process_dplane_notify(struct zebra_dplane_ctx *ctx) int start_count = 0, end_count = 0; /* Installed counts */ bool changed_p = false; bool is_debug = (IS_ZEBRA_DEBUG_DPLANE | IS_ZEBRA_DEBUG_MPLS); + enum zebra_sr_policy_update_label_mode update_mode; if (is_debug) zlog_debug("LSP dplane notif, in-label %u", @@ -2091,10 +2092,21 @@ void zebra_mpls_process_dplane_notify(struct zebra_dplane_ctx *ctx) if (end_count > 0) { SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); + /* SR-TE update too */ + if (start_count == 0) + update_mode = ZEBRA_SR_POLICY_LABEL_CREATED; + else + update_mode = ZEBRA_SR_POLICY_LABEL_UPDATED; + zebra_sr_policy_label_update(lsp->ile.in_label, update_mode); + if (changed_p) dplane_lsp_notif_update(lsp, DPLANE_OP_LSP_UPDATE, ctx); } else { + /* SR-TE update too */ + zebra_sr_policy_label_update(lsp->ile.in_label, + ZEBRA_SR_POLICY_LABEL_REMOVED); + UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); clear_nhlfe_installed(lsp); }