summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMark Stapp <mjs@voltanet.io>2021-03-29 16:09:40 -0400
committerMark Stapp <mjs@voltanet.io>2021-05-04 15:51:01 -0400
commit338ec3b86723f19bc43df9899e345811ad5f80d0 (patch)
treef31790b798509d1ec8f5134e5c44e4e990da4b03 /lib
parent26dddc01a885c3d1369e124b84afa08af817d830 (diff)
lib: add basic nexthop comparison api
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>
Diffstat (limited to 'lib')
-rw-r--r--lib/nexthop.c99
-rw-r--r--lib/nexthop.h5
2 files changed, 104 insertions, 0 deletions
diff --git a/lib/nexthop.c b/lib/nexthop.c
index 6b15442a87..0ac6c0ae1b 100644
--- a/lib/nexthop.c
+++ b/lib/nexthop.c
@@ -204,6 +204,105 @@ int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2)
}
/*
+ * 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
*/
const char *nexthop_type_to_str(enum nexthop_types_t nh_type)
diff --git a/lib/nexthop.h b/lib/nexthop.h
index f1ad195cf4..d6ea83cf06 100644
--- a/lib/nexthop.h
+++ b/lib/nexthop.h
@@ -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);