bgpkit-parser 0.18.0 Release
bgpkit-parser 0.18.0 preserves more of the original BGP wire data. Earlier versions parsed many common attributes into typed Rust structures, but element conversion could drop known attributes that did not yet have a semantic parser. That worked for many analysis workflows, but it was not enough for users who need to inspect, serialize, or re-encode less common BGP path attributes.
This release changes that behavior: the parser now retains known-but-unsupported, malformed, deprecated, and unknown BGP path attributes in AttrRaw-backed variants instead of silently dropping them.
Install
cargo add [email protected]
For the WebAssembly package:
npm install @bgpkit/[email protected]
RIS Live raw message parsing
RIS Live’s JSON messages expose a convenient projection of UPDATE data, but that projection does not include every BGP path attribute. For example, attributes such as Only to Customer (OTC, code 35), BGP Prefix-SID, BFD Discriminator, and other less common path attributes may appear in the raw UPDATE while remaining absent from the projected JSON fields. Version 0.18.0 adds helpers that parse RIS Live messages containing the original raw BGP UPDATE bytes.
To request raw BGP messages from RIS Live, set socketOptions.includeRaw in the subscription message. The crate now re-exports RisSubscribe, RisSubscribeType, and RisLiveClientMessage from the crate root, so examples and downstream applications can build subscription messages directly.
use bgpkit_parser::{RisLiveClientMessage, RisSubscribe};
let subscribe = RisSubscribe::new()
.with_host("rrc00")
.with_include_raw(true);
let msg = RisLiveClientMessage::RisSubscribe(subscribe).to_json_string().unwrap();
// send `msg` over a WebSocket connection to RIS Live
When a RIS Live message arrives, parse the full ris_message envelope with the raw parser:
use bgpkit_parser::parse_ris_live_message_raw;
let elems = parse_ris_live_message_raw(message_text).expect("parse RIS Live message");
for elem in elems {
println!("{} {} {:?}", elem.elem_type, elem.prefix, elem.as_path);
}
Users who prefer RIS Live’s JSON-projected fields can call parse_ris_live_message_json() for the explicit JSON-path parser, or keep using the older parse_ris_live_message() function for the same JSON-projected path.
Raw BGP attribute retention
The main parser now keeps raw bytes for attributes it cannot or should not decode semantically. The new AttributeValue::Raw(AttrRaw) variant stores the wire attribute code and value bytes for known-but-unsupported attributes:
use bgpkit_parser::models::bgp::attributes::AttributeValue;
for attr in attributes.inner.iter() {
match attr {
AttributeValue::Raw(raw) => {
println!("raw attribute code={} len={}", raw.code, raw.bytes.len());
}
other => {
println!("typed attribute code={}", other.attr_code());
}
}
}
This matters for round-trip workflows. If a route contains a known attribute that bgpkit-parser does not yet decode into a typed model, 0.18.0 preserves and re-encodes the original attribute bytes.
Malformed attributes that target typed parsers now fall back to Raw after recording a validation warning, rather than disappearing from the parsed attribute list.
Deprecated attribute code handling
The IANA registry lists attribute code 13 as deprecated: RCID_PATH / CLUSTER_ID. Version 0.18.0 removes AttrType::CLUSTER_ID and retains code 13 as deprecated raw data instead.
If downstream code exhaustively matches AttrType or AttributeValue, this is one of the release’s breaking changes. Use AttributeValue::attr_code() when the raw code point matters, and AttrRaw::attr_type() when you want to map the raw wire code back to an AttrType value.
New typed BGP path attribute parsers
This release adds typed parsers and round-trip encoding support for several RFC-defined path attributes:
- RFC 7311 — AIGP, attribute code 26
- RFC 9015 — SFP, attribute code 37
- RFC 9026 — BFD Discriminator, attribute code 38
- RFC 8669 — BGP Prefix-SID, attribute code 40
- RFC 9793 — BIER, attribute code 41
Each parser preserves unknown TLVs, so applications can inspect known fields without losing the rest of the attribute payload.
For example, AIGP exposes an accumulated_metric() helper:
use bgpkit_parser::models::bgp::attributes::AttributeValue;
for attr in attributes.inner.iter() {
if let AttributeValue::Aigp(aigp) = attr {
if let Some(metric) = aigp.accumulated_metric() {
println!("AIGP accumulated metric: {metric}");
}
}
}
API changes to note
The main breaking changes affect raw attribute representation and exhaustive matches:
AttrRawnow storescode: u8instead ofattr_type: AttrType.AttrRaw.bytesnow usesbytes::Bytesinstead ofVec<u8>.AigpTlv.valuenow usesBytes.AttributeValuehas new variants:Raw,BfdDiscriminator,BgpPrefixSid,Bier, andSfp.- The release removes
AttrType::CLUSTER_ID.
For most users who iterate over BgpElem, the visible behavior should stay the same except that the parser preserves more attributes internally. Code that destructures attributes or performs exhaustive matching will need updates.
WebAssembly package
The @bgpkit/parser npm package also ships 0.18.0. The WASM package continues to expose parsers for BGP UPDATE, BMP/OpenBMP, and MRT data in Node.js, bundler, browser, and Worker environments.
import { parseBgpUpdate } from '@bgpkit/parser';
const elems = parseBgpUpdate(updateBytes);
for (const elem of elems) {
console.log(elem.type, elem.prefix, elem.as_path);
}
The Rust crate includes RIS Live parsing in this release. We track WASM-level RIS Live parser exports and WebSocket helpers separately.