diff options
Diffstat (limited to 'zebra')
-rw-r--r-- | zebra/zebra_nhg.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index 4763d7741..1354f6813 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. */ |