On Fri, Sep 14, 2018 at 04:59:51PM +0200, Claudio Jeker wrote:
> 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.
> 

Anyone having something against me committing this later today?
Will make it easier to send out the next bits to get us ROA support.

-- 
: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