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);
 }

Reply via email to