fix(render): stop logging every route the export catch-all drops - #29
Merged
Merged
Conversation
Every generated export filter ended in `reject "not permitted by any export policy"`, and BIRD logs a reject's message once per route. On a full-table router that line drops nearly the whole table on each export to an upstream or iBGP peer, so each session (re)establishment and routine churn floods syslog. One production router logged 9.5 million such lines in three days, and journald's rate limiter then dropped the BGP/BFD session events alongside them. The catch-all is now a bare `reject;`. The targeted rejects inside policy functions keep their reasons; they fire rarely and say something useful. `show route noexport`, behind the peer page's "Rejected on export" tab, still answers which routes were withheld. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review of the export fix found the same flood on the import side: an allow-list (`not in SET`), the default-only rule, an origin AS set, the origin-only check, and the fail-closed rejects for a disabled or other-family allow-list all rejected everything not explicitly allowed with a message, and BIRD logs that message once per route. USAGE even recommends an allow-list import on iBGP, where the far end sends a full table. These catch-alls are now bare `reject;` with the reason as a config comment, as is the export catch-all. Vetoes (bogon, RPKI invalid, AS-path, prefix length, first AS) keep their messages: they name one thing wrong with a route. TestOnlyVetoRejectsCarryAMessage renders every catch-all and fails on any messaged reject not on the veto list, so a new one has to be added on purpose. The code comment and CHANGELOG no longer claim `show route noexport` says why a route was withheld (it lists which), and the CHANGELOG notes the change lands on the next apply. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
floreabogdan
force-pushed
the
fix/quiet-export-reject
branch
from
September 30, 2026 14:19
7d53f70 to
9f7bd00
Compare
Owner
Author
|
Review follow-up (pushed; rebased onto
Re-verified locally (Actions is still billing-locked): gofmt, vet, golangci-lint, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every generated export filter ends in
reject "not permitted by any export policy";, and BIRD logs a reject's message once per route. On a full-table router, that catch-all drops nearly the whole table on each export to an upstream or iBGP peer. It fires on every session (re)establishment and on routine table churn.On rt1.kicked.ro (full tables from Digi, four iBGP sessions over GRE), the journal held 9,536,490 of these lines covering about three days. journald's rate limiter was suppressing up to ~1.5 M
bird.servicemessages per 30 s window. It dropped the BGP and BFD events along with them, which is exactly what you need when chasing flapping sessions.Change: the catch-all becomes a bare
reject;. The targeted rejects inside the policy functions ("bogon prefix","RPKI invalid", …) keep their reasons: they fire rarely and say something useful. Nothing reads the message back. The peer page's Rejected on export tab usesshow route noexport, not the log.Test:
TestExportChainEndsInRejectnow asserts that the filter ends in a barereject;and carries no reject message. It was watched failing against the old rendering first.Verification: GitHub Actions is currently refusing to start jobs (account billing lock), so this was verified locally with the
ci.ymlsteps, on go1.26.8 withGOTOOLCHAIN=local: gofmt, vet, golangci-lint (0 issues),go test -race ./..., govulncheck (none reachable), build, and the BIRD 2.14 integration test all pass.If this merges after #21, the CHANGELOG hunk (the
[Unreleased]→### Fixedsection) will need a trivial rebase, since #21 adds its own sections there.🤖 Generated with Claude Code