> But those calls have either a break or continue, so either the loop is > exited or restarted (depending on PEERFLAG_EVALUATE_ALL).
That's what I was missing. Not sure how. > So there should be no way to go from a rde_filterstate_clean(&state) to > prefix_adjout_update(new). > > There is a missing rde_filterstate_clean(&state) in up_generate_update(). > if (up_enforce_open_policy(peer, &state)) { > rde_filterstate_clean(&state); > if (peer->flags & PEERFLAG_EVALUATE_ALL) { > new = TAILQ_NEXT(new, entry.list.rib); > if (new != NULL && prefix_eligible(new)) > continue; > } > break; > } > > /* check if this was actually a withdraw */ > if (need_withdraw) > >>>>>>>> here the filterstate is leaked, which is bad. > break; > > /* from here on we know this is an update */ > > up_prep_adjout(peer, &state, addr.aid); > prefix_adjout_update(p, peer, &state, &addr, > new->pt->prefixlen, new->path_id_tx); > rde_filterstate_clean(&state); > > Below a diff that fixes the extra leak. Agreed. I'm now happy with the diff. Sorry about the confusion. ok tb