> 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

Reply via email to