On Thu, Oct 25, 2018 at 09:04:18PM +0200, Denis Fondras wrote: > On Thu, Oct 25, 2018 at 08:51:30AM +0200, Claudio Jeker wrote: > > Next step on my quest to make the RIB code better. > > This changes the following things: > > - network_flush is now using rib_dump_new to walk the Adj-RIB-In and > > remove all dynamically added announcements > > - peer_flush got generalized and is now used also in peer_down. > > It also uses a rib_dump_new call to walk the Adj-RIB-In and remove > > all prefixes from a peer but this is done synchronous for now. > > - peer_flush is now working correctly for AID_UNSPEC. > > - Change the rib_valid check to continue instead of break out of the loop. > > The rib table can have holes so the loop needs to continue. > > > > This removes the last three places that use the peer -> path -> prefix > > tailqs so the next step is to remove these and make rde_aspath just an > > object that is referenced by prefixes. After that adding a proper > > Adj-RIB-Out should be possible. > > > > Question below. > Running on prod too :) > > > Index: rde_rib.c > > =================================================================== > > RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v > > retrieving revision 1.180 > > diff -u -p -r1.180 rde_rib.c > > --- rde_rib.c 24 Oct 2018 08:26:37 -0000 1.180 > > +++ rde_rib.c 24 Oct 2018 08:44:54 -0000 > > @@ -339,8 +339,8 @@ rib_restart(struct rib_context *ctx) > > static void > > rib_dump_r(struct rib_context *ctx) > > { > > + struct rib_entry *re, *next; > > struct rib *rib; > > - struct rib_entry *re; > > unsigned int i; > > > > rib = rib_byid(ctx->ctx_rib_id); > > @@ -352,7 +352,8 @@ rib_dump_r(struct rib_context *ctx) > > else > > re = rib_restart(ctx); > > > > - for (i = 0; re != NULL; re = RB_NEXT(rib_tree, unused, re)) { > > + for (i = 0; re != NULL; re = next) { > > + next = RB_NEXT(rib_tree, unused, re); > > Why not RB_FOREACH_SAFE ?
Because we do not start with RB_MIN. The inital element is set above and so we can't use a regular RB_FOREACH loop either. > > if (re->rib_id != ctx->ctx_rib_id) > > fatalx("%s: Unexpected RIB %u != %u.", __func__, > > re->rib_id, ctx->ctx_rib_id); > > @@ -435,6 +436,10 @@ rib_dump_new(u_int16_t id, u_int8_t aid, > > > > LIST_INSERT_HEAD(&rib_dumps, ctx, entry); > > > > + /* requested a sync traversal */ > > + if (count == 0) > > + rib_dump_r(ctx); > > + > > return 0; > > } > > > > @@ -664,65 +669,6 @@ path_lookup(struct rde_aspath *aspath, s > > return (NULL); > > } > > > > -void > > -path_remove(struct rde_aspath *asp) > > -{ > > - struct prefix *p, *np; > > - > > - for (p = TAILQ_FIRST(&asp->prefixes); p != NULL; p = np) { > > - np = TAILQ_NEXT(p, path_l); > > - if (asp->pftableid) { > > - struct bgpd_addr addr; > > - > > - pt_getaddr(p->re->prefix, &addr); > > - /* Commit is done in peer_down() */ > > - rde_send_pftable(prefix_aspath(p)->pftableid, &addr, > > - p->re->prefix->prefixlen, 1); > > - } > > - prefix_destroy(p); > > - } > > -} > > - > > -/* remove all stale routes or if staletime is 0 remove all routes for > > - a specified AID. */ > > -u_int32_t > > -path_remove_stale(struct rde_aspath *asp, u_int8_t aid, time_t staletime) > > -{ > > - struct prefix *p, *np; > > - u_int32_t rprefixes; > > - > > - rprefixes=0; > > - /* > > - * This is called when a session flapped and during that time > > - * the pending updates for that peer are getting reset. > > - */ > > - for (p = TAILQ_FIRST(&asp->prefixes); p != NULL; p = np) { > > - np = TAILQ_NEXT(p, path_l); > > - if (p->re->prefix->aid != aid) > > - continue; > > - > > - if (staletime && p->lastchange > staletime) > > - continue; > > - > > - if (asp->pftableid) { > > - struct bgpd_addr addr; > > - > > - pt_getaddr(p->re->prefix, &addr); > > - /* Commit is done in peer_flush() */ > > - rde_send_pftable(prefix_aspath(p)->pftableid, &addr, > > - p->re->prefix->prefixlen, 1); > > - } > > - > > - /* only count Adj-RIB-In */ > > - if (re_rib(p->re) == &ribs[RIB_ADJ_IN].rib) > > - rprefixes++; > > - > > - prefix_destroy(p); > > - } > > - return (rprefixes); > > -} > > - > > - > > /* > > * This function can only called when all prefix have been removed first. > > * Normally this happens directly out of the prefix removal functions. > > @@ -1144,29 +1090,6 @@ prefix_destroy(struct prefix *p) > > > > if (path_empty(asp)) > > path_destroy(asp); > > -} > > - > > -/* > > - * helper function to clean up the dynamically added networks > > - */ > > -void > > -prefix_network_clean(struct rde_peer *peer) > > -{ > > - struct rde_aspath *asp, *xasp; > > - struct prefix *p, *xp; > > - > > - for (asp = TAILQ_FIRST(&peer->path_h); asp != NULL; asp = xasp) { > > - xasp = TAILQ_NEXT(asp, peer_l); > > - if ((asp->flags & F_ANN_DYNAMIC) != F_ANN_DYNAMIC) > > - continue; > > - for (p = TAILQ_FIRST(&asp->prefixes); p != NULL; p = xp) { > > - xp = TAILQ_NEXT(p, path_l); > > - prefix_unlink(p); > > - prefix_free(p); > > - } > > - if (path_empty(asp)) > > - path_destroy(asp); > > - } > > } > > > > /* > > > -- :wq Claudio