From: Theo Buehler Subject: Re: bgpd: prefix_evaluate is tricky To: tech@openbsd.org Date: Thu, 14 May 2026 16:07:10 +0200 On Thu, May 14, 2026 at 03:36:33PM +0200, Claudio Jeker wrote: > I tricked myself again in thinking that changing the state of a prefix and > then calling prefix_evaluate(re, p, p); would do the right thing. > It does not, at least not in all cases. > > The problem is that prefix_evaluate() uses prefix_best() to decide if the > overall route decision changed or not. prefix_best() is influenced by > prefix_eligible() and so changing PREFIX_FLAG_FILTERED also affects the > prefix_best() calls inside prefix_evaluate(). > > If the only prefix sets PREFIX_FLAG_FILTERED then the code would not > correctly withdraw the route. In the current code > oldbest = prefix_best(re); > already returns NULL even though the path is still active. > > This is similar to prefix_evaluate_nexthop() but I decided to fix this > with a more brutal method. First remove the prefix, then readd it. > Since the flag is toggled no real extra work should be caused by this. Reads fine. Thanks for the detailed explanation. That saved quite some time in following the change. ok tb > > -- > :wq Claudio > > Index: rde_rib.c > =================================================================== > RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v > diff -u -p -r1.293 rde_rib.c > --- rde_rib.c 13 May 2026 14:06:24 -0000 1.293 > +++ rde_rib.c 14 May 2026 13:22:56 -0000 > @@ -890,11 +890,13 @@ prefix_update(struct rib *rib, struct rd > if (p_filtered != filtered) { > struct rib_entry *re; > > + re = rib_get_addr(rib, prefix, prefixlen); > + /* remove prefix from rib */ > + prefix_evaluate(re, NULL, p); > /* toggle filtered flag */ > p->flags ^= PREFIX_FLAG_FILTERED; > - /* make route decision */ > - re = rib_get_addr(rib, prefix, prefixlen); > - prefix_evaluate(re, p, p); > + /* redo route decision */ > + prefix_evaluate(re, p, NULL); > } > return (0); > } >