On Thu, Sep 20, 2018 at 07:58:10PM +0200, Denis Fondras wrote:
> On Thu, Sep 20, 2018 at 01:56:04PM +0200, Claudio Jeker wrote:
> > This is the next step for ROA validation.
> > 
> > Implement code to parse, print and reload roa-set tables.
> > This is sharing a lot of code with prefixset which makes all a bit easier.
> > A roa-set is defined like this:
> > roa-set "test2" {
> >     1.2.3.0/24 source-as 1,
> >     1.2.8.0/22 source-as 3
> > }
> > 
> 
> Shouldn't roa-set include maxlen ?

It does in the code, forgot to show it in this example. Sorry about that.
Wanted something short which was a bad idea.
 
> > This does not include any code to acutally use the data yet, I'm working
> > on that now and that will be then the next and hopefully last diff to
> > support ROA validations in bgpd.
> > -- 
> > :wq Claudio
> > 
> > 
> > Index: bgpd.c
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/bgpd/bgpd.c,v
> > retrieving revision 1.200
> > diff -u -p -r1.200 bgpd.c
> > --- bgpd.c  20 Sep 2018 11:45:59 -0000      1.200
> > +++ bgpd.c  20 Sep 2018 11:49:56 -0000
> > @@ -516,6 +516,34 @@ reconfigure(char *conffile, struct bgpd_
> >                     if (imsg_compose(ibuf_rde, IMSG_RECONF_PREFIXSETITEM, 0,
> >                         0, -1, psi, sizeof(*psi)) == -1)
> >                             return (-1);
> > +                   set_free(psi->set);
> > +                   free(psi);
> > +           }
> > +           free(ps);
> > +   }
> > +
> > +   /* roasets for filters in the RDE */
> > +   while ((ps = SIMPLEQ_FIRST(conf->roasets)) != NULL) {
> > +           SIMPLEQ_REMOVE_HEAD(conf->roasets, entry);
> > +           if (imsg_compose(ibuf_rde, IMSG_RECONF_ROA_SET, 0, 0, -1,
> > +               ps->name, sizeof(ps->name)) == -1)
> > +                   return (-1);
> > +           RB_FOREACH_SAFE(psi, prefixset_tree, &ps->psitems, npsi) {
> > +                   u_int32_t *as;
> > +                   size_t i, l, n;
> > +                   RB_REMOVE(prefixset_tree, &ps->psitems, psi);
> > +                   as = set_get(psi->set, &n);
> > +                   for (i = 0; i < n; i += l) {
> > +                           l = (n - i > 1024 ? 1024 : n - i);
> > +                           if (imsg_compose(ibuf_rde,
> > +                               IMSG_RECONF_ROA_AS_SET_ITEMS,
> > +                               0, 0, -1, as + i, l) == -1)
> > +                                   return -1;
> > +                   }
> > +                   if (imsg_compose(ibuf_rde, IMSG_RECONF_PREFIXSETITEM, 0,
> > +                       0, -1, psi, sizeof(*psi)) == -1)
> > +                           return (-1);
> > +                   set_free(psi->set);
> >                     free(psi);
> >             }
> >             free(ps);
> > Index: bgpd.h
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
> > retrieving revision 1.343
> > diff -u -p -r1.343 bgpd.h
> > --- bgpd.h  20 Sep 2018 11:45:59 -0000      1.343
> > +++ bgpd.h  20 Sep 2018 11:49:56 -0000
> > @@ -229,7 +229,9 @@ struct bgpd_config {
> >     struct listen_addrs                     *listen_addrs;
> >     struct mrt_head                         *mrt;
> >     struct prefixset_head                   *prefixsets;
> > +   struct prefixset_head                   *roasets;
> >     struct rde_prefixset_head               *rde_prefixsets;
> > +   struct rde_prefixset_head               *rde_roasets;
> >     struct as_set_head                      *as_sets;
> >     char                                    *csock;
> >     char                                    *rcsock;
> > @@ -431,6 +433,8 @@ enum imsg_type {
> >     IMSG_RECONF_AS_SET,
> >     IMSG_RECONF_AS_SET_ITEMS,
> >     IMSG_RECONF_AS_SET_DONE,
> > +   IMSG_RECONF_ROA_SET,
> > +   IMSG_RECONF_ROA_AS_SET_ITEMS,
> >     IMSG_RECONF_DONE,
> >     IMSG_UPDATE,
> >     IMSG_UPDATE_ERR,
> > @@ -961,6 +965,7 @@ struct roa_set {
> >  struct prefixset_item {
> >     struct filter_prefix            p;
> >     RB_ENTRY(prefixset_item)        entry;
> > +   struct set_table                *set;
> >  };
> >  RB_HEAD(prefixset_tree, prefixset_item);
> >  
> > Index: config.c
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/bgpd/config.c,v
> > retrieving revision 1.74
> > diff -u -p -r1.74 config.c
> > --- config.c        20 Sep 2018 07:46:39 -0000      1.74
> > +++ config.c        20 Sep 2018 11:49:56 -0000
> > @@ -67,6 +67,8 @@ new_config(void)
> >     if ((conf->prefixsets = calloc(1, sizeof(struct prefixset_head)))
> >         == NULL)
> >             fatal(NULL);
> > +   if ((conf->roasets = calloc(1, sizeof(struct prefixset_head))) == NULL)
> > +           fatal(NULL);
> >     if ((conf->as_sets = calloc(1, sizeof(struct as_set_head))) == NULL)
> >             fatal(NULL);
> >     if ((conf->filters = calloc(1, sizeof(struct filter_head))) == NULL)
> > @@ -81,6 +83,7 @@ new_config(void)
> >     TAILQ_INIT(&conf->networks);
> >     SIMPLEQ_INIT(&conf->rdomains);
> >     SIMPLEQ_INIT(conf->prefixsets);
> > +   SIMPLEQ_INIT(conf->roasets);
> >     SIMPLEQ_INIT(conf->as_sets);
> >  
> >     TAILQ_INIT(conf->filters);
> > @@ -129,6 +132,7 @@ free_prefixsets(struct prefixset_head *p
> >             ps = SIMPLEQ_FIRST(psh);
> >             RB_FOREACH_SAFE(psi, prefixset_tree, &ps->psitems, npsi) {
> >                     RB_REMOVE(prefixset_tree, &ps->psitems, psi);
> > +                   set_free(psi->set);
> >                     free(psi);
> >             }
> >             SIMPLEQ_REMOVE_HEAD(psh, entry);
> > @@ -147,6 +151,7 @@ free_config(struct bgpd_config *conf)
> >     free_networks(&conf->networks);
> >     filterlist_free(conf->filters);
> >     free_prefixsets(conf->prefixsets);
> > +   free_prefixsets(conf->roasets);
> >     as_sets_free(conf->as_sets);
> >  
> >     while ((la = TAILQ_FIRST(conf->listen_addrs)) != NULL) {
> > @@ -224,6 +229,11 @@ merge_config(struct bgpd_config *xconf, 
> >     free_prefixsets(xconf->prefixsets);
> >     xconf->prefixsets = conf->prefixsets;
> >     conf->prefixsets = NULL;
> > +
> > +   /* switch the roasets, first remove the old ones */
> > +   free_prefixsets(xconf->roasets);
> > +   xconf->roasets = conf->roasets;
> > +   conf->roasets = NULL;
> >  
> >     /* switch the as_sets, first remove the old ones */
> >     as_sets_free(xconf->as_sets);
> > Index: parse.y
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
> > retrieving revision 1.355
> > diff -u -p -r1.355 parse.y
> > --- parse.y 20 Sep 2018 11:45:59 -0000      1.355
> > +++ parse.y 20 Sep 2018 11:49:57 -0000
> > @@ -93,6 +93,7 @@ static struct peer                *curpeer;
> >  static struct peer         *curgroup;
> >  static struct rdomain              *currdom;
> >  static struct prefixset            *curpset;
> > +static struct prefixset            *curroaset;
> >  static struct filter_head  *filter_l;
> >  static struct filter_head  *peerfilter_l;
> >  static struct filter_head  *groupfilter_l;
> > @@ -162,7 +163,8 @@ int              parseextcommunity(struct filter_ex
> >  static int  new_as_set(char *);
> >  static void         add_as_set(u_int32_t);
> >  static void         done_as_set(void);
> > -static int  new_prefix_set(char *);
> > +static struct prefixset    *new_prefix_set(char *, int);
> > +static void         add_roa_set(struct prefixset_item *, u_int32_t, 
> > u_int8_t);
> >  
> >  typedef struct {
> >     union {
> > @@ -211,7 +213,7 @@ typedef struct {
> >  %token     FROM TO ANY
> >  %token     CONNECTED STATIC
> >  %token     COMMUNITY EXTCOMMUNITY LARGECOMMUNITY DELETE
> > -%token     PREFIX PREFIXLEN PREFIXSET
> > +%token     PREFIX PREFIXLEN PREFIXSET ROASET
> >  %token     ASSET SOURCEAS TRANSITAS PEERAS MAXASLEN MAXASSEQ
> >  %token     SET LOCALPREF MED METRIC NEXTHOP REJECT BLACKHOLE NOMODIFY SELF
> >  %token     PREPEND_SELF PREPEND_PEER PFTABLE WEIGHT RTLABEL ORIGIN PRIORITY
> > @@ -250,6 +252,7 @@ grammar         : /* empty */
> >             | grammar include '\n'
> >             | grammar as_set '\n'
> >             | grammar prefixset '\n'
> > +           | grammar roa_set '\n'
> >             | grammar conf_main '\n'
> >             | grammar rdomain '\n'
> >             | grammar neighbor '\n'
> > @@ -423,7 +426,7 @@ as_set_l        : as4number_any                 { 
> > add_as_set(
> >             | as_set_l comma as4number_any  { add_as_set($3); }
> >  
> >  prefixset  : PREFIXSET STRING '{' optnl            {
> > -                   if (new_prefix_set($2) != 0) {
> > +                   if ((curpset = new_prefix_set($2, 0)) == NULL) {
> >                             free($2);
> >                             YYERROR;
> >                     }
> > @@ -433,7 +436,7 @@ prefixset       : PREFIXSET STRING '{' optnl            
> >                     curpset = NULL;
> >             }
> >             | PREFIXSET STRING '{' optnl '}'        {
> > -                   if (new_prefix_set($2) != 0) {
> > +                   if ((curpset = new_prefix_set($2, 0)) == NULL) {
> >                             free($2);
> >                             YYERROR;
> >                     }
> > @@ -487,6 +490,47 @@ prefixset_item : prefix prefixlenop                    
> > {
> >             }
> >             ;
> >  
> > +roa_set            : ROASET STRING '{' optnl               {
> > +                   if ((curroaset = new_prefix_set($2, 1)) == NULL) {
> > +                           free($2);
> > +                           YYERROR;
> > +                   }
> > +                   free($2);
> > +           } roa_set_l optnl '}'                   {
> > +                   SIMPLEQ_INSERT_TAIL(conf->roasets, curroaset, entry);
> > +                   curroaset = NULL;
> > +           }
> > +           | ROASET STRING '{' optnl '}'           {
> > +                   if ((curroaset = new_prefix_set($2, 1)) == NULL) {
> > +                           free($2);
> > +                           YYERROR;
> > +                   }
> > +                   free($2);
> > +                   SIMPLEQ_INSERT_TAIL(conf->roasets, curroaset, entry);
> > +                   curroaset = NULL;
> > +           }
> > +           ;
> > +
> > +roa_set_l  : prefixset_item SOURCEAS as4number_any                 {
> > +                   if ($1->p.len_min != $1->p.len) {
> > +                           yyerror("unsupported prefixlen operation in "
> > +                               "roa-set");
> > +                           free($1);
> > +                           YYERROR;
> > +                   }
> > +                   add_roa_set($1, $3, $1->p.len_max);
> > +           }
> > +           | roa_set_l comma prefixset_item SOURCEAS as4number_any {
> > +                   if ($3->p.len_min != $3->p.len) {
> > +                           yyerror("unsupported prefixlen operation in "
> > +                               "roa-set");
> > +                           free($3);
> > +                           YYERROR;
> > +                   }
> > +                   add_roa_set($3, $5, $3->p.len_max);
> > +           }
> > +           ;
> > +
> >  conf_main  : AS as4number          {
> >                     conf->as = $2;
> >                     if ($2 > USHRT_MAX)
> > @@ -2768,6 +2812,7 @@ lookup(char *s)
> >             { "restart",            RESTART},
> >             { "restricted",         RESTRICTED},
> >             { "rib",                RIB},
> > +           { "roa-set",            ROASET },
> >             { "route-collector",    ROUTECOLL},
> >             { "route-reflector",    REFLECTOR},
> >             { "router-id",          ROUTERID},
> > @@ -4230,21 +4275,52 @@ done_as_set(void)
> >     curset = NULL;
> >  }
> >  
> > -static int
> > -new_prefix_set(char *name)
> > +static struct prefixset *
> > +new_prefix_set(char *name, int is_roa)
> >  {
> > -   if (find_prefixset(name, conf->prefixsets) != NULL)  {
> > -           yyerror("prefix-set \"%s\" already exists", name);
> > -           return -1;
> > +   const char *type = "prefix-set";
> > +   struct prefixset_head *sets = conf->prefixsets;
> > +   struct prefixset *pset;
> > +
> > +   if (is_roa) {
> > +           type = "roa-set";
> > +           sets = conf->roasets;
> >     }
> > -   if ((curpset = calloc(1, sizeof(*curpset))) == NULL)
> > +
> > +   if (find_prefixset(name, sets) != NULL)  {
> > +           yyerror("%s \"%s\" already exists", type, name);
> > +           return NULL;
> > +   }
> > +   if ((pset = calloc(1, sizeof(*pset))) == NULL)
> >             fatal("prefixset");
> > -   if (strlcpy(curpset->name, name, sizeof(curpset->name)) >=
> > -       sizeof(curpset->name)) {
> > +   if (strlcpy(pset->name, name, sizeof(pset->name)) >=
> > +       sizeof(pset->name)) {
> >             yyerror("prefix-set \"%s\" too long: max %zu",
> > -               name, sizeof(curpset->name) - 1);
> > -                   return -1;
> > +               name, sizeof(pset->name) - 1);
> > +           free(pset);
> > +           return NULL;
> >     }
> > -   RB_INIT(&curpset->psitems);
> > -   return 0;
> > +   RB_INIT(&pset->psitems);
> > +   return pset;
> > +}
> > +
> > +static void
> > +add_roa_set(struct prefixset_item *npsi, u_int32_t as, u_int8_t max)
> > +{
> > +   struct prefixset_item   *psi;
> > +   struct roa_set rs;
> > +
> > +   /* no prefixlen option on this tree */
> > +   npsi->p.len_max = npsi->p.len_min = npsi->p.len;
> > +   psi = RB_INSERT(prefixset_tree, &curroaset->psitems, npsi);
> > +   if (psi == NULL)
> > +           psi = npsi;
> > +
> > +   if (psi->set == NULL)
> > +           if ((psi->set = set_new(1, sizeof(rs))) == NULL)
> > +                   fatal("set_new");
> > +   rs.as = as;
> > +   rs.maxlen = max;
> > +   if (set_add(psi->set, &rs, 1) != 0)
> > +           fatal("as_set_new");
> >  }
> > Index: printconf.c
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/bgpd/printconf.c,v
> > retrieving revision 1.121
> > diff -u -p -r1.121 printconf.c
> > --- printconf.c     20 Sep 2018 11:45:59 -0000      1.121
> > +++ printconf.c     20 Sep 2018 11:49:57 -0000
> > @@ -42,6 +42,7 @@ const char        *print_af(u_int8_t);
> >  void                print_network(struct network_config *, const char *);
> >  void                print_as_sets(struct as_set_head *);
> >  void                print_prefixsets(struct prefixset_head *);
> > +void                print_roasets(struct prefixset_head *);
> >  void                print_peer(struct peer_config *, struct bgpd_config *,
> >                 const char *);
> >  const char *print_auth_alg(u_int8_t);
> > @@ -486,6 +487,35 @@ print_prefixsets(struct prefixset_head *
> >  }
> >  
> >  void
> > +print_roasets(struct prefixset_head *psh)
> > +{
> > +   struct prefixset        *ps;
> > +   struct prefixset_item   *psi;
> > +   struct roa_set          *rs;
> > +   size_t                   i, n;
> > +
> > +   SIMPLEQ_FOREACH(ps, psh, entry) {
> > +           int count = 0;
> > +           printf("roa-set \"%s\" {", ps->name);
> > +           RB_FOREACH(psi, prefixset_tree, &ps->psitems) {
> > +                   rs = set_get(psi->set, &n);
> > +                   for (i = 0; i < n; i++) {
> > +                           if (count++ % 2 == 0)
> > +                                   printf("\n\t");
> > +                           else
> > +                                   printf(", ");
> > +
> > +                           print_prefix(&psi->p);
> > +                           if (psi->p.len != rs[i].maxlen)
> > +                                   printf(" maxlen %u", rs[i].maxlen);
> > +                           printf(" source-as %u", rs[i].as);
> > +                   }
> > +           }
> > +           printf("\n}\n\n");
> > +   }
> > +}
> > +
> > +void
> >  print_peer(struct peer_config *p, struct bgpd_config *conf, const char *c)
> >  {
> >     char            *method;
> > @@ -891,6 +921,7 @@ print_config(struct bgpd_config *conf, s
> >     print_mainconf(conf);
> >     print_prefixsets(conf->prefixsets);
> >     print_as_sets(conf->as_sets);
> > +   print_roasets(conf->roasets);
> >     TAILQ_FOREACH(n, net_l, entry)
> >             print_network(&n->net, "");
> >     if (!SIMPLEQ_EMPTY(rdom_l))
> > Index: rde.c
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
> > retrieving revision 1.425
> > diff -u -p -r1.425 rde.c
> > --- rde.c   20 Sep 2018 11:45:59 -0000      1.425
> > +++ rde.c   20 Sep 2018 11:49:57 -0000
> > @@ -131,6 +131,7 @@ time_t                   reloadtime;
> >  struct rde_peer_head        peerlist;
> >  struct rde_peer            *peerself;
> >  struct rde_prefixset_head *prefixsets_tmp, *prefixsets_old;
> > +struct rde_prefixset_head *roasets_tmp, *roasets_old;
> >  struct as_set_head *as_sets_tmp, *as_sets_old;
> >  struct filter_head *out_rules, *out_rules_tmp;
> >  struct rdomain_head        *rdomains_l, *newdomains;
> > @@ -689,6 +690,7 @@ rde_dispatch_imsg_parent(struct imsgbuf 
> >  {
> >     static struct rde_prefixset     *last_prefixset;
> >     static struct as_set    *last_as_set;
> > +   static struct set_table *last_set;
> >     static struct rdomain   *rd;
> >     struct imsg              imsg;
> >     struct mrt               xmrt;
> > @@ -702,7 +704,7 @@ rde_dispatch_imsg_parent(struct imsgbuf 
> >     struct prefixset_item    psi;
> >     char                    *name;
> >     size_t                   nmemb;
> > -   int                      n, fd;
> > +   int                      n, fd, rv;
> >     u_int16_t                rid;
> >  
> >     while (ibuf) {
> > @@ -774,6 +776,11 @@ rde_dispatch_imsg_parent(struct imsgbuf 
> >                     if (prefixsets_tmp == NULL)
> >                             fatal(NULL);
> >                     SIMPLEQ_INIT(prefixsets_tmp);
> > +                   roasets_tmp = calloc(1,
> > +                       sizeof(struct rde_prefixset_head));
> > +                   if (roasets_tmp == NULL)
> > +                           fatal(NULL);
> > +                   SIMPLEQ_INIT(roasets_tmp);
> >                     as_sets_tmp = calloc(1,
> >                         sizeof(struct as_set_head));
> >                     if (as_sets_tmp == NULL)
> > @@ -877,6 +884,7 @@ rde_dispatch_imsg_parent(struct imsgbuf 
> >                             TAILQ_INSERT_TAIL(out_rules_tmp, r, entry);
> >                     break;
> >             case IMSG_RECONF_PREFIXSET:
> > +           case IMSG_RECONF_ROA_SET:
> >                     if (imsg.hdr.len - IMSG_HEADER_SIZE !=
> >                         sizeof(ps->name))
> >                             fatalx("IMSG_RECONF_PREFIXSET bad len");
> > @@ -884,9 +892,22 @@ rde_dispatch_imsg_parent(struct imsgbuf 
> >                     if (ps == NULL)
> >                             fatal(NULL);
> >                     memcpy(ps->name, imsg.data, sizeof(ps->name));
> > -                   SIMPLEQ_INSERT_TAIL(prefixsets_tmp, ps, entry);
> > +                   if (imsg.hdr.type == IMSG_RECONF_ROA_SET) {
> > +                           SIMPLEQ_INSERT_TAIL(roasets_tmp, ps, entry);
> > +                           ps->roa = 1;
> > +                           last_set = set_new(1, sizeof(struct roa_set));
> > +                           if (last_set == NULL)
> > +                                   fatal(NULL);
> > +                   } else
> > +                           SIMPLEQ_INSERT_TAIL(prefixsets_tmp, ps, entry);
> >                     last_prefixset = ps;
> >                     break;
> > +           case IMSG_RECONF_ROA_AS_SET_ITEMS:
> > +                   nmemb = imsg.hdr.len - IMSG_HEADER_SIZE;
> > +                   nmemb /= sizeof(struct roa_set);
> > +                   if (set_add(last_set, imsg.data, nmemb) != 0)
> > +                           fatal(NULL);
> > +                   break;
> >             case IMSG_RECONF_PREFIXSETITEM:
> >                     if (imsg.hdr.len - IMSG_HEADER_SIZE !=
> >                         sizeof(psi))
> > @@ -894,11 +915,19 @@ rde_dispatch_imsg_parent(struct imsgbuf 
> >                     memcpy(&psi, imsg.data, sizeof(psi));
> >                     if (last_prefixset == NULL)
> >                             fatalx("King Bula has no prefixset");
> > -                   if (trie_add(&last_prefixset->th, &psi.p.addr,
> > -                       psi.p.len, psi.p.len_min, psi.p.len_max) == -1)
> > -                           log_warnx("trie_add(%s) %s/%u, %u-%u) failed",
> > +                   if (last_prefixset->roa) {
> > +                           set_prep(last_set);
> > +                           rv = trie_roa_add(&last_prefixset->th,
> > +                               &psi.p.addr, psi.p.len, last_set);
> > +                   } else {
> > +                           rv = trie_add(&last_prefixset->th,
> > +                               &psi.p.addr, psi.p.len,
> > +                               psi.p.len_min, psi.p.len_max);
> > +                   }
> > +                   if (rv == -1)
> > +                           log_warnx("trie_add(%s) %s/%u) failed",
> >                                 last_prefixset->name, log_addr(&psi.p.addr),
> > -                               psi.p.len, psi.p.len_min, psi.p.len_max);
> > +                               psi.p.len);
> >                     break;
> >             case IMSG_RECONF_AS_SET:
> >                     if (imsg.hdr.len - IMSG_HEADER_SIZE !=
> > @@ -2795,6 +2824,7 @@ rde_reload_done(void)
> >     }
> >  
> >     prefixsets_old = conf->rde_prefixsets;
> > +   roasets_old = conf->rde_roasets;
> >     as_sets_old = conf->as_sets;
> >  
> >     memcpy(conf, nconf, sizeof(struct bgpd_config));
> > @@ -2802,6 +2832,7 @@ rde_reload_done(void)
> >     conf->csock = NULL;
> >     conf->rcsock = NULL;
> >     conf->prefixsets = NULL;
> > +   conf->roasets = NULL;
> >     free(nconf);
> >     nconf = NULL;
> >  
> > @@ -2826,11 +2857,15 @@ rde_reload_done(void)
> >     /* XXX WHERE IS THE SYNC ??? */
> >  
> >     rde_mark_prefixsets_dirty(prefixsets_old, prefixsets_tmp);
> > +   rde_mark_prefixsets_dirty(roasets_old, roasets_tmp);
> >     as_sets_mark_dirty(as_sets_old, as_sets_tmp);
> >  
> >     /* swap the prefixsets */
> >     conf->rde_prefixsets = prefixsets_tmp;
> >     prefixsets_tmp = NULL;
> > +   /* the roa-sets */
> > +   conf->rde_roasets = roasets_tmp;
> > +   roasets_tmp = NULL;
> >     /* and the as_sets */
> >     conf->as_sets = as_sets_tmp;
> >     as_sets_tmp = NULL;
> > @@ -3022,6 +3057,8 @@ rde_softreconfig_done(void)
> >  
> >     rde_free_prefixsets(prefixsets_old);
> >     prefixsets_old = NULL;
> > +   rde_free_prefixsets(roasets_old);
> > +   roasets_old = NULL;
> >     as_sets_free(as_sets_old);
> >     as_sets_old = NULL;
> >  
> > 
> 

-- 
:wq Claudio

Reply via email to