This diff extends the existing trie code for prefix-set to also work with roa-set. Unlike prefix-set there is no need for a prefixlen mask during lookup, instead the source-as needs to be checked and also if the prefixlen of the prefix is allowed. The lookup can return 3 states: ROA_UNKNONW: prefix is not covered by any entry ROA_VALID: prefix is covered and the source-as matches as does the prefixlen ROA_INVALID: there was a covering ROA entry that did not match source-as or prefixlen The source-as check is done with an as_set and should therefor scale well. In general these lookups need to be quick since all prefixes will go through roa lookups.
The frontend code (parse.y and imsg passing) is missing, since this is already fairly large and it is tested by the unit tests I decided to send this out as an idividual step. Cheers -- :wq Claudio Index: usr.sbin/bgpd/bgpd.h =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v retrieving revision 1.340 diff -u -p -r1.340 bgpd.h --- usr.sbin/bgpd/bgpd.h 14 Sep 2018 10:22:11 -0000 1.340 +++ usr.sbin/bgpd/bgpd.h 14 Sep 2018 14:08:49 -0000 @@ -952,6 +952,11 @@ struct filter_set { enum action_types type; }; +struct roa_set { + u_int32_t as; /* must be first */ + u_int32_t maxlen; /* change type for better struct layout */ +}; + struct prefixset_item { struct filter_prefix p; SIMPLEQ_ENTRY(prefixset_item) entry; Index: usr.sbin/bgpd/rde.h =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v retrieving revision 1.190 diff -u -p -r1.190 rde.h --- usr.sbin/bgpd/rde.h 9 Sep 2018 12:33:51 -0000 1.190 +++ usr.sbin/bgpd/rde.h 14 Sep 2018 14:08:22 -0000 @@ -36,6 +36,12 @@ enum peer_state { PEER_ERR /* error occurred going to PEER_DOWN state */ }; +enum roa_state { + ROA_UNKNOWN, + ROA_INVALID, + ROA_VALID +}; + /* * How do we identify peers between the session handler and the rde? * Currently I assume that we can do that with the neighbor_ip... @@ -332,7 +338,8 @@ struct rde_prefixset { char name[SET_NAME_LEN]; struct trie_head th; SIMPLEQ_ENTRY(rde_prefixset) entry; - int dirty; + int dirty; + int roa; }; SIMPLEQ_HEAD(rde_prefixset_head, rde_prefixset); @@ -578,8 +585,12 @@ int up_dump_mp_reach(u_char *, u_int16 /* rde_trie.c */ int trie_add(struct trie_head *, struct bgpd_addr *, u_int8_t, u_int8_t, u_int8_t); +int trie_roa_add(struct trie_head *, struct bgpd_addr *, u_int8_t, + struct as_set *); void trie_free(struct trie_head *); int trie_match(struct trie_head *, struct bgpd_addr *, u_int8_t, int); +int trie_roa_check(struct trie_head *, struct bgpd_addr *, u_int8_t, + u_int32_t); void trie_dump(struct trie_head *); int trie_equal(struct trie_head *, struct trie_head *); Index: usr.sbin/bgpd/rde_trie.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/rde_trie.c,v retrieving revision 1.5 diff -u -p -r1.5 rde_trie.c --- usr.sbin/bgpd/rde_trie.c 10 Sep 2018 13:15:50 -0000 1.5 +++ usr.sbin/bgpd/rde_trie.c 14 Sep 2018 14:08:22 -0000 @@ -57,22 +57,20 @@ */ struct tentry_v4 { struct tentry_v4 *trie[2]; + struct as_set *aset; /* for roa source-as set */ struct in_addr addr; struct in_addr plenmask; u_int8_t plen; u_int8_t node; - - /* roa source-as list pointer */ }; struct tentry_v6 { struct tentry_v6 *trie[2]; + struct as_set *aset; /* for roa source-as set */ struct in6_addr addr; struct in6_addr plenmask; u_int8_t plen; u_int8_t node; - - /* roa source-as list pointer */ }; /* @@ -143,37 +141,14 @@ inet6setbit(struct in6_addr *addr, u_int addr->s6_addr[bit / 8] |= (0x80 >> (bit % 8)); } -static int -trie_add_v4(struct trie_head *th, struct in_addr *prefix, u_int8_t plen, - u_int8_t min, u_int8_t max) +static struct tentry_v4 * +trie_add_v4(struct trie_head *th, struct in_addr *prefix, u_int8_t plen) { struct tentry_v4 *n, *new, *b, **prev; - struct in_addr p, plenmask; - u_int8_t i; - - /* - * check for default route, this is special cased since prefixlen 0 - * can't be checked in the prefixlen mask plenmask. Also there is only - * one default route so using a flag for this works. - */ - if (min == 0) { - th->match_default_v4 = 1; - if (max == 0) /* just the default route */ - return 0; - min = 1; - } + struct in_addr p; inet4applymask(&p, prefix, plen); - /* - * The prefixlen mask goes from 1 to 32 but the bitmask - * starts at 0 and so all bits are set with an offset of 1. - * The default /0 route is handled specially above. - */ - memset(&plenmask, 0, sizeof(plenmask)); - for (i = min; i <= max; i++) - inet4setbit(&plenmask, i - 1); - /* walk tree finding spot to insert */ prev = &th->root_v4; n = *prev; @@ -189,7 +164,7 @@ trie_add_v4(struct trie_head *th, struct * np and n, then insert n and new node there */ if ((b = calloc(1, sizeof(*b))) == NULL) - return -1; + return NULL; b->plen = inet4findmsb(&n->addr, &mp); inet4applymask(&b->addr, &n->addr, b->plen); @@ -213,8 +188,7 @@ trie_add_v4(struct trie_head *th, struct if (n->plen == plen) { /* matching node, adjust */ n->node = 1; - n->plenmask.s_addr |= plenmask.s_addr; - return 0; + return n; } /* no need to check for n->plen == 32 because of above if */ @@ -227,10 +201,9 @@ trie_add_v4(struct trie_head *th, struct /* create new node */ if ((new = calloc(1, sizeof(*new))) == NULL) - return -1; + return NULL; new->addr = p; new->plen = plen; - new->plenmask = plenmask; new->node = 1; /* link node */ @@ -241,40 +214,17 @@ trie_add_v4(struct trie_head *th, struct else new->trie[0] = n; } - return 0; + return new; } -static int -trie_add_v6(struct trie_head *th, struct in6_addr *prefix, u_int8_t plen, - u_int8_t min, u_int8_t max) +static struct tentry_v6 * +trie_add_v6(struct trie_head *th, struct in6_addr *prefix, u_int8_t plen) { struct tentry_v6 *n, *new, *b, **prev; - struct in6_addr p, plenmask; - u_int8_t i; - - /* - * check for default route, this is special cased since prefixlen 0 - * can't be checked in the prefixlen mask plenmask. Also there is only - * one default route so using a flag for this works. - */ - if (min == 0) { - th->match_default_v6 = 1; - if (max == 0) /* just the default route */ - return 0; - min = 1; - } + struct in6_addr p; inet6applymask(&p, prefix, plen); - /* - * The prefixlen mask goes from 1 to 128 but the bitmask - * starts at 0 and so all bits are set with an offset of 1. - * The default /0 route is handled specially above. - */ - memset(&plenmask, 0, sizeof(plenmask)); - for (i = min; i <= max; i++) - inet6setbit(&plenmask, i - 1); - /* walk tree finding spot to insert */ prev = &th->root_v6; n = *prev; @@ -290,7 +240,7 @@ trie_add_v6(struct trie_head *th, struct * np and n, then insert n and new node there */ if ((b = calloc(1, sizeof(*b))) == NULL) - return -1; + return NULL; b->plen = inet6findmsb(&n->addr, &mp); inet6applymask(&b->addr, &n->addr, b->plen); @@ -314,9 +264,7 @@ trie_add_v6(struct trie_head *th, struct if (n->plen == plen) { /* matching node, adjust */ n->node = 1; - for (i = 0; i < sizeof(plenmask); i++) - n->plenmask.s6_addr[i] |= plenmask.s6_addr[i]; - return 0; + return n; } /* no need to check for n->plen == 128 because of above if */ @@ -329,10 +277,9 @@ trie_add_v6(struct trie_head *th, struct /* create new node */ if ((new = calloc(1, sizeof(*new))) == NULL) - return -1; + return NULL; new->addr = p; new->plen = plen; - new->plenmask = plenmask; new->node = 1; /* link node */ @@ -343,30 +290,125 @@ trie_add_v6(struct trie_head *th, struct else new->trie[0] = n; } - return 0; + return new; } +/* + * Insert prefix/plen into the trie with a prefixlen mask covering min - max. + * If plen == min == max then only the prefix/plen will match and no longer + * match is possible. Else all prefixes under prefix/plen with a prefixlen + * between min and max will match. + */ int trie_add(struct trie_head *th, struct bgpd_addr *prefix, u_int8_t plen, u_int8_t min, u_int8_t max) { + struct tentry_v4 *n4; + struct tentry_v6 *n6; + u_int8_t i; + /* precondition plen <= min <= max */ if (plen > min || min > max) return -1; + if (prefix->aid != AID_INET && prefix->aid != AID_INET6) + return -1; + + /* + * Check for default route, this is special cased since prefixlen 0 + * can't be checked in the prefixlen mask plenmask. Also there is + * only one default route so using a flag for this works. + */ + if (min == 0) { + if (prefix->aid == AID_INET) + th->match_default_v4 = 1; + else + th->match_default_v6 = 1; + + if (max == 0) /* just the default route */ + return 0; + min = 1; + } switch (prefix->aid) { case AID_INET: if (max > 32) return -1; - return trie_add_v4(th, &prefix->v4, plen, min, max); + + n4 = trie_add_v4(th, &prefix->v4, plen); + if (n4 == NULL) + return -1; + /* + * The prefixlen min - max goes from 1 to 32 but the bitmask + * starts at 0 and so all bits are set with an offset of -1. + * The default /0 route is handled specially above. + */ + for (i = min; i <= max; i++) + inet4setbit(&n4->plenmask, i - 1); + break; case AID_INET6: if (max > 128) return -1; - return trie_add_v6(th, &prefix->v6, plen, min, max); + + n6 = trie_add_v6(th, &prefix->v6, plen); + if (n6 == NULL) + return -1; + + /* See above for the - 1 reason. */ + for (i = min; i <= max; i++) + inet6setbit(&n6->plenmask, i - 1); + break; + } + return 0; +} + +/* + * Insert a ROA entry for prefix/plen. The prefix will insert an as_set with + * source_as and the maxlen as data. This makes it possible to validate if a + * prefix is matching this ROA record. It is possible to insert prefixes with + * source_as = 0. These entries will never return ROA_VALID on check and can + * be used to cover a large prefix as ROA_INVALID unless a more specific route + * is a match. + */ +int +trie_roa_add(struct trie_head *th, struct bgpd_addr *prefix, u_int8_t plen, + struct as_set *aset) +{ + struct tentry_v4 *n4; + struct tentry_v6 *n6; + struct as_set **ap; + + /* ignore possible default route since it does not make sense */ + + switch (prefix->aid) { + case AID_INET: + if (plen > 32) + return -1; + + n4 = trie_add_v4(th, &prefix->v4, plen); + if (n4 == NULL) + return -1; + ap = &n4->aset; + break; + case AID_INET6: + if (plen > 128) + return -1; + + n6 = trie_add_v6(th, &prefix->v6, plen); + if (n6 == NULL) + return -1; + ap = &n6->aset; + break; default: /* anything else fails */ return -1; } + + /* aset already set, error out */ + if (*ap != NULL) + return -1; + *ap = aset; + + return 0; } static void @@ -376,6 +418,7 @@ trie_free_v4(struct tentry_v4 *n) return; trie_free_v4(n->trie[0]); trie_free_v4(n->trie[1]); + as_set_free(n->aset); free(n); } @@ -386,6 +429,7 @@ trie_free_v6(struct tentry_v6 *n) return; trie_free_v6(n->trie[0]); trie_free_v6(n->trie[1]); + as_set_free(n->aset); free(n); } @@ -490,6 +534,123 @@ trie_match(struct trie_head *th, struct default: /* anything else is no match */ return 0; + } +} + +static int +trie_roa_check_v4(struct trie_head *th, struct in_addr *prefix, u_int8_t plen, + u_int32_t as) +{ + struct tentry_v4 *n; + struct roa_set *rs; + int validity = ROA_UNKNOWN; + + /* ignore possible default route since it does not make sense */ + + n = th->root_v4; + while (n) { + struct in_addr mp; + + if (n->plen > plen) + break; /* too specific, no match possible */ + + inet4applymask(&mp, prefix, n->plen); + if (n->addr.s_addr != mp.s_addr) + break; /* off path, no other match possible */ + + if (n->node) { + /* + * The prefix is covered by this roa node + * therefor invalid unless roa_set matches. + */ + validity = ROA_INVALID; + + /* Treat AS 0 as NONE which can never be matched */ + if (as != 0) { + rs = as_set_match(n->aset, as); + if (rs && plen <= rs->maxlen) + return ROA_VALID; + } + } + + if (n->plen == 32) + break; /* can't go deeper */ + if (inet4isset(prefix, n->plen)) + n = n->trie[1]; + else + n = n->trie[0]; + } + + return validity; +} + +static int +trie_roa_check_v6(struct trie_head *th, struct in6_addr *prefix, u_int8_t plen, + u_int32_t as) +{ + struct tentry_v6 *n; + struct roa_set *rs; + int validity = ROA_UNKNOWN; + + /* ignore possible default route since it does not make sense */ + + n = th->root_v6; + while (n) { + struct in6_addr mp; + + if (n->plen > plen) + break; /* too specific, no match possible */ + + inet6applymask(&mp, prefix, n->plen); + if (memcmp(&n->addr, &mp, sizeof(mp)) != 0) + break; /* off path, no other match possible */ + + if (n->node) { + /* + * This prefix is covered by this roa node. + * Therefor invalid unless proven otherwise. + */ + validity = ROA_INVALID; + + /* Treat AS 0 as NONE which can never be matched */ + if (as != 0) { + if ((rs = as_set_match(n->aset, as)) != NULL) + if (plen == n->plen || plen <= rs->maxlen) + return ROA_VALID; + } + } + + if (n->plen == 128) + break; /* can't go deeper */ + if (inet6isset(prefix, n->plen)) + n = n->trie[1]; + else + n = n->trie[0]; + } + + return validity; +} + +/* + * Do a ROA (Route Origin Validation) check. Look for elements in the trie + * which cover prefix "prefix/plen" and match the source-as as. + * AS 0 is treated here like AS NONE and should be used when the source-as + * is unknown (e.g. AS_SET). In other words the check will then only return + * ROA_UNKNOWN or ROA_INVALID depending if the prefix is covered by the ROA. + */ +int +trie_roa_check(struct trie_head *th, struct bgpd_addr *prefix, u_int8_t plen, + u_int32_t as) +{ + /* valid, invalid, unknow */ + switch (prefix->aid) { + case AID_INET: + return trie_roa_check_v4(th, &prefix->v4, plen, as); + case AID_INET6: + return trie_roa_check_v6(th, &prefix->v6, plen, as); + default: + /* anything else is unkown */ + return ROA_UNKNOWN; } } Index: regress/usr.sbin/bgpd/unittests/Makefile =================================================================== RCS file: /cvs/src/regress/usr.sbin/bgpd/unittests/Makefile,v retrieving revision 1.3 diff -u -p -r1.3 Makefile --- regress/usr.sbin/bgpd/unittests/Makefile 10 Sep 2018 20:51:59 -0000 1.3 +++ regress/usr.sbin/bgpd/unittests/Makefile 14 Sep 2018 14:10:05 -0000 @@ -18,13 +18,15 @@ run-regress-rde_sets_test: rde_sets_test ./rde_sets_test SRCS_rde_trie_test= rde_trie_test.c rde_trie.c util.c rde_sets.c -TRIE_TESTS=1 2 3 4 +TRIE_TESTS=1 2 3 4 5 +TRIE4_FLAGS=-o +TRIE5_FLAGS=-r .for n in ${TRIE_TESTS} TRIE_TARGETS+=run-regress-rde_trie_test-${n} run-regress-rde_trie_test-${n}: rde_trie_test - ./rde_trie_test ${.CURDIR}/rde_trie_test.${n}.in \ + ./rde_trie_test ${TRIE${n}_FLAGS} ${.CURDIR}/rde_trie_test.${n}.in \ ${.CURDIR}/rde_trie_test.${n}.check | \ diff -u ${.CURDIR}/rde_trie_test.${n}.out /dev/stdin .endfor Index: regress/usr.sbin/bgpd/unittests/rde_trie_test.1.out =================================================================== RCS file: /cvs/src/regress/usr.sbin/bgpd/unittests/rde_trie_test.1.out,v retrieving revision 1.2 diff -u -p -r1.2 rde_trie_test.1.out --- regress/usr.sbin/bgpd/unittests/rde_trie_test.1.out 10 Sep 2018 20:51:59 -0000 1.2 +++ regress/usr.sbin/bgpd/unittests/rde_trie_test.1.out 14 Sep 2018 14:10:05 -0000 @@ -1,11 +1,11 @@ -62.48.0.0/19 MATCH 0 -62.48.0.0/18 miss 0 -62.48.0.0/20 miss 0 -62.48.3.0/24 MATCH 0 -62.48.2.0/24 miss 0 -62.48.2.0/25 MATCH 0 -62.48.2.0/26 MATCH 0 -10.0.0.0/8 MATCH 0 -10.0.0.0/24 MATCH 0 -192.168.3.0/24 miss 0 -192.168.3.66/30 MATCH 0 +62.48.0.0/19 MATCH +62.48.0.0/18 miss +62.48.0.0/20 miss +62.48.3.0/24 MATCH +62.48.2.0/24 miss +62.48.2.0/25 MATCH +62.48.2.0/26 MATCH +10.0.0.0/8 MATCH +10.0.0.0/24 MATCH +192.168.3.0/24 miss +192.168.3.66/30 MATCH Index: regress/usr.sbin/bgpd/unittests/rde_trie_test.2.out =================================================================== RCS file: /cvs/src/regress/usr.sbin/bgpd/unittests/rde_trie_test.2.out,v retrieving revision 1.2 diff -u -p -r1.2 rde_trie_test.2.out --- regress/usr.sbin/bgpd/unittests/rde_trie_test.2.out 10 Sep 2018 20:51:59 -0000 1.2 +++ regress/usr.sbin/bgpd/unittests/rde_trie_test.2.out 14 Sep 2018 14:10:05 -0000 @@ -1,14 +1,14 @@ -46.21.0.0/20 MATCH 0 -87.253.240.0/20 MATCH 0 -185.108.8.0/22 MATCH 0 -193.41.124.0/23 MATCH 0 -195.110.26.0/23 MATCH 0 -213.135.192.0/21 MATCH 0 -2a01:7f8::/32 MATCH 0 -199.185.136.0/23 miss 0 -199.185.178.0/24 miss 0 -199.185.230.0/23 miss 0 -204.174.115.0/24 miss 0 -204.209.252.0/24 miss 0 -204.209.253.0/24 miss 0 -2620:3d:c000::/48 miss 0 +46.21.0.0/20 MATCH +87.253.240.0/20 MATCH +185.108.8.0/22 MATCH +193.41.124.0/23 MATCH +195.110.26.0/23 MATCH +213.135.192.0/21 MATCH +2a01:7f8::/32 MATCH +199.185.136.0/23 miss +199.185.178.0/24 miss +199.185.230.0/23 miss +204.174.115.0/24 miss +204.209.252.0/24 miss +204.209.253.0/24 miss +2620:3d:c000::/48 miss Index: regress/usr.sbin/bgpd/unittests/rde_trie_test.3.out =================================================================== RCS file: /cvs/src/regress/usr.sbin/bgpd/unittests/rde_trie_test.3.out,v retrieving revision 1.2 diff -u -p -r1.2 rde_trie_test.3.out --- regress/usr.sbin/bgpd/unittests/rde_trie_test.3.out 10 Sep 2018 20:51:59 -0000 1.2 +++ regress/usr.sbin/bgpd/unittests/rde_trie_test.3.out 14 Sep 2018 14:10:05 -0000 @@ -1,143 +1,143 @@ -82.130.64.0/18 MATCH 0 -86.119.0.0/16 MATCH 0 -89.206.64.0/18 MATCH 0 -128.178.0.0/15 MATCH 0 -129.129.0.0/16 MATCH 0 -129.132.0.0/16 MATCH 0 -129.194.0.0/15 MATCH 0 -130.59.0.0/16 MATCH 0 -130.60.0.0/16 MATCH 0 -130.82.0.0/16 MATCH 0 -130.92.0.0/16 MATCH 0 -130.125.0.0/16 MATCH 0 -130.223.0.0/16 MATCH 0 -131.152.0.0/16 MATCH 0 -134.21.0.0/16 MATCH 0 -138.131.0.0/16 MATCH 0 -141.249.0.0/16 MATCH 0 -144.200.0.0/16 MATCH 0 -146.136.0.0/16 MATCH 0 -147.86.0.0/16 MATCH 0 -147.87.0.0/16 MATCH 0 -147.88.0.0/16 MATCH 0 -148.187.0.0/16 MATCH 0 -148.196.0.0/16 MATCH 0 -152.88.0.0/16 MATCH 0 -152.96.0.0/16 MATCH 0 -153.109.0.0/16 MATCH 0 -155.105.0.0/16 MATCH 0 -155.228.0.0/16 MATCH 0 -156.25.0.0/16 MATCH 0 -156.135.0.0/21 MATCH 0 -156.135.12.0/22 MATCH 0 -156.135.16.0/21 MATCH 0 -156.135.28.0/22 MATCH 0 -156.135.32.0/19 MATCH 0 -156.135.64.0/18 MATCH 0 -156.135.128.0/17 MATCH 0 -157.26.0.0/16 MATCH 0 -160.85.0.0/16 MATCH 0 -160.98.0.0/16 MATCH 0 -161.62.0.0/16 MATCH 0 -185.51.68.0/22 MATCH 0 -185.133.44.0/22 MATCH 0 -185.144.36.0/22 MATCH 0 -185.194.180.0/22 MATCH 0 -185.225.92.0/22 MATCH 0 -192.12.247.0/24 MATCH 0 -192.26.28.0/22 MATCH 0 -192.26.32.0/21 MATCH 0 -192.26.40.0/22 MATCH 0 -192.26.44.0/24 MATCH 0 -192.26.46.0/23 MATCH 0 -192.33.87.0/24 MATCH 0 -192.33.88.0/21 MATCH 0 -192.33.96.0/21 MATCH 0 -192.33.104.0/22 MATCH 0 -192.33.108.0/23 MATCH 0 -192.33.110.0/24 MATCH 0 -192.33.118.0/23 MATCH 0 -192.33.120.0/21 MATCH 0 -192.33.192.0/19 MATCH 0 -192.33.224.0/21 MATCH 0 -192.41.132.0/22 MATCH 0 -192.41.136.0/24 MATCH 0 -192.41.149.0/24 MATCH 0 -192.41.150.0/23 MATCH 0 -192.41.152.0/21 MATCH 0 -192.41.160.0/24 MATCH 0 -192.42.42.0/23 MATCH 0 -192.42.44.0/22 MATCH 0 -192.42.180.0/22 MATCH 0 -192.42.184.0/21 MATCH 0 -192.42.192.0/21 MATCH 0 -192.42.200.0/23 MATCH 0 -192.43.192.0/22 MATCH 0 -192.43.196.0/24 MATCH 0 -192.47.244.0/22 MATCH 0 -192.47.248.0/23 MATCH 0 -192.65.92.0/23 MATCH 0 -192.101.176.0/24 MATCH 0 -192.135.150.0/23 MATCH 0 -192.135.151.0/24 MATCH 0 -192.135.152.0/21 MATCH 0 -192.152.98.0/24 MATCH 0 -193.5.22.0/24 MATCH 0 -193.5.26.0/23 MATCH 0 -193.5.54.0/23 MATCH 0 -193.5.58.0/24 MATCH 0 -193.5.60.0/24 MATCH 0 -193.5.80.0/21 MATCH 0 -193.5.152.0/22 MATCH 0 -193.5.168.0/22 MATCH 0 -193.5.180.0/24 MATCH 0 -193.5.182.0/24 MATCH 0 -193.5.186.0/24 MATCH 0 -193.5.188.0/24 MATCH 0 -193.8.136.0/23 MATCH 0 -193.36.32.0/24 MATCH 0 -193.73.125.0/24 MATCH 0 -193.134.200.0/21 MATCH 0 -193.134.216.0/21 MATCH 0 -193.135.168.0/22 MATCH 0 -193.135.172.0/24 MATCH 0 -193.135.240.0/21 MATCH 0 -193.138.69.0/24 MATCH 0 -193.222.112.0/20 MATCH 0 -193.222.241.0/24 MATCH 0 -193.222.242.0/23 MATCH 0 -193.222.244.0/22 MATCH 0 -193.222.248.0/23 MATCH 0 -193.222.250.0/24 MATCH 0 -193.246.121.0/24 MATCH 0 -193.246.124.0/23 MATCH 0 -193.246.176.0/20 MATCH 0 -193.247.190.0/23 MATCH 0 -193.247.203.0/24 MATCH 0 -193.247.240.0/22 MATCH 0 -193.247.248.0/23 MATCH 0 -193.247.254.0/24 MATCH 0 -194.153.96.0/24 MATCH 0 -195.176.0.0/17 MATCH 0 -195.176.160.0/19 MATCH 0 -195.176.224.0/19 MATCH 0 -198.21.18.0/24 miss 0 -2001:620::/29 MATCH 0 -2001:620::/32 MATCH 0 -2001:678:678::/48 MATCH 0 -2001:67c:10ec::/48 MATCH 0 -2001:67c:13c0::/48 MATCH 0 -2001:67c:16dc::/48 MATCH 0 -2a02:7dc0::/32 MATCH 0 -2a07:290a::/32 MATCH 0 -2a07:3e00::/29 MATCH 0 -2a07:6b40::/29 MATCH 0 -2a0a:4ec0::/29 MATCH 0 -2a0b:2040::/29 MATCH 0 -199.185.136.0/23 miss 0 -199.185.178.0/24 miss 0 -199.185.230.0/23 miss 0 -204.174.115.0/24 miss 0 -204.209.252.0/24 miss 0 -204.209.253.0/24 miss 0 -2620:3d:c000::/48 miss 0 +82.130.64.0/18 MATCH +86.119.0.0/16 MATCH +89.206.64.0/18 MATCH +128.178.0.0/15 MATCH +129.129.0.0/16 MATCH +129.132.0.0/16 MATCH +129.194.0.0/15 MATCH +130.59.0.0/16 MATCH +130.60.0.0/16 MATCH +130.82.0.0/16 MATCH +130.92.0.0/16 MATCH +130.125.0.0/16 MATCH +130.223.0.0/16 MATCH +131.152.0.0/16 MATCH +134.21.0.0/16 MATCH +138.131.0.0/16 MATCH +141.249.0.0/16 MATCH +144.200.0.0/16 MATCH +146.136.0.0/16 MATCH +147.86.0.0/16 MATCH +147.87.0.0/16 MATCH +147.88.0.0/16 MATCH +148.187.0.0/16 MATCH +148.196.0.0/16 MATCH +152.88.0.0/16 MATCH +152.96.0.0/16 MATCH +153.109.0.0/16 MATCH +155.105.0.0/16 MATCH +155.228.0.0/16 MATCH +156.25.0.0/16 MATCH +156.135.0.0/21 MATCH +156.135.12.0/22 MATCH +156.135.16.0/21 MATCH +156.135.28.0/22 MATCH +156.135.32.0/19 MATCH +156.135.64.0/18 MATCH +156.135.128.0/17 MATCH +157.26.0.0/16 MATCH +160.85.0.0/16 MATCH +160.98.0.0/16 MATCH +161.62.0.0/16 MATCH +185.51.68.0/22 MATCH +185.133.44.0/22 MATCH +185.144.36.0/22 MATCH +185.194.180.0/22 MATCH +185.225.92.0/22 MATCH +192.12.247.0/24 MATCH +192.26.28.0/22 MATCH +192.26.32.0/21 MATCH +192.26.40.0/22 MATCH +192.26.44.0/24 MATCH +192.26.46.0/23 MATCH +192.33.87.0/24 MATCH +192.33.88.0/21 MATCH +192.33.96.0/21 MATCH +192.33.104.0/22 MATCH +192.33.108.0/23 MATCH +192.33.110.0/24 MATCH +192.33.118.0/23 MATCH +192.33.120.0/21 MATCH +192.33.192.0/19 MATCH +192.33.224.0/21 MATCH +192.41.132.0/22 MATCH +192.41.136.0/24 MATCH +192.41.149.0/24 MATCH +192.41.150.0/23 MATCH +192.41.152.0/21 MATCH +192.41.160.0/24 MATCH +192.42.42.0/23 MATCH +192.42.44.0/22 MATCH +192.42.180.0/22 MATCH +192.42.184.0/21 MATCH +192.42.192.0/21 MATCH +192.42.200.0/23 MATCH +192.43.192.0/22 MATCH +192.43.196.0/24 MATCH +192.47.244.0/22 MATCH +192.47.248.0/23 MATCH +192.65.92.0/23 MATCH +192.101.176.0/24 MATCH +192.135.150.0/23 MATCH +192.135.151.0/24 MATCH +192.135.152.0/21 MATCH +192.152.98.0/24 MATCH +193.5.22.0/24 MATCH +193.5.26.0/23 MATCH +193.5.54.0/23 MATCH +193.5.58.0/24 MATCH +193.5.60.0/24 MATCH +193.5.80.0/21 MATCH +193.5.152.0/22 MATCH +193.5.168.0/22 MATCH +193.5.180.0/24 MATCH +193.5.182.0/24 MATCH +193.5.186.0/24 MATCH +193.5.188.0/24 MATCH +193.8.136.0/23 MATCH +193.36.32.0/24 MATCH +193.73.125.0/24 MATCH +193.134.200.0/21 MATCH +193.134.216.0/21 MATCH +193.135.168.0/22 MATCH +193.135.172.0/24 MATCH +193.135.240.0/21 MATCH +193.138.69.0/24 MATCH +193.222.112.0/20 MATCH +193.222.241.0/24 MATCH +193.222.242.0/23 MATCH +193.222.244.0/22 MATCH +193.222.248.0/23 MATCH +193.222.250.0/24 MATCH +193.246.121.0/24 MATCH +193.246.124.0/23 MATCH +193.246.176.0/20 MATCH +193.247.190.0/23 MATCH +193.247.203.0/24 MATCH +193.247.240.0/22 MATCH +193.247.248.0/23 MATCH +193.247.254.0/24 MATCH +194.153.96.0/24 MATCH +195.176.0.0/17 MATCH +195.176.160.0/19 MATCH +195.176.224.0/19 MATCH +198.21.18.0/24 miss +2001:620::/29 MATCH +2001:620::/32 MATCH +2001:678:678::/48 MATCH +2001:67c:10ec::/48 MATCH +2001:67c:13c0::/48 MATCH +2001:67c:16dc::/48 MATCH +2a02:7dc0::/32 MATCH +2a07:290a::/32 MATCH +2a07:3e00::/29 MATCH +2a07:6b40::/29 MATCH +2a0a:4ec0::/29 MATCH +2a0b:2040::/29 MATCH +199.185.136.0/23 miss +199.185.178.0/24 miss +199.185.230.0/23 miss +204.174.115.0/24 miss +204.209.252.0/24 miss +204.209.253.0/24 miss +2620:3d:c000::/48 miss Index: regress/usr.sbin/bgpd/unittests/rde_trie_test.4.check =================================================================== RCS file: /cvs/src/regress/usr.sbin/bgpd/unittests/rde_trie_test.4.check,v retrieving revision 1.1 diff -u -p -r1.1 rde_trie_test.4.check --- regress/usr.sbin/bgpd/unittests/rde_trie_test.4.check 11 Sep 2018 08:55:49 -0000 1.1 +++ regress/usr.sbin/bgpd/unittests/rde_trie_test.4.check 14 Sep 2018 14:10:05 -0000 @@ -1,148 +1,148 @@ -23.128.23.0/28 1 -23.128.23.16/28 1 -23.128.23.192/28 1 -82.130.64.0/18 1 -86.119.0.0/16 1 -89.206.64.0/18 1 -128.178.0.0/15 1 -129.129.0.0/16 1 -129.132.0.0/16 1 -129.194.0.0/15 1 -130.59.0.0/16 1 -130.60.0.0/16 1 -130.82.0.0/16 1 -130.92.0.0/16 1 -130.125.0.0/16 1 -130.223.0.0/16 1 -131.152.0.0/16 1 -134.21.0.0/16 1 -138.131.0.0/16 1 -141.249.0.0/16 1 -144.200.0.0/16 1 -146.136.0.0/16 1 -147.86.0.0/16 1 -147.87.0.0/16 1 -147.88.0.0/16 1 -148.187.0.0/16 1 -148.196.0.0/16 1 -152.88.0.0/16 1 -152.96.0.0/16 1 -153.109.0.0/16 1 -155.105.0.0/16 1 -155.228.0.0/16 1 -156.25.0.0/16 1 -156.135.0.0/21 1 -156.135.12.0/22 1 -156.135.16.0/21 1 -156.135.28.0/22 1 -156.135.32.0/19 1 -156.135.64.0/18 1 -156.135.128.0/17 1 -157.26.0.0/16 1 -160.85.0.0/16 1 -160.98.0.0/16 1 -161.62.0.0/16 1 -185.51.68.0/22 1 -185.133.44.0/22 1 -185.144.36.0/22 1 -185.194.180.0/22 1 -185.225.92.0/22 1 -192.12.247.0/24 1 -192.26.28.0/22 1 -192.26.32.0/21 1 -192.26.40.0/22 1 -192.26.44.0/24 1 -192.26.46.0/23 1 -192.33.87.0/24 1 -192.33.88.0/21 1 -192.33.96.0/21 1 -192.33.104.0/22 1 -192.33.108.0/23 1 -192.33.110.0/24 1 -192.33.118.0/23 1 -192.33.120.0/21 1 -192.33.192.0/19 1 -192.33.224.0/21 1 -192.41.132.0/22 1 -192.41.136.0/24 1 -192.41.149.0/24 1 -192.41.150.0/23 1 -192.41.152.0/21 1 -192.41.160.0/24 1 -192.42.42.0/23 1 -192.42.44.0/22 1 -192.42.180.0/22 1 -192.42.184.0/21 1 -192.42.192.0/21 1 -192.42.200.0/23 1 -192.43.192.0/22 1 -192.43.196.0/24 1 -192.47.244.0/22 1 -192.47.248.0/23 1 -192.65.92.0/23 1 -192.101.176.0/24 1 -192.135.150.0/23 1 -192.135.151.0/24 1 -192.135.152.0/21 1 -192.152.98.0/24 1 -193.5.22.0/24 1 -193.5.26.0/23 1 -193.5.54.0/23 1 -193.5.58.0/24 1 -193.5.60.0/24 1 -193.5.80.0/21 1 -193.5.152.0/22 1 -193.5.168.0/22 1 -193.5.180.0/24 1 -193.5.182.0/24 1 -193.5.186.0/24 1 -193.5.188.0/24 1 -193.8.136.0/23 1 -193.36.32.0/24 1 -193.73.125.0/24 1 -193.134.200.0/21 1 -193.134.216.0/21 1 -193.135.168.0/22 1 -193.135.172.0/24 1 -193.135.240.0/21 1 -193.138.69.0/24 1 -193.222.112.0/20 1 -193.222.241.0/24 1 -193.222.242.0/23 1 -193.222.244.0/22 1 -193.222.248.0/23 1 -193.222.250.0/24 1 -193.246.121.0/24 1 -193.246.124.0/23 1 -193.246.176.0/20 1 -193.247.190.0/23 1 -193.247.203.0/24 1 -193.247.240.0/22 1 -193.247.248.0/23 1 -193.247.254.0/24 1 -194.153.96.0/24 1 -195.176.0.0/17 1 -195.176.160.0/19 1 -195.176.224.0/19 1 -198.21.18.0/24 1 -2001:620::/29 1 -2001:620::/32 1 -2001:678:678::/48 1 -2001:67c:10ec::/48 1 -2001:67c:13c0::/48 1 -2001:67c:16dc::/48 1 -2a02:7dc0::/32 1 -2a07:290a::/32 1 -2a07:3e00::/29 1 -2a07:6b40::/29 1 -2a0a:4ec0::/29 1 -2a0b:2040::/29 1 -199.185.136.0/23 1 -199.185.178.0/24 1 -199.185.230.0/23 1 -204.174.115.0/24 1 -204.209.252.0/24 1 -204.209.253.0/24 1 -2620:3d:c000::/48 1 -2a0c:fffe::2/127 1 1 -2a0c:fffd::/127 1 \ No newline at end of file +23.128.23.0/28 +23.128.23.16/28 +23.128.23.192/28 +82.130.64.0/18 +86.119.0.0/16 +89.206.64.0/18 +128.178.0.0/15 +129.129.0.0/16 +129.132.0.0/16 +129.194.0.0/15 +130.59.0.0/16 +130.60.0.0/16 +130.82.0.0/16 +130.92.0.0/16 +130.125.0.0/16 +130.223.0.0/16 +131.152.0.0/16 +134.21.0.0/16 +138.131.0.0/16 +141.249.0.0/16 +144.200.0.0/16 +146.136.0.0/16 +147.86.0.0/16 +147.87.0.0/16 +147.88.0.0/16 +148.187.0.0/16 +148.196.0.0/16 +152.88.0.0/16 +152.96.0.0/16 +153.109.0.0/16 +155.105.0.0/16 +155.228.0.0/16 +156.25.0.0/16 +156.135.0.0/21 +156.135.12.0/22 +156.135.16.0/21 +156.135.28.0/22 +156.135.32.0/19 +156.135.64.0/18 +156.135.128.0/17 +157.26.0.0/16 +160.85.0.0/16 +160.98.0.0/16 +161.62.0.0/16 +185.51.68.0/22 +185.133.44.0/22 +185.144.36.0/22 +185.194.180.0/22 +185.225.92.0/22 +192.12.247.0/24 +192.26.28.0/22 +192.26.32.0/21 +192.26.40.0/22 +192.26.44.0/24 +192.26.46.0/23 +192.33.87.0/24 +192.33.88.0/21 +192.33.96.0/21 +192.33.104.0/22 +192.33.108.0/23 +192.33.110.0/24 +192.33.118.0/23 +192.33.120.0/21 +192.33.192.0/19 +192.33.224.0/21 +192.41.132.0/22 +192.41.136.0/24 +192.41.149.0/24 +192.41.150.0/23 +192.41.152.0/21 +192.41.160.0/24 +192.42.42.0/23 +192.42.44.0/22 +192.42.180.0/22 +192.42.184.0/21 +192.42.192.0/21 +192.42.200.0/23 +192.43.192.0/22 +192.43.196.0/24 +192.47.244.0/22 +192.47.248.0/23 +192.65.92.0/23 +192.101.176.0/24 +192.135.150.0/23 +192.135.151.0/24 +192.135.152.0/21 +192.152.98.0/24 +193.5.22.0/24 +193.5.26.0/23 +193.5.54.0/23 +193.5.58.0/24 +193.5.60.0/24 +193.5.80.0/21 +193.5.152.0/22 +193.5.168.0/22 +193.5.180.0/24 +193.5.182.0/24 +193.5.186.0/24 +193.5.188.0/24 +193.8.136.0/23 +193.36.32.0/24 +193.73.125.0/24 +193.134.200.0/21 +193.134.216.0/21 +193.135.168.0/22 +193.135.172.0/24 +193.135.240.0/21 +193.138.69.0/24 +193.222.112.0/20 +193.222.241.0/24 +193.222.242.0/23 +193.222.244.0/22 +193.222.248.0/23 +193.222.250.0/24 +193.246.121.0/24 +193.246.124.0/23 +193.246.176.0/20 +193.247.190.0/23 +193.247.203.0/24 +193.247.240.0/22 +193.247.248.0/23 +193.247.254.0/24 +194.153.96.0/24 +195.176.0.0/17 +195.176.160.0/19 +195.176.224.0/19 +198.21.18.0/24 +2001:620::/29 +2001:620::/32 +2001:678:678::/48 +2001:67c:10ec::/48 +2001:67c:13c0::/48 +2001:67c:16dc::/48 +2a02:7dc0::/32 +2a07:290a::/32 +2a07:3e00::/29 +2a07:6b40::/29 +2a0a:4ec0::/29 +2a0b:2040::/29 +199.185.136.0/23 +199.185.178.0/24 +199.185.230.0/23 +204.174.115.0/24 +204.209.252.0/24 +204.209.253.0/24 +2620:3d:c000::/48 +2a0c:fffe::2/127 +2a0c:fffd::/127 Index: regress/usr.sbin/bgpd/unittests/rde_trie_test.4.out =================================================================== RCS file: /cvs/src/regress/usr.sbin/bgpd/unittests/rde_trie_test.4.out,v retrieving revision 1.1 diff -u -p -r1.1 rde_trie_test.4.out --- regress/usr.sbin/bgpd/unittests/rde_trie_test.4.out 11 Sep 2018 08:55:49 -0000 1.1 +++ regress/usr.sbin/bgpd/unittests/rde_trie_test.4.out 14 Sep 2018 14:10:05 -0000 @@ -1,148 +1,148 @@ -23.128.23.0/28 MATCH 1 -23.128.23.16/28 MATCH 1 -23.128.23.192/28 miss 1 -82.130.64.0/18 MATCH 1 -86.119.0.0/16 MATCH 1 -89.206.64.0/18 MATCH 1 -128.178.0.0/15 MATCH 1 -129.129.0.0/16 MATCH 1 -129.132.0.0/16 MATCH 1 -129.194.0.0/15 MATCH 1 -130.59.0.0/16 MATCH 1 -130.60.0.0/16 MATCH 1 -130.82.0.0/16 MATCH 1 -130.92.0.0/16 MATCH 1 -130.125.0.0/16 MATCH 1 -130.223.0.0/16 MATCH 1 -131.152.0.0/16 MATCH 1 -134.21.0.0/16 MATCH 1 -138.131.0.0/16 MATCH 1 -141.249.0.0/16 MATCH 1 -144.200.0.0/16 MATCH 1 -146.136.0.0/16 MATCH 1 -147.86.0.0/16 MATCH 1 -147.87.0.0/16 MATCH 1 -147.88.0.0/16 MATCH 1 -148.187.0.0/16 MATCH 1 -148.196.0.0/16 MATCH 1 -152.88.0.0/16 MATCH 1 -152.96.0.0/16 MATCH 1 -153.109.0.0/16 MATCH 1 -155.105.0.0/16 MATCH 1 -155.228.0.0/16 MATCH 1 -156.25.0.0/16 MATCH 1 -156.135.0.0/21 MATCH 1 -156.135.12.0/22 MATCH 1 -156.135.16.0/21 MATCH 1 -156.135.28.0/22 MATCH 1 -156.135.32.0/19 MATCH 1 -156.135.64.0/18 MATCH 1 -156.135.128.0/17 MATCH 1 -157.26.0.0/16 MATCH 1 -160.85.0.0/16 MATCH 1 -160.98.0.0/16 MATCH 1 -161.62.0.0/16 MATCH 1 -185.51.68.0/22 MATCH 1 -185.133.44.0/22 MATCH 1 -185.144.36.0/22 MATCH 1 -185.194.180.0/22 MATCH 1 -185.225.92.0/22 MATCH 1 -192.12.247.0/24 MATCH 1 -192.26.28.0/22 MATCH 1 -192.26.32.0/21 MATCH 1 -192.26.40.0/22 MATCH 1 -192.26.44.0/24 MATCH 1 -192.26.46.0/23 MATCH 1 -192.33.87.0/24 MATCH 1 -192.33.88.0/21 MATCH 1 -192.33.96.0/21 MATCH 1 -192.33.104.0/22 MATCH 1 -192.33.108.0/23 MATCH 1 -192.33.110.0/24 MATCH 1 -192.33.118.0/23 MATCH 1 -192.33.120.0/21 MATCH 1 -192.33.192.0/19 MATCH 1 -192.33.224.0/21 MATCH 1 -192.41.132.0/22 MATCH 1 -192.41.136.0/24 MATCH 1 -192.41.149.0/24 MATCH 1 -192.41.150.0/23 MATCH 1 -192.41.152.0/21 MATCH 1 -192.41.160.0/24 MATCH 1 -192.42.42.0/23 MATCH 1 -192.42.44.0/22 MATCH 1 -192.42.180.0/22 MATCH 1 -192.42.184.0/21 MATCH 1 -192.42.192.0/21 MATCH 1 -192.42.200.0/23 MATCH 1 -192.43.192.0/22 MATCH 1 -192.43.196.0/24 MATCH 1 -192.47.244.0/22 MATCH 1 -192.47.248.0/23 MATCH 1 -192.65.92.0/23 MATCH 1 -192.101.176.0/24 MATCH 1 -192.135.150.0/23 MATCH 1 -192.135.151.0/24 MATCH 1 -192.135.152.0/21 MATCH 1 -192.152.98.0/24 MATCH 1 -193.5.22.0/24 MATCH 1 -193.5.26.0/23 MATCH 1 -193.5.54.0/23 MATCH 1 -193.5.58.0/24 MATCH 1 -193.5.60.0/24 MATCH 1 -193.5.80.0/21 MATCH 1 -193.5.152.0/22 MATCH 1 -193.5.168.0/22 MATCH 1 -193.5.180.0/24 MATCH 1 -193.5.182.0/24 MATCH 1 -193.5.186.0/24 MATCH 1 -193.5.188.0/24 MATCH 1 -193.8.136.0/23 MATCH 1 -193.36.32.0/24 MATCH 1 -193.73.125.0/24 MATCH 1 -193.134.200.0/21 MATCH 1 -193.134.216.0/21 MATCH 1 -193.135.168.0/22 MATCH 1 -193.135.172.0/24 MATCH 1 -193.135.240.0/21 MATCH 1 -193.138.69.0/24 MATCH 1 -193.222.112.0/20 MATCH 1 -193.222.241.0/24 MATCH 1 -193.222.242.0/23 MATCH 1 -193.222.244.0/22 MATCH 1 -193.222.248.0/23 MATCH 1 -193.222.250.0/24 MATCH 1 -193.246.121.0/24 MATCH 1 -193.246.124.0/23 MATCH 1 -193.246.176.0/20 MATCH 1 -193.247.190.0/23 MATCH 1 -193.247.203.0/24 MATCH 1 -193.247.240.0/22 MATCH 1 -193.247.248.0/23 MATCH 1 -193.247.254.0/24 MATCH 1 -194.153.96.0/24 MATCH 1 -195.176.0.0/17 MATCH 1 -195.176.160.0/19 MATCH 1 -195.176.224.0/19 MATCH 1 -198.21.18.0/24 miss 1 -2001:620::/29 MATCH 1 -2001:620::/32 MATCH 1 -2001:678:678::/48 MATCH 1 -2001:67c:10ec::/48 MATCH 1 -2001:67c:13c0::/48 MATCH 1 -2001:67c:16dc::/48 MATCH 1 -2a02:7dc0::/32 MATCH 1 -2a07:290a::/32 MATCH 1 -2a07:3e00::/29 MATCH 1 -2a07:6b40::/29 MATCH 1 -2a0a:4ec0::/29 MATCH 1 -2a0b:2040::/29 MATCH 1 -199.185.136.0/23 miss 1 -199.185.178.0/24 miss 1 -199.185.230.0/23 miss 1 -204.174.115.0/24 miss 1 -204.209.252.0/24 miss 1 -204.209.253.0/24 miss 1 -2620:3d:c000::/48 miss 1 -2a0c:fffe::2/127 MATCH 1 -2a0c:fffd::/127 miss 1 +23.128.23.0/28 MATCH +23.128.23.16/28 MATCH +23.128.23.192/28 miss +82.130.64.0/18 MATCH +86.119.0.0/16 MATCH +89.206.64.0/18 MATCH +128.178.0.0/15 MATCH +129.129.0.0/16 MATCH +129.132.0.0/16 MATCH +129.194.0.0/15 MATCH +130.59.0.0/16 MATCH +130.60.0.0/16 MATCH +130.82.0.0/16 MATCH +130.92.0.0/16 MATCH +130.125.0.0/16 MATCH +130.223.0.0/16 MATCH +131.152.0.0/16 MATCH +134.21.0.0/16 MATCH +138.131.0.0/16 MATCH +141.249.0.0/16 MATCH +144.200.0.0/16 MATCH +146.136.0.0/16 MATCH +147.86.0.0/16 MATCH +147.87.0.0/16 MATCH +147.88.0.0/16 MATCH +148.187.0.0/16 MATCH +148.196.0.0/16 MATCH +152.88.0.0/16 MATCH +152.96.0.0/16 MATCH +153.109.0.0/16 MATCH +155.105.0.0/16 MATCH +155.228.0.0/16 MATCH +156.25.0.0/16 MATCH +156.135.0.0/21 MATCH +156.135.12.0/22 MATCH +156.135.16.0/21 MATCH +156.135.28.0/22 MATCH +156.135.32.0/19 MATCH +156.135.64.0/18 MATCH +156.135.128.0/17 MATCH +157.26.0.0/16 MATCH +160.85.0.0/16 MATCH +160.98.0.0/16 MATCH +161.62.0.0/16 MATCH +185.51.68.0/22 MATCH +185.133.44.0/22 MATCH +185.144.36.0/22 MATCH +185.194.180.0/22 MATCH +185.225.92.0/22 MATCH +192.12.247.0/24 MATCH +192.26.28.0/22 MATCH +192.26.32.0/21 MATCH +192.26.40.0/22 MATCH +192.26.44.0/24 MATCH +192.26.46.0/23 MATCH +192.33.87.0/24 MATCH +192.33.88.0/21 MATCH +192.33.96.0/21 MATCH +192.33.104.0/22 MATCH +192.33.108.0/23 MATCH +192.33.110.0/24 MATCH +192.33.118.0/23 MATCH +192.33.120.0/21 MATCH +192.33.192.0/19 MATCH +192.33.224.0/21 MATCH +192.41.132.0/22 MATCH +192.41.136.0/24 MATCH +192.41.149.0/24 MATCH +192.41.150.0/23 MATCH +192.41.152.0/21 MATCH +192.41.160.0/24 MATCH +192.42.42.0/23 MATCH +192.42.44.0/22 MATCH +192.42.180.0/22 MATCH +192.42.184.0/21 MATCH +192.42.192.0/21 MATCH +192.42.200.0/23 MATCH +192.43.192.0/22 MATCH +192.43.196.0/24 MATCH +192.47.244.0/22 MATCH +192.47.248.0/23 MATCH +192.65.92.0/23 MATCH +192.101.176.0/24 MATCH +192.135.150.0/23 MATCH +192.135.151.0/24 MATCH +192.135.152.0/21 MATCH +192.152.98.0/24 MATCH +193.5.22.0/24 MATCH +193.5.26.0/23 MATCH +193.5.54.0/23 MATCH +193.5.58.0/24 MATCH +193.5.60.0/24 MATCH +193.5.80.0/21 MATCH +193.5.152.0/22 MATCH +193.5.168.0/22 MATCH +193.5.180.0/24 MATCH +193.5.182.0/24 MATCH +193.5.186.0/24 MATCH +193.5.188.0/24 MATCH +193.8.136.0/23 MATCH +193.36.32.0/24 MATCH +193.73.125.0/24 MATCH +193.134.200.0/21 MATCH +193.134.216.0/21 MATCH +193.135.168.0/22 MATCH +193.135.172.0/24 MATCH +193.135.240.0/21 MATCH +193.138.69.0/24 MATCH +193.222.112.0/20 MATCH +193.222.241.0/24 MATCH +193.222.242.0/23 MATCH +193.222.244.0/22 MATCH +193.222.248.0/23 MATCH +193.222.250.0/24 MATCH +193.246.121.0/24 MATCH +193.246.124.0/23 MATCH +193.246.176.0/20 MATCH +193.247.190.0/23 MATCH +193.247.203.0/24 MATCH +193.247.240.0/22 MATCH +193.247.248.0/23 MATCH +193.247.254.0/24 MATCH +194.153.96.0/24 MATCH +195.176.0.0/17 MATCH +195.176.160.0/19 MATCH +195.176.224.0/19 MATCH +198.21.18.0/24 miss +2001:620::/29 MATCH +2001:620::/32 MATCH +2001:678:678::/48 MATCH +2001:67c:10ec::/48 MATCH +2001:67c:13c0::/48 MATCH +2001:67c:16dc::/48 MATCH +2a02:7dc0::/32 MATCH +2a07:290a::/32 MATCH +2a07:3e00::/29 MATCH +2a07:6b40::/29 MATCH +2a0a:4ec0::/29 MATCH +2a0b:2040::/29 MATCH +199.185.136.0/23 miss +199.185.178.0/24 miss +199.185.230.0/23 miss +204.174.115.0/24 miss +204.209.252.0/24 miss +204.209.253.0/24 miss +2620:3d:c000::/48 miss +2a0c:fffe::2/127 MATCH +2a0c:fffd::/127 miss Index: regress/usr.sbin/bgpd/unittests/rde_trie_test.5.check =================================================================== RCS file: regress/usr.sbin/bgpd/unittests/rde_trie_test.5.check diff -N regress/usr.sbin/bgpd/unittests/rde_trie_test.5.check --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ regress/usr.sbin/bgpd/unittests/rde_trie_test.5.check 14 Sep 2018 14:10:05 -0000 @@ -0,0 +1,37 @@ +2a01:c00::/24 source-as 6805 +2a01:c00::/24 source-as 42 +2a01:c00::/26 source-as 6805 +2a01:c00::/26 source-as 42 +2a01:c00::/28 source-as 6805 +2a01:c00::/28 source-as 42 +2a01:c50::/28 source-as 12479 +2a01:c500::/31 source-as 12479 +2a01:c500::/32 source-as 12479 +2a01:c500::/42 source-as 12479 +2a01:c500::/42 source-as 6805 +2a01:c500::/42 source-as 42 +2a01:c500::/46 source-as 12479 +2a01:c500::/48 source-as 12479 +2a01:c500::/48 source-as 6805 +2a01:c500::/48 source-as 42 +80.128.0.0/11 +80.128.0.0/11 source-as 3320 +80.128.0.0/11 source-as 42 +80.128.0.0/12 source-as 3320 +80.128.0.0/12 source-as 42 +80.128.0.0/13 source-as 3320 +80.128.0.0/13 source-as 42 +80.144.0.0/13 source-as 3320 +80.144.0.0/14 source-as 3320 +80.157.16.0/20 source-as 3320 +80.157.16.0/21 source-as 3320 +80.158.0.0/17 source-as 34086 +80.158.120.0/21 source-as 34086 +80.158.0.0/17 source-as 3320 +80.158.120.0/21 source-as 42 +80.159.224.0/19 source-as 2792 +80.159.225.0/24 source-as 2792 +80.159.224.0/19 source-as 3320 +80.159.225.0/24 source-as 3320 +80.159.224.0/19 source-as 42 +80.159.225.0/24 source-as 42 Index: regress/usr.sbin/bgpd/unittests/rde_trie_test.5.in =================================================================== RCS file: regress/usr.sbin/bgpd/unittests/rde_trie_test.5.in diff -N regress/usr.sbin/bgpd/unittests/rde_trie_test.5.in --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ regress/usr.sbin/bgpd/unittests/rde_trie_test.5.in 14 Sep 2018 14:10:05 -0000 @@ -0,0 +1,47 @@ +source-as 6805 +prefix 2a01:c00::/26 +source-as 12479 maxlen 46 +prefix 2a01:c500::/28 +source-as 12479 maxlen 42 +prefix 2a01:c500::/31 +source-as 3215 maxlen 48 +prefix 2a01:c910::/29 +source-as 51964 maxlen 48 +prefix 2a01:ce80::/26 +source-as 20603 maxlen 48 +prefix 2a01:cf00::/40 +source-as 2278 maxlen 48 +prefix 2a01:cf00::/42 +source-as 2278 +prefix 2a01:cf00:f::/48 +source-as 12322 maxlen 32 +prefix 2a01:e00::/26 +source-as 12322 +prefix 2a01:e00::/32 +source-as 12322 +prefix 2a01:e01::/32 +source-as 12322 +prefix 2a01:e02::/32 +source-as 12322 +prefix 2a01:e0a::/38 +source-as 0 maxlen 11 +source-as 3320 +prefix 80.128.0.0/11 +source-as 3320 +prefix 80.128.0.0/12 +source-as 3320 +prefix 80.144.0.0/13 +source-as 3320 +prefix 80.152.0.0/14 +source-as 3320 +prefix 80.156.0.0/16 +source-as 3320 +prefix 80.157.0.0/16 +source-as 3320 +prefix 80.157.16.0/20 +source-as 3320 +prefix 80.157.8.0/21 +source-as 34086 maxlen 21 +prefix 80.158.0.0/17 +source-as 2792 maxlen 24 +prefix 80.159.224.0/19 Index: regress/usr.sbin/bgpd/unittests/rde_trie_test.5.out =================================================================== RCS file: regress/usr.sbin/bgpd/unittests/rde_trie_test.5.out diff -N regress/usr.sbin/bgpd/unittests/rde_trie_test.5.out --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ regress/usr.sbin/bgpd/unittests/rde_trie_test.5.out 14 Sep 2018 14:10:05 -0000 @@ -0,0 +1,37 @@ +2a01:c00::/24 source-as 6805 is not found +2a01:c00::/24 source-as 42 is not found +2a01:c00::/26 source-as 6805 is VALID +2a01:c00::/26 source-as 42 is invalid +2a01:c00::/28 source-as 6805 is invalid +2a01:c00::/28 source-as 42 is invalid +2a01:c50::/28 source-as 12479 is not found +2a01:c500::/31 source-as 12479 is VALID +2a01:c500::/32 source-as 12479 is VALID +2a01:c500::/42 source-as 12479 is VALID +2a01:c500::/42 source-as 6805 is invalid +2a01:c500::/42 source-as 42 is invalid +2a01:c500::/46 source-as 12479 is VALID +2a01:c500::/48 source-as 12479 is invalid +2a01:c500::/48 source-as 6805 is invalid +2a01:c500::/48 source-as 42 is invalid +80.128.0.0/11 source-as 0 is invalid +80.128.0.0/11 source-as 3320 is invalid +80.128.0.0/11 source-as 42 is invalid +80.128.0.0/12 source-as 3320 is invalid +80.128.0.0/12 source-as 42 is invalid +80.128.0.0/13 source-as 3320 is invalid +80.128.0.0/13 source-as 42 is invalid +80.144.0.0/13 source-as 3320 is invalid +80.144.0.0/14 source-as 3320 is invalid +80.157.16.0/20 source-as 3320 is invalid +80.157.16.0/21 source-as 3320 is invalid +80.158.0.0/17 source-as 34086 is VALID +80.158.120.0/21 source-as 34086 is VALID +80.158.0.0/17 source-as 3320 is invalid +80.158.120.0/21 source-as 42 is invalid +80.159.224.0/19 source-as 2792 is VALID +80.159.225.0/24 source-as 2792 is VALID +80.159.224.0/19 source-as 3320 is invalid +80.159.225.0/24 source-as 3320 is invalid +80.159.224.0/19 source-as 42 is invalid +80.159.225.0/24 source-as 42 is invalid Index: regress/usr.sbin/bgpd/unittests/rde_trie_test.c =================================================================== RCS file: /cvs/src/regress/usr.sbin/bgpd/unittests/rde_trie_test.c,v retrieving revision 1.3 diff -u -p -r1.3 rde_trie_test.c --- regress/usr.sbin/bgpd/unittests/rde_trie_test.c 10 Sep 2018 20:51:59 -0000 1.3 +++ regress/usr.sbin/bgpd/unittests/rde_trie_test.c 14 Sep 2018 14:10:05 -0000 @@ -20,6 +20,7 @@ #include <sys/socket.h> #include <err.h> +#include <limits.h> #include <netdb.h> #include <string.h> #include <stdlib.h> @@ -30,9 +31,11 @@ #include "bgpd.h" #include "rde.h" +int roa; +int orlonger; static int -host_v4(const char *s, struct bgpd_addr *h, u_int8_t *len, int *orl) +host_v4(const char *s, struct bgpd_addr *h, u_int8_t *len) { struct in_addr ina = { 0 }; int bits = 32; @@ -52,7 +55,7 @@ host_v4(const char *s, struct bgpd_addr } static int -host_v6(const char *s, struct bgpd_addr *h, u_int8_t *len, int *orl) +host_v6(const char *s, struct bgpd_addr *h, u_int8_t *len) { struct addrinfo hints, *res; const char *errstr; @@ -85,21 +88,11 @@ host_v6(const char *s, struct bgpd_addr } static int -host_l(char *s, struct bgpd_addr *h, u_int8_t *len, int *orl) +host_l(char *s, struct bgpd_addr *h, u_int8_t *len) { - char *c, *t; - - *orl = 0; - if ((c = strchr(s, '\t')) != NULL) { - if (c[1] == '1') { - *orl = 1; - } - *c = '\0'; - } - - if (host_v4(s, h, len, orl)) + if (host_v4(s, h, len)) return (1); - if (host_v6(s, h, len, orl)) + if (host_v6(s, h, len)) return (1); return (0); } @@ -127,34 +120,31 @@ parse_file(FILE *in, struct trie_head *t const char *errstr; char *line, *s; struct bgpd_addr prefix; - u_int8_t plen, min, max, maskmax; - int foo; + u_int8_t plen; while ((line = fparseln(in, NULL, NULL, NULL, FPARSELN_UNESCALL))) { int state = 0; - while ((s = strsep(&line, " \t"))) { + u_int8_t min = 255, max = 255, maskmax = 0; + + while ((s = strsep(&line, " \t\n"))) { if (*s == '\0') - break; + continue; switch (state) { case 0: - if (!host_l(s, &prefix, &plen, &foo)) - errx(1, "could not parse prefix \"%s\"", - s); - break; - case 1: + if (!host_l(s, &prefix, &plen)) + errx(1, "%s: could not parse " + "prefix \"%s\"", __func__, s); if (prefix.aid == AID_INET6) maskmax = 128; else maskmax = 32; + break; + case 1: min = strtonum(s, 0, maskmax, &errstr); if (errstr != NULL) errx(1, "min is %s: %s", errstr, s); break; case 2: - if (prefix.aid == AID_INET6) - maskmax = 128; - else - maskmax = 32; max = strtonum(s, 0, maskmax, &errstr); if (errstr != NULL) errx(1, "max is %s: %s", errstr, s); @@ -164,6 +154,12 @@ parse_file(FILE *in, struct trie_head *t } state++; } + if (state == 0) + continue; + if (max == 255) + max = maskmax; + if (min == 255) + min = plen; if (trie_add(th, &prefix, plen, min, max) != 0) errx(1, "trie_add(%s, %u, %u, %u) failed", @@ -174,21 +170,142 @@ parse_file(FILE *in, struct trie_head *t } static void +parse_roa_file(FILE *in, struct trie_head *th) +{ + const char *errstr; + char *line, *s; + struct as_set *aset = NULL; + struct roa_set rs; + struct bgpd_addr prefix; + u_int8_t plen; + + while ((line = fparseln(in, NULL, NULL, NULL, FPARSELN_UNESCALL))) { + int state = 0; + u_int32_t as; + u_int8_t max = 0; + + while ((s = strsep(&line, " \t\n"))) { + if (*s == '\0') + continue; + if (strcmp(s, "source-as") == 0) { + state = 4; + continue; + } + if (strcmp(s, "maxlen") == 0) { + state = 2; + continue; + } + if (strcmp(s, "prefix") == 0) { + state = 0; + continue; + } + switch (state) { + case 0: + if (!host_l(s, &prefix, &plen)) + errx(1, "%s: could not parse " + "prefix \"%s\"", __func__, s); + break; + case 2: + max = strtonum(s, 0, 128, &errstr); + if (errstr != NULL) + errx(1, "max is %s: %s", errstr, s); + break; + case 4: + as = strtonum(s, 0, UINT_MAX, &errstr); + if (errstr != NULL) + errx(1, "source-as is %s: %s", errstr, + s); + break; + default: + errx(1, "could not parse \"%s\", confused", s); + } + } + + if (state == 0) { + as_set_prep(aset); + if (trie_roa_add(th, &prefix, plen, aset) != 0) + errx(1, "trie_roa_add(%s, %u) failed", + print_prefix(&prefix), plen); + aset = NULL; + } else { + if (aset == NULL) { + if ((aset = as_set_new("", 1, sizeof(rs))) == + NULL) + err(1, "as_set_new"); + } + rs.as = as; + rs.maxlen = max; + if (as_set_add(aset, &rs, 1) != 0) + err(1, "as_set_add"); + } + + free(line); + } +} + +static void test_file(FILE *in, struct trie_head *th) { char *line; struct bgpd_addr prefix; u_int8_t plen; - int orlonger; while ((line = fparseln(in, NULL, NULL, NULL, FPARSELN_UNESCALL))) { - if (!host_l(line, &prefix, &plen, &orlonger)) - errx(1, "could not parse prefix \"%s\"", line); - printf("%s ", line); + if (!host_l(line, &prefix, &plen)) + errx(1, "%s: could not parse prefix \"%s\"", + __func__, line); + printf("%s/%u ", print_prefix(&prefix), plen); if (trie_match(th, &prefix, plen, orlonger)) - printf("MATCH %i\n", orlonger); + printf("MATCH\n"); else - printf("miss %i\n", orlonger); + printf("miss\n"); + free(line); + } +} + +static void +test_roa_file(FILE *in, struct trie_head *th) +{ + const char *errstr; + char *line, *s; + struct bgpd_addr prefix; + u_int8_t plen; + u_int32_t as; + int r; + + while ((line = fparseln(in, NULL, NULL, NULL, FPARSELN_UNESCALL))) { + s = strchr(line, ' '); + if (s) + *s++ = '\0'; + if (!host_l(line, &prefix, &plen)) + errx(1, "%s: could not parse prefix \"%s\"", + __func__, line); + if (s) + s = strstr(s, "source-as"); + if (s) { + s += strlen("source-as"); + as = strtonum(s, 0, UINT_MAX, &errstr); + if (errstr != NULL) + errx(1, "source-as is %s: %s", errstr, s); + } else + as = 0; + printf("%s/%u source-as %u is ", + print_prefix(&prefix), plen, as); + r = trie_roa_check(th, &prefix, plen, as); + switch (r) { + case ROA_UNKNOWN: + printf("not found\n"); + break; + case ROA_VALID: + printf("VALID\n"); + break; + case ROA_INVALID: + printf("invalid\n"); + break; + default: + printf("UNEXPECTED %d\n", r); + break; + } free(line); } } @@ -197,7 +314,7 @@ static void usage(void) { extern char *__progname; - fprintf(stderr, "usage: %s prefixfile testfile\n", __progname); + fprintf(stderr, "usage: %s [-or] prefixfile testfile\n", __progname); exit(1); } @@ -208,21 +325,43 @@ main(int argc, char **argv) FILE *in, *tin; int ch; - if (argc != 3) + while ((ch = getopt(argc, argv, "or")) != -1) { + switch (ch) { + case 'o': + orlonger = 1; + break; + case 'r': + roa = 1; + break; + default: + usage(); + /* NOTREACHED */ + } + } + argc -= optind; + argv += optind; + + if (argc != 2) usage(); - in = fopen(argv[1], "r"); + in = fopen(argv[0], "r"); if (in == NULL) err(1, "fopen(%s)", argv[0]); - tin = fopen(argv[2], "r"); + tin = fopen(argv[1], "r"); if (tin == NULL) err(1, "fopen(%s)", argv[1]); - parse_file(in, &th); + if (roa) + parse_roa_file(in, &th); + else + parse_file(in, &th); /* trie_dump(&th); */ if (trie_equal(&th, &th) == 0) errx(1, "trie_equal failure"); - test_file(tin, &th); + if (roa) + test_roa_file(tin, &th); + else + test_file(tin, &th); trie_free(&th); }