fix: rv-live should honor the BMP peer A flag - #39
Merged
Merged
Conversation
processRecord() parsed the BGP message without setting Meta.ParseAS4, so attribute parsing fell back to the pipe-wide caps, which default to CAP_AS4 on and CAP_AS_GUESS off. Peers that never negotiated RFC 6793 with the collector thus failed with "ASPATH: invalid ASPATH segment length: N < 2+4*M" and were dropped. Bmp.FromBytes() already parses the Per-Peer header, whose A flag (RFC 7854/4.2) announces the legacy 2-byte AS_PATH format. bmp.Reader.setMeta() uses it, so "read --format=obmp" has always handled such peers correctly - only the Kafka path ignored it. The flag is trusted only when set. Setting ParseAS4=1 on a clear flag would be the strict reading, but senders that never set it (routeviews, as of 2026-09) would then pin every peer to 4-byte ASNs and short-circuit the retry in attrs.Aspath.Unmarshal, silently breaking --guess-asn: measured against routeviews route-views7, --guess-asn went 0 -> 720 parse errors per ~90s. NB: must happen before fixPath(), which triggers attribute parsing.
There was a problem hiding this comment.
🟢 Approval recommended
The change is minimal, well-scoped to the Kafka rv-live path, and addresses the described failure mode without introducing risky behavioral changes for non-legacy peers.
Pull request overview
This PR fixes rv-live (Kafka/OpenBMP ingestion path) so it honors the BMP per-peer A flag when deciding whether to parse AS_PATH as legacy 2-byte ASNs, aligning its behavior with the existing read --format=obmp BMP reader and preventing UPDATE drops from legacy peers.
Changes:
- Set
m.ParseAS4 = -1when the BMP peer indicates 2-byte AS_PATH (bm.Peer.Is2ByteAS()), before any UPDATE attribute parsing is triggered (e.g., byfixPath). - Document why the flag is only trusted when set (to avoid breaking
--guess-asnin the presence of non-conformant senders).
File summaries
| File | Description |
|---|---|
| stages/rv-live/openbmp.go | Apply per-peer BMP A-flag-derived AS_PATH parsing mode to the message meta before UPDATE attribute parsing occurs. |
Review details
- Files reviewed: 1/1 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
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.
Problem
rv-livedropped UPDATEs from any peer that did not negotiate 4-byte ASNs (RFC 6793) with the collector:Reported by a RouteViews operator against
route-views7peer AS40864, and reproducible on RIPE RIS too.processRecord()parsed the BGP message without ever settingMeta.ParseAS4, so attribute parsing fell back to the pipe-wide caps — which default toCAP_AS4on andCAP_AS_GUESSoff. Every peer was therefore parsed as 4-byte, and legacy peers failed hard and were dropped.Fix
The per-peer answer was already in hand and being discarded.
Bmp.FromBytes()parses the Per-Peer header, whose A flag (RFC 7854 §4.2) announces the legacy 2-byte AS_PATH format.bmp.Reader.setMeta()honors it — which is whyread --format=obmphas always handled these peers correctly. Only the Kafka path ignored it.Eight lines, no parser swap: just read the flag that
bm.Peeralready carries, beforefixPath()triggers attribute parsing.Why the flag is trusted only when set
The strict reading of RFC 7854 is that a clear A flag means 4-byte. That turns out to be actively harmful in the field, because senders that never set the flag then pin every peer to 4-byte — and
ParseAS4 = 1also short-circuits the retry inattrs.Aspath.Unmarshal, silently disabling--guess-asn.RouteViews is such a sender. Measured on their live feed,
route-views7, ~92k route-monitoring messages across 15 peers:The flag is clear on 100% of messages. For the 14 modern peers that is accidentally correct; for AS40864 it is wrong.
Validation
Against live
routeviews route-views7, 75–90s windows:--guess-asnThe strict variant was implemented first and measured at 720 errors with
--guess-asn(vs 0), which is what motivated the narrower rule.Since RouteViews never sets the flag, this change is a no-op against their feed today — the before/after difference without
--guess-asnis window-to-window variance in AS40864's announcement rate, not an effect. It is correct for any conformant sender, bringsrv-livein line withread --format=obmp, and leaves--guess-asnworking as the escape hatch for non-conformant ones.Also verified with synthetic OpenBMP records carrying a real 2-byte UPDATE: flag set parses
[61292,24482,16509], flag clear reproduces the reported error byte-for-byte.