> 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