Skip to content

v0.20.0

Choose a tag to compare

@github-actions github-actions released this 16 Aug 03:27
· 33 commits to main since this release
v0.20.0
800bb04

Breaking changes

  • Fallible encoding (#313): all encode paths now return Result<_, EncodingError> instead of silently truncating values that do not fit their wire-format fields. There are no panicking wrappers; callers that want the old "just give me bytes" ergonomics can .unwrap(). Migration table:

    Before After
    Attribute::encode(asn_len) -> Bytes -> Result<Bytes, EncodingError> (also encode_to(asn_len, &mut BytesMut))
    Attributes::encode(asn_len) -> Bytes -> Result<Bytes, EncodingError> (also encode_to)
    BgpOpenMessage::encode() -> Bytes -> Result<Bytes, EncodingError>
    BgpUpdateMessage::encode(asn_len) -> Bytes -> Result<Bytes, EncodingError>
    BgpMessage::encode(asn_len) -> Bytes -> Result<Bytes, EncodingError>
    TableDumpMessage::encode() -> Bytes -> Result<Bytes, EncodingError>
    RibEntry::encode() / RibAfiEntries::encode() -> Bytes -> Result<Bytes, EncodingError>
    PeerIndexTable::encode() / GeoPeerTable::encode() -> Bytes -> Result<Bytes, EncodingError>
    PeerIndexTable::add_peer(peer) -> u16 -> Result<u16, EncodingError> (rejects the 65,536th peer instead of wrapping the id)
    MrtMessage::encode(sub_type) / Bgp4MpMessage::encode(asn_len) / MrtRecord::encode() -> Bytes -> Result<Bytes, EncodingError>
    MrtRibEncoder::process_elem(&elem) -> Result<(), EncodingError>
    MrtRibEncoder::export_bytes() / MrtUpdatesEncoder::export_bytes() -> Bytes -> Result<Bytes, EncodingError>

    EncodingError has two variants: ValueTooLarge { field, actual, max } for wire-capacity overflows and Unencodable { field, reason } for values with no valid wire representation (ATTR_SET, RIB_GENERIC, OPEN parameter type 255, labeled NLRI with an empty label stack).

  • Legacy MRT enum variants: MrtMessage gains TableDumpMessageBatch and LegacyBgp, and MrtUpdate gains LegacyBgpUpdate. Downstream exhaustive matches must handle the new variants.

  • Traffic Engineering attribute variant: AttributeValue gains TrafficEngineering (#290). The code-24 BGP Traffic Engineering attribute (RFC 5543), previously raw-retained, now parses to this typed variant. Downstream exhaustive matches must handle the new variant.

  • Link Bandwidth extended community variant: ExtendedCommunity gains LinkBandwidth (#299). Two-octet AS-specific extended communities with subtype 0x04 (RFC 10005 link bandwidth) now parse to this variant instead of TransitiveTwoOctetAs / NonTransitiveTwoOctetAs, changing their Display and serde representations (wire encoding is byte-identical). Downstream exhaustive matches must handle the new variant.

  • Tlv::length() and SubTlv::length() removed: both silently saturated at u16::MAX; encoders now compute checked lengths internally.

  • OptParam no longer has a param_len field: the field was redundant now that the encoder always derives the wire length from param_value, and the parser recomputes it on read. Construct OptParam with just param_type and param_value.

  • Quagga BGP states: BgpState gains the implementation-specific Clearing and Deleted variants for wire values 7 and 8. Downstream exhaustive matches must handle the new variants.

  • ROUTE-REFRESH message variant: BgpMessage gains RouteRefresh(BgpRouteRefreshMessage) and BgpMessageType gains ROUTE_REFRESH for BGP message type 5 (RFC 2918), previously rejected as "Unknown BGP Message Type". Downstream exhaustive matches must handle the new variants.

Added

Parser interfaces

  • Unified MRT/text-dump parser API (#321): BgpkitParser gains three new constructor groups that integrate text dumps into the standard for elem in parser iteration loop. new_text(path) / from_text_reader(r) parse a known text dump; new_auto(path) / from_auto_reader(r) peek the first bytes and auto-dispatch to the text or MRT path. Both text-dump paths stream elements lazily — one route line at a time, constant memory — via a new TextDumpElemIterator. All existing filter methods (add_filter, with_filters, etc.) work on both paths. The default new(path) constructor remains MRT-only.
  • Diagnostic MRT iterator (#324, #303): added into_diagnostic_iter() for record-level malformed-data investigation. It emits clean records, recoverable RFC 7606 validation findings with original MRT bytes, and fatal parse errors with available header and byte context.
  • Experimental resumable HTTP reader (#323): BgpkitParser::new_resumable_http uses oneio's range-request reader to resume interrupted HTTP(S) downloads without changing the behavior of new. Unsupported Range requests or inconsistent resumed responses return an error (#288).
  • Cisco sh ip bgp text dump parsing (#320): new parser::text_dump module parses fixed-width text RIB dumps published by PCH (daily routing table snapshots) and route-views (oix-full-snapshot-*.bz2) into BgpElems. Column offsets are derived from the table header so blank numeric columns (Metric, LocPrf, Weight) stay distinct from AS-path data; multipath continuation lines and wrapped prefixes (including IPv6) are supported. Route-views dumps without the BGP table version / local AS preamble parse with sentinel peer identity (0.0.0.0 / AS0) (#321). Also provides detect_text_dump for format sniffing and infer_timestamp_from_path for PCH (YYYY.MM.DD) and route-views (YYYY-MM-DD-HHMM) file-name timestamps. Ported from monocle (#143, #146).

Protocol support

  • Early RIPE RIS MRT support (#316): Parse deprecated MRT Type 5 BGP OPEN, UPDATE, NOTIFY, KEEPALIVE, and STATE_CHANGE records, along with historical TABLE_DUMP v1 records that batch multiple entries and declare their physical length four bytes short. Record iteration preserves each physical TABLE_DUMP batch while element, update, and route iteration expands its entries.
  • RFC 5543 Traffic Engineering attribute (#322): Typed parsing and encoding for the BGP Traffic Engineering attribute (type 24) (#290). Exposes the Switching Capability, Encoding, Reserved, and eight Maximum LSP Bandwidth fields (IEEE-754), and retains switching-capability-specific information as raw bytes with wire-faithful round-trip.
  • RFC 2918 ROUTE-REFRESH messages (#326): Parse and encode BGP ROUTE-REFRESH messages (type 5) found in RIS BGP4MP update archives. AFI and SAFI are kept as raw integers so refreshes for address families outside the typed enums still round-trip byte-for-byte; the reserved byte is exposed as the RFC 7313 message subtype and trailing ORF data (RFC 5291) is retained raw. ROUTE-REFRESH records yield no elements. RFC 7313 Section 5 findings — an unknown message subtype, or a BoRR/EoRR message whose body is not exactly 4 bytes — surface as new BgpValidationWarning variants (UnknownRouteRefreshSubtype, InvalidRouteRefreshLength) through BgpRouteRefreshMessage::validation_warnings() and the diagnostic iterator, while the message itself is retained.
  • RFC 10005 Link Bandwidth Extended Community (#319): Typed parsing and encoding for the BGP Link Bandwidth Extended Community in both transitive (0x00) and non-transitive (0x40) forms (#299). Exposes the Global Administrator, bandwidth in bytes per second, and transitivity, and preserves the wire type on encode.
  • Updated bgpkit-broker dependency from 0.11 to 0.12 (#318).
  • Fixed standalone cli feature: cargo build --no-default-features --features cli now compiles; the CLI binary was previously broken in that combination because BgpkitParser::new/new_cached require oneio (broken since at least v0.18.0, and not covered by any CI feature combination). TLS backend selection is unchanged: standalone cli enables oneio's plain-HTTP reader, and cli,rustls / cli,native-tls select a backend additively as before.

Test data

  • Historical RIPE regression fixtures (#316): Added original RRC00 update and bview gzip files from 1999 and January 2000 as repository-only, offline integration fixtures.
  • PacketLife ORF capture fixture (#326): Added the PacketLife.net "bgp orf prefix advertisement" capture (via https://github.com/epiecs/packetlife-backup) as a repository-only fixture exercising ROUTE-REFRESH with RFC 5291 ORF payload bytes extracted from the pcapng TCP stream.
  • Opt-in MRT framing recovery (#325): Added into_recovering_record_iter, into_recovering_elem_iter, and CLI --recover support for salvaging records after damaged MRT framing. Recovery validates a three-record chain, uses exact embedded BGP headers as BGP4MP anchors, and reports every skipped decompressed byte range as a typed gap event. A record of any MRT type whose framing is intact but whose body fails to parse is skipped exactly (AlignedRecordChain evidence) when intact records follow its declared boundary, and damage extending to the end of the stream — e.g. a truncated final record — is reported as a terminal gap (EndOfStream evidence) instead of an error. Text-dump parsers, which have no MRT record representation, yield an explicit Unsupported error.

Examples

  • Diagnostic MRT iterator example (#324): Added examples/diagnostic_iterator.rs to classify clean records, RFC 7606 validation findings, and fatal parse errors while exporting raw MRT bytes for each finding.
  • Resumable HTTP reader example (#323): Added examples/resumable_http.rs to parse a remote MRT file with new_resumable_http and report unrecoverable read failures.

Fixed

  • Fallible MRT error bytes (#315): Header, oversized-record, partial-body, and route-iterator failures now retain all consumed record bytes. Default/raw iteration only writes mrt_core_dump when explicitly enabled, and raw error skipping no longer recurses.
  • Silent truncation on encode eliminated (#313): AS_PATH segments with >255 ASes, attribute values exceeding their (extended or non-extended) length field, TLV values in Tunnel Encapsulation / BGP-LS / SFP / BFD Discriminator / Prefix-SID / BIER attributes, RIB entry counts, peer counts, view names, and BGP message total lengths now return EncodingError instead of writing corrupt length fields.
  • FlowSpec NLRI length bound: the wire length field is 12-bit (RFC 8955); NLRI data of 4096..=65535 bytes previously passed an unchecked u16 cast and encoded a corrupt length byte. It is now rejected with ValueTooLarge.
  • MP_REACH/MP_UNREACH encoding errors are no longer swallowed: labeled-NLRI failures previously logged a warning and emitted a zero-length (RFC-invalid) attribute value; they now propagate as EncodingError.
  • FlowSpec NLRI entries are now encoded: Nlri::flowspec_nlris was previously silently dropped when encoding MP_REACH/MP_UNREACH attributes.
  • Peer index aliasing: PeerIndexTable::add_peer previously wrapped the peer id at 65,536 peers, silently attributing routes to the wrong peer; it now returns an error and leaves the table unmodified.
  • BGP OPEN parameter type 255 rejected: RFC 9072 reserves type 255 as the extended-length marker; encoding it as a real parameter produced output that round-tripped to a structurally different message.
  • BGP OPEN optional-parameter encoding: Encode the Optional Parameters Length as the total byte length required by RFC 4271 instead of the number of parameters. OPEN messages now also use the extended length format from RFC 9072 when requested or required.
  • Historical Quagga state changes: Parse BGP4MP state-change records containing Quagga's Clearing (7) and Deleted (8) FSM states instead of logging an error and dropping the MRT record.
  • CLI broken-pipe exit status (#325): the CLI now exits 0 when its stdout consumer closes the pipe early (e.g. bgpkit-parser updates.gz | head), matching Unix convention; previous releases exited 1. Other write errors still exit 1.

Contributors

  • @ties — fallible encoding and MRT error-handling overhaul (#312, #315), early RIPE RIS MRT support (#316), historical Quagga BGP states (#317), recovering parser (#325), ROUTE-REFRESH parsing (#326)
  • @downwithbgp — RFC 10005 Link Bandwidth Extended Community support (#319), RFC 5543 Traffic Engineering attribute support (#322)
  • @digizeph — unified MRT/text-dump parser API (#321), resumable HTTP parser (#323), diagnostic MRT iterator (#324)