I noticed that the order generated in an RB tree using flowspec_cmp() is reversed. The problem is that for addresses preferred means smaller. I think it is best to change the flowspec_cmp function to sort data so that RB_FOREACH will print them most-preferred to least-preferred.
I had not caught this oversight until I started to really test all the bits an pieces. -- :wq Claudio Index: flowspec.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/flowspec.c,v retrieving revision 1.1 diff -u -p -r1.1 flowspec.c --- flowspec.c 17 Apr 2023 08:02:21 -0000 1.1 +++ flowspec.c 17 Apr 2023 16:50:59 -0000 @@ -91,7 +91,7 @@ flowspec_next_component(const uint8_t *b /* * Compare two IPv4 flowspec prefix components. - * Returns 1 if first prefix is preferred, -1 if second, 0 if equal. + * Returns -1 if first prefix is preferred, 1 if second, 0 if equal. */ static int flowspec_cmp_prefix4(const uint8_t *abuf, int ablen, const uint8_t *bbuf, @@ -113,15 +113,15 @@ flowspec_cmp_prefix4(const uint8_t *abuf /* lowest IP value has precedence */ cmp = memcmp(a, b, sizeof(a)); if (cmp < 0) - return 1; - if (cmp > 0) return -1; + if (cmp > 0) + return 1; /* if common prefix, more specific route has precedence */ if (alen > blen) - return 1; - if (alen < blen) return -1; + if (alen < blen) + return 1; return 0; } @@ -139,9 +139,9 @@ flowspec_cmp_prefix6(const uint8_t *abuf /* lowest offset has precedence */ if (abuf[2] < bbuf[2]) - return 1; - if (abuf[2] > bbuf[2]) return -1; + if (abuf[2] > bbuf[2]) + return 1; /* calculate actual pattern size (len - offset) */ alen = abuf[1] - abuf[2]; @@ -157,15 +157,15 @@ flowspec_cmp_prefix6(const uint8_t *abuf /* lowest IP value has precedence */ cmp = memcmp(a, b, sizeof(a)); if (cmp < 0) - return 1; - if (cmp > 0) return -1; + if (cmp > 0) + return 1; /* if common prefix, more specific route has precedence */ if (alen > blen) - return 1; - if (alen < blen) return -1; + if (alen < blen) + return 1; return 0; } @@ -199,7 +199,7 @@ flowspec_valid(const uint8_t *buf, int l /* * Compare two valid flowspec NLRI objects according to RFC 8955 & 8956. - * Returns 1 if the first object has preference, -1 if not, and 0 if the + * Returns -1 if the first object has preference, 1 if not, and 0 if the * two objects are equal. */ int @@ -219,9 +219,9 @@ flowspec_cmp(const uint8_t *a, int alen, /* If types differ, lowest type wins. */ if (atype < btype) - return 1; - if (atype > btype) return -1; + if (atype > btype) + return 1; switch (atype) { case FLOWSPEC_TYPE_DEST: @@ -244,9 +244,9 @@ flowspec_cmp(const uint8_t *a, int alen, * string has precedence. */ if (cmp < 0) - return 1; - if (cmp > 0) return -1; + if (cmp > 0) + return 1; /* * Longest component wins when common prefix is equal. * This is not really possible because EOL encoding will @@ -254,9 +254,9 @@ flowspec_cmp(const uint8_t *a, int alen, * it (and it is cheap). */ if (acomplen > bcomplen) - return 1; - if (acomplen < bcomplen) return -1; + if (acomplen < bcomplen) + return 1; break; } a += acomplen; @@ -266,9 +266,9 @@ flowspec_cmp(const uint8_t *a, int alen, /* Rule with more components wins */ if (alen > 0 && blen <= 0) - return 1; - if (alen <= 0 && blen > 0) return -1; + if (alen <= 0 && blen > 0) + return 1; } return 0; }