Skip to content

Commit 1315d74

Browse files
committed
lib: fix prefix_cmp() return values
OMGWTFBBQ Signed-off-by: David Lamparter <equinox@diac24.net>
1 parent 51e75ed commit 1315d74

File tree

2 files changed

+23
-16
lines changed

2 files changed

+23
-16
lines changed

lib/compiler.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,13 @@ extern "C" {
165165
_min_a < _min_b ? _min_a : _min_b; \
166166
})
167167

168+
#define numcmp(a, b) \
169+
({ \
170+
typeof(a) _cmp_a = (a); \
171+
typeof(b) _cmp_b = (b); \
172+
(_cmp_a < _cmp_b) ? -1 : ((_cmp_a > _cmp_b) ? 1 : 0); \
173+
})
174+
168175
#ifndef offsetof
169176
#ifdef __compiler_offsetof
170177
#define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE,MEMBER)

lib/prefix.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -712,10 +712,11 @@ int prefix_same(const struct prefix *p1, const struct prefix *p2)
712712
}
713713

714714
/*
715-
* Return 0 if the network prefixes represented by the struct prefix
716-
* arguments are the same prefix, and 1 otherwise. Network prefixes
717-
* are considered the same if the prefix lengths are equal and the
718-
* network parts are the same. Host bits (which are considered masked
715+
* Return -1/0/1 comparing the prefixes in a way that gives a full/linear
716+
* order.
717+
*
718+
* Network prefixes are considered the same if the prefix lengths are equal
719+
* and the network parts are the same. Host bits (which are considered masked
719720
* by the prefix length) are not significant. Thus, 10.0.0.1/8 and
720721
* 10.0.0.2/8 are considered equivalent by this routine. Note that
721722
* this routine has the same return sense as strcmp (which is different
@@ -725,44 +726,43 @@ int prefix_cmp(const struct prefix *p1, const struct prefix *p2)
725726
{
726727
int offset;
727728
int shift;
729+
int i;
728730

729731
/* Set both prefix's head pointer. */
730732
const uint8_t *pp1;
731733
const uint8_t *pp2;
732734

733735
if (p1->family != p2->family)
734-
return 1;
736+
return numcmp(p1->family, p2->family);
735737
if (p1->family == AF_FLOWSPEC) {
736738
pp1 = (const uint8_t *)p1->u.prefix_flowspec.ptr;
737739
pp2 = (const uint8_t *)p2->u.prefix_flowspec.ptr;
738740

739741
if (p1->u.prefix_flowspec.prefixlen !=
740742
p2->u.prefix_flowspec.prefixlen)
741-
return 1;
743+
return numcmp(p1->u.prefix_flowspec.prefixlen,
744+
p2->u.prefix_flowspec.prefixlen);
742745

743746
offset = p1->u.prefix_flowspec.prefixlen;
744747
while (offset--)
745748
if (pp1[offset] != pp2[offset])
746-
return 1;
749+
return numcmp(pp1[offset], pp2[offset]);
747750
return 0;
748751
}
749752
pp1 = p1->u.val;
750753
pp2 = p2->u.val;
751754

752755
if (p1->prefixlen != p2->prefixlen)
753-
return 1;
756+
return numcmp(p1->prefixlen, p2->prefixlen);
754757
offset = p1->prefixlen / PNBBY;
755758
shift = p1->prefixlen % PNBBY;
756759

757-
if (shift)
758-
if (maskbit[shift] & (pp1[offset] ^ pp2[offset]))
759-
return 1;
760-
761-
while (offset--)
762-
if (pp1[offset] != pp2[offset])
763-
return 1;
760+
i = memcmp(pp1, pp2, offset);
761+
if (i)
762+
return i;
764763

765-
return 0;
764+
return numcmp(pp1[offset] & maskbit[shift],
765+
pp2[offset] & maskbit[shift]);
766766
}
767767

768768
/*

0 commit comments

Comments
 (0)