From: Claudio Jeker Subject: bgpd: fix error handling PREFIX_FLAG_FILTERED To: tech@openbsd.org Date: Mon, 4 May 2026 21:15:11 +0200 With the introduction of 'rde rib Loc-RIB include filtered' it is possible that prefixes change prefix_eligible() outcome without a change of attributes or nexthop. This happens when new filters are installed. In prefix_update() this takes a shortcut path but that path is missing a call to prefix_evaluate() to ensure that if the filtered flag changes an update is forced. Below is my try to fix this. If the filtered state changed, toggle the PREFIX_FLAG_FILTERED bit and then call prefix_evaluate(). If the filtered flag is in sync with filtered then this can be skipped. I used p_filtered to be 0 or 1 and check against !filtered (to ensure that this value is also 0 or 1). I hope that's not too much magic... -- :wq Claudio Index: rde_rib.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v diff -u -p -r1.290 rde_rib.c --- rde_rib.c 17 Mar 2026 09:29:29 -0000 1.290 +++ rde_rib.c 4 May 2026 18:36:51 -0000 @@ -872,13 +872,22 @@ prefix_update(struct rib *rib, struct rd prefix_nhflags(p) == state->nhflags && communities_equal(ncomm, prefix_communities(p)) && path_equal(nasp, prefix_aspath(p))) { + int p_filtered; + /* no change, update last change */ p->lastchange = getmonotime(); p->validation_state = state->vstate; - if (filtered) - p->flags |= PREFIX_FLAG_FILTERED; - else - p->flags &= ~PREFIX_FLAG_FILTERED; + p_filtered = (p->flags & PREFIX_FLAG_FILTERED) != 0; + /* check if filtered flag changed */ + if (p_filtered == !filtered) { + struct rib_entry *re; + + /* toggle filtered flag */ + p->flags ^= PREFIX_FLAG_FILTERED; + /* make route decision */ + re = rib_get_addr(rib, prefix, prefixlen); + prefix_evaluate(re, p, p); + } return (0); } }