From: Claudio Jeker Subject: bgpd: prefix_evaluate is tricky To: tech@openbsd.org Date: Thu, 14 May 2026 15:36:33 +0200 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. -- :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); }