]> 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 d2ab70e209276f109f5933d71468a4dd821d1d4c..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"
 #include "jhash.h"
 #include "printfrr.h"
 #include "vrf.h"
+#include "nexthop_group.h"
 
 DEFINE_MTYPE_STATIC(LIB, NEXTHOP, "Nexthop")
 DEFINE_MTYPE_STATIC(LIB, NH_LABEL, "Nexthop label")
@@ -154,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;
 }
 
@@ -239,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.
@@ -392,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;
@@ -401,23 +417,26 @@ 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;
 }
 
 /* Free label information of nexthop, if present. */
 void nexthop_del_labels(struct nexthop *nexthop)
 {
-       if (nexthop->nh_label) {
-               XFREE(MTYPE_NH_LABEL, nexthop->nh_label);
-               nexthop->nh_label_type = ZEBRA_LSP_NONE;
-       }
+       XFREE(MTYPE_NH_LABEL, nexthop->nh_label);
+       nexthop->nh_label_type = ZEBRA_LSP_NONE;
 }
 
 const char *nexthop2str(const struct nexthop *nexthop, char *str, int size)
@@ -504,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);
@@ -533,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;
@@ -565,14 +589,16 @@ uint32_t nexthop_hash(const struct nexthop *nexthop)
        return key;
 }
 
-void nexthop_copy(struct nexthop *copy, const struct nexthop *nexthop,
-                 struct nexthop *rparent)
+void nexthop_copy_no_recurse(struct nexthop *copy,
+                            const struct nexthop *nexthop,
+                            struct nexthop *rparent)
 {
        copy->vrf_id = nexthop->vrf_id;
        copy->ifindex = nexthop->ifindex;
        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));
@@ -583,6 +609,28 @@ void nexthop_copy(struct nexthop *copy, const struct nexthop *nexthop,
                                   &nexthop->nh_label->label[0]);
 }
 
+void nexthop_copy(struct nexthop *copy, const struct nexthop *nexthop,
+                 struct nexthop *rparent)
+{
+       nexthop_copy_no_recurse(copy, nexthop, rparent);
+
+       /* Bit of a special case here, we need to handle the case
+        * of a nexthop resolving to agroup. Hence, we need to
+        * use a nexthop_group API.
+        */
+       if (CHECK_FLAG(copy->flags, NEXTHOP_FLAG_RECURSIVE))
+               copy_nexthops(&copy->resolved, nexthop->resolved, copy);
+}
+
+struct nexthop *nexthop_dup_no_recurse(const struct nexthop *nexthop,
+                                      struct nexthop *rparent)
+{
+       struct nexthop *new = nexthop_new();
+
+       nexthop_copy_no_recurse(new, nexthop, rparent);
+       return new;
+}
+
 struct nexthop *nexthop_dup(const struct nexthop *nexthop,
                            struct nexthop *rparent)
 {