Skip to content

fix: rv-live should honor the BMP peer A flag - #39

Merged
pforemski merged 1 commit into
mainfrom
fix-rvlive-as4
Sep 4, 2026
Merged

pforemski merged 1 commit into
mainfrom
fix-rvlive-as4

Conversation

@pforemski

Copy link
Copy Markdown
Contributor

Problem

rv-live dropped UPDATEs from any peer that did not negotiate 4-byte ASNs (RFC 6793) with the collector:

ASPATH: invalid ASPATH segment length: 22 < 2+4*10

Reported by a RouteViews operator against route-views7 peer AS40864, and reproducible on RIPE RIS too.

processRecord() parsed the BGP message without ever setting Meta.ParseAS4, so attribute parsing fell back to the pipe-wide caps — which default to CAP_AS4 on and CAP_AS_GUESS off. 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 why read --format=obmp has always handled these peers correctly. Only the Kafka path ignored it.

Eight lines, no parser swap: just read the flag that bm.Peer already carries, before fixPath() 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 = 1 also short-circuits the retry in attrs.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:

PEER_AS    Aflag_set Aflag_clr   only2B   only4B   MISMATCH
40864              0       199      147        0        147  <-- 2-byte on the wire, flag says otherwise
16276              0     68421        0    63700          0
48112              0      1457        0     1353          0
...
total route-monitoring msgs: 91628, distinct peers: 15

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:

ASPATH errors with --guess-asn
before 233 0
after 143 0

The 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-asn is window-to-window variance in AS40864's announcement rate, not an effect. It is correct for any conformant sender, brings rv-live in line with read --format=obmp, and leaves --guess-asn working 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.

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.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 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 = -1 when the BMP peer indicates 2-byte AS_PATH (bm.Peer.Is2ByteAS()), before any UPDATE attribute parsing is triggered (e.g., by fixPath).
  • Document why the flag is only trusted when set (to avoid breaking --guess-asn in 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.

@pforemski
pforemski merged commit 1c74272 into main Sep 4, 2026
3 checks passed
@pforemski
pforemski deleted the fix-rvlive-as4 branch September 4, 2026 11:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants