]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: include inner labels with recursive backups
authorMark Stapp <mjs@voltanet.io>
Thu, 1 Apr 2021 15:56:30 +0000 (11:56 -0400)
committerMark Stapp <mjs@voltanet.io>
Wed, 21 Apr 2021 18:30:15 +0000 (14:30 -0400)
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 <mjs@voltanet.io>
zebra/zebra_nhg.c

index 4763d774135cfe005a8f75ef79aa9b5df331a19c..1354f681317128ef53aee4a23ef7218ff2a79a5c 100644 (file)
@@ -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.
                 */