diff options
| author | Mark Stapp <mjs@voltanet.io> | 2021-03-29 16:09:40 -0400 | 
|---|---|---|
| committer | Mark Stapp <mjs@voltanet.io> | 2021-05-04 15:51:01 -0400 | 
| commit | 338ec3b86723f19bc43df9899e345811ad5f80d0 (patch) | |
| tree | f31790b798509d1ec8f5134e5c44e4e990da4b03 /lib | |
| parent | 26dddc01a885c3d1369e124b84afa08af817d830 (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.c | 99 | ||||
| -rw-r--r-- | lib/nexthop.h | 5 | 
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);  | 
