]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: add basic nexthop comparison api
authorMark Stapp <mjs@voltanet.io>
Mon, 29 Mar 2021 20:09:40 +0000 (16:09 -0400)
committerMark Stapp <mjs@voltanet.io>
Tue, 4 May 2021 19:51:01 +0000 (15:51 -0400)
Add a simpler, more limited nexthop comparison function. This
compares a few key attributes, such as vrf, gateway, labels.

Signed-off-by: Mark Stapp <mjs@voltanet.io>
lib/nexthop.c
lib/nexthop.h

index 6b15442a87f26704740aaf21b84dca4ab88343fb..0ac6c0ae1b0eec87cb5989b05337f4cf9029cabe 100644 (file)
@@ -203,6 +203,105 @@ int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2)
        return ret;
 }
 
+/*
+ * More-limited comparison function used to detect duplicate
+ * nexthops. This is used in places where we don't need the full
+ * comparison of 'nexthop_cmp()'.
+ */
+int nexthop_cmp_basic(const struct nexthop *nh1,
+                     const struct nexthop *nh2)
+{
+       int ret = 0;
+       const struct mpls_label_stack *nhl1 = NULL;
+       const struct mpls_label_stack *nhl2 = NULL;
+
+       if (nh1 == NULL && nh2 == NULL)
+               return 0;
+
+       if (nh1 && !nh2)
+               return 1;
+
+       if (!nh1 && nh2)
+               return -1;
+
+       if (nh1->vrf_id < nh2->vrf_id)
+               return -1;
+
+       if (nh1->vrf_id > nh2->vrf_id)
+               return 1;
+
+       if (nh1->type < nh2->type)
+               return -1;
+
+       if (nh1->type > nh2->type)
+               return 1;
+
+       if (nh1->weight < nh2->weight)
+               return -1;
+
+       if (nh1->weight > nh2->weight)
+               return 1;
+
+       switch (nh1->type) {
+       case NEXTHOP_TYPE_IPV4:
+       case NEXTHOP_TYPE_IPV6:
+               ret = nexthop_g_addr_cmp(nh1->type, &nh1->gate, &nh2->gate);
+               if (ret != 0)
+                       return ret;
+               break;
+       case NEXTHOP_TYPE_IPV4_IFINDEX:
+       case NEXTHOP_TYPE_IPV6_IFINDEX:
+               ret = nexthop_g_addr_cmp(nh1->type, &nh1->gate, &nh2->gate);
+               if (ret != 0)
+                       return ret;
+               /* Intentional Fall-Through */
+       case NEXTHOP_TYPE_IFINDEX:
+               if (nh1->ifindex < nh2->ifindex)
+                       return -1;
+
+               if (nh1->ifindex > nh2->ifindex)
+                       return 1;
+               break;
+       case NEXTHOP_TYPE_BLACKHOLE:
+               if (nh1->bh_type < nh2->bh_type)
+                       return -1;
+
+               if (nh1->bh_type > nh2->bh_type)
+                       return 1;
+               break;
+       }
+
+       /* Compare source addr */
+       ret = nexthop_g_addr_cmp(nh1->type, &nh1->src, &nh2->src);
+       if (ret != 0)
+               goto done;
+
+       nhl1 = nh1->nh_label;
+       nhl2 = nh2->nh_label;
+
+       /* No labels is a match */
+       if (!nhl1 && !nhl2)
+               return 0;
+
+       if (nhl1 && !nhl2)
+               return 1;
+
+       if (nhl2 && !nhl1)
+               return -1;
+
+       if (nhl1->num_labels > nhl2->num_labels)
+               return 1;
+
+       if (nhl1->num_labels < nhl2->num_labels)
+               return -1;
+
+       ret = memcmp(nhl1->label, nhl2->label,
+                    (nhl1->num_labels * sizeof(mpls_label_t)));
+
+done:
+       return ret;
+}
+
 /*
  * nexthop_type_to_str
  */
index f1ad195cf4cfbe67b9efe5553d2aa1fe500cab3b..d6ea83cf0614db530f8fc0f8be486a1569510311 100644 (file)
@@ -207,6 +207,11 @@ extern int nexthop_g_addr_cmp(enum nexthop_types_t type,
                              const union g_addr *addr1,
                              const union g_addr *addr2);
 
+/* More-limited comparison function used to detect duplicate nexthops.
+ * Returns -1, 0, 1
+ */
+int nexthop_cmp_basic(const struct nexthop *nh1, const struct nexthop *nh2);
+
 extern const char *nexthop_type_to_str(enum nexthop_types_t nh_type);
 extern bool nexthop_labels_match(const struct nexthop *nh1,
                                 const struct nexthop *nh2);