]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/nexthop.c
Merge pull request #6279 from opensourcerouting/nb-cb-args
[mirror_frr.git] / lib / nexthop.c
index c3be0a71e67aa9ece57a89c05cad0287c410202b..0d239e091b5ea71a2d7a0ea2f62d3ba91e604358 100644 (file)
 #include "table.h"
 #include "memory.h"
 #include "command.h"
-#include "if.h"
 #include "log.h"
 #include "sockunion.h"
 #include "linklist.h"
-#include "thread.h"
 #include "prefix.h"
 #include "nexthop.h"
 #include "mpls.h"
@@ -155,7 +153,24 @@ static int _nexthop_cmp_no_labels(const struct nexthop *next1,
        }
 
        ret = _nexthop_source_cmp(next1, next2);
+       if (ret != 0)
+               goto done;
+
+       if (!CHECK_FLAG(next1->flags, NEXTHOP_FLAG_HAS_BACKUP) &&
+           CHECK_FLAG(next2->flags, NEXTHOP_FLAG_HAS_BACKUP))
+               return -1;
+
+       if (CHECK_FLAG(next1->flags, NEXTHOP_FLAG_HAS_BACKUP) &&
+           !CHECK_FLAG(next2->flags, NEXTHOP_FLAG_HAS_BACKUP))
+               return 1;
+
+       if (next1->backup_idx < next2->backup_idx)
+               return -1;
+
+       if (next1->backup_idx > next2->backup_idx)
+               return 1;
 
+done:
        return ret;
 }
 
@@ -240,7 +255,7 @@ struct nexthop *nexthop_new(void)
         * The linux kernel does some weird stuff with adding +1 to
         * all nexthop weights it gets over netlink.
         * To handle this, just default everything to 1 right from
-        * from the beggining so we don't have to special case
+        * from the beginning so we don't have to special case
         * default weights in the linux netlink code.
         *
         * 1 should be a valid on all platforms anyway.
@@ -393,8 +408,8 @@ struct nexthop *nexthop_from_blackhole(enum blackhole_type bh_type)
 }
 
 /* Update nexthop with label information. */
-void nexthop_add_labels(struct nexthop *nexthop, enum lsp_types_t type,
-                       uint8_t num_labels, mpls_label_t *label)
+void nexthop_add_labels(struct nexthop *nexthop, enum lsp_types_t ltype,
+                       uint8_t num_labels, const mpls_label_t *labels)
 {
        struct mpls_label_stack *nh_label;
        int i;
@@ -402,13 +417,18 @@ void nexthop_add_labels(struct nexthop *nexthop, enum lsp_types_t type,
        if (num_labels == 0)
                return;
 
-       nexthop->nh_label_type = type;
+       /* Enforce limit on label stack size */
+       if (num_labels > MPLS_MAX_LABELS)
+               num_labels = MPLS_MAX_LABELS;
+
+       nexthop->nh_label_type = ltype;
+
        nh_label = XCALLOC(MTYPE_NH_LABEL,
                           sizeof(struct mpls_label_stack)
                                   + num_labels * sizeof(mpls_label_t));
        nh_label->num_labels = num_labels;
        for (i = 0; i < num_labels; i++)
-               nh_label->label[i] = *(label + i);
+               nh_label->label[i] = *(labels + i);
        nexthop->nh_label = nh_label;
 }
 
@@ -503,6 +523,7 @@ unsigned int nexthop_level(struct nexthop *nexthop)
 uint32_t nexthop_hash_quick(const struct nexthop *nexthop)
 {
        uint32_t key = 0x45afe398;
+       uint32_t val;
 
        key = jhash_3words(nexthop->type, nexthop->vrf_id,
                           nexthop->nh_label_type, key);
@@ -532,8 +553,12 @@ uint32_t nexthop_hash_quick(const struct nexthop *nexthop)
                        key = jhash_1word(nexthop->nh_label->label[i], key);
        }
 
-       key = jhash_2words(nexthop->ifindex,
-                          CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK),
+       val = 0;
+       if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP))
+               val = (uint32_t)nexthop->backup_idx;
+
+       key = jhash_3words(nexthop->ifindex,
+                          CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK), val,
                           key);
 
        return key;
@@ -573,6 +598,7 @@ void nexthop_copy_no_recurse(struct nexthop *copy,
        copy->type = nexthop->type;
        copy->flags = nexthop->flags;
        copy->weight = nexthop->weight;
+       copy->backup_idx = nexthop->backup_idx;
        memcpy(&copy->gate, &nexthop->gate, sizeof(nexthop->gate));
        memcpy(&copy->src, &nexthop->src, sizeof(nexthop->src));
        memcpy(&copy->rmap_src, &nexthop->rmap_src, sizeof(nexthop->rmap_src));