Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.

## Unreleased

### Improvements

* **Enhanced warning messages**: Added context to 14 warning messages across BGP, BMP, and MRT parsers to help identify which parsing stage encountered an issue. Also fixed typo in NLRI warning ("NRLI" → "NLRI").

### Bug fixes

* **WASM `only_to_customer` serialization**: Added test to verify that messages without the OTC (Only To Customer) attribute correctly serialize `only_to_customer` as `null` (not `0`) in JSON output. This ensures JavaScript consumers can properly distinguish between "no OTC attribute" (`null`) and "OTC with AS 0" (`0`).
Expand Down
8 changes: 7 additions & 1 deletion codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,10 @@ coverage:
target: auto
# adjust accordingly based on how flaky your tests are
# this allows a 10% drop from the previous base commit coverage
threshold: 10%
threshold: 10%
# make coverage check informational (non-blocking)
informational: true
patch:
default:
# make patch coverage check informational (non-blocking)
informational: true
2 changes: 1 addition & 1 deletion src/parser/bgp/attributes/attr_07_18_aggregator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub fn parse_aggregator(
};
if asn_len_found != *asn_len {
warn!(
"Aggregator attribute with ASN length set to {:?} but found {:?}",
"Aggregator attribute with ASN length set to {:?} but found {:?} (parsing Aggregator attribute)",
asn_len, asn_len_found
);
}
Expand Down
8 changes: 4 additions & 4 deletions src/parser/bgp/attributes/attr_14_15_nlri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ pub fn parse_nlri(
if reachable {
// skip reserved byte for reachable NRLI
if input.read_u8()? != 0 {
warn!("NRLI reserved byte not 0");
warn!("NLRI reserved byte not 0 (parsing NLRI Link-State)");
}
}
let ls_nlri = parse_link_state_nlri(input, afi, safi, next_hop, reachable)?;
Expand All @@ -85,7 +85,7 @@ pub fn parse_nlri(
if reachable {
// skip reserved byte for reachable NRLI
if input.read_u8()? != 0 {
warn!("NRLI reserved byte not 0");
warn!("NLRI reserved byte not 0 (parsing NLRI prefixes)");
}
}
parse_nlri_list(input, additional_paths, &afi)?
Expand All @@ -97,7 +97,7 @@ pub fn parse_nlri(
if reachable {
// skip reserved byte for reachable NRLI
if input.read_u8()? != 0 {
warn!("NRLI reserved byte not 0");
warn!("NLRI reserved byte not 0 (parsing NLRI prefixes)");
}
}
parse_nlri_list(input, additional_paths, &afi)?
Expand Down Expand Up @@ -131,7 +131,7 @@ pub fn encode_nlri(nlri: &Nlri, reachable: bool) -> Bytes {

if let Some(next_hop) = &nlri.next_hop {
if !reachable {
warn!("NLRI next hop should not be set for unreachable NLRI");
warn!("NLRI next hop should not be set for unreachable NLRI (encoding NLRI)");
}
// encode next hop
let next_hop_bytes = match next_hop {
Expand Down
4 changes: 2 additions & 2 deletions src/parser/bgp/attributes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,8 @@ pub fn parse_attributes(

if data.remaining() < attr_length {
warn!(
"not enough bytes: input bytes left - {}, want to read - {}; skipping",
bytes_left, attr_length
"{:?} attribute encodes a length ({}) that is longer than the remaining attribute data ({}). Skipping remaining attribute data for BGP message",
attr_type, attr_length, bytes_left
);
// break and return already parsed attributes
break;
Expand Down
12 changes: 6 additions & 6 deletions src/parser/bgp/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ pub fn parse_bgp_message(

if data.remaining() != bgp_msg_length {
warn!(
"BGP message length {} does not match the actual length {}",
"BGP message length {} does not match the actual length {} (parsing BGP message)",
bgp_msg_length,
data.remaining()
);
Expand Down Expand Up @@ -256,10 +256,10 @@ pub fn parse_bgp_open_message(input: &mut Bytes) -> Result<BgpOpenMessage, Parse
// let pos_end = input.position() + opt_params_len as u64;
if input.remaining() != opt_params_len as usize {
warn!(
"BGP open message length {} does not match the actual length {}",
opt_params_len,
input.remaining()
);
"BGP open message length {} does not match the actual length {} (parsing BGP OPEN message)",
opt_params_len,
input.remaining()
);
}

param_type = input.read_u8()?;
Expand Down Expand Up @@ -422,7 +422,7 @@ fn read_nlri(
}
if length == 1 {
// 1 byte does not make sense
warn!("seeing strange one-byte NLRI field");
warn!("seeing strange one-byte NLRI field (parsing NLRI in BGP UPDATE message)");
input.advance(1); // skip the byte
return Ok(vec![]);
}
Expand Down
4 changes: 2 additions & 2 deletions src/parser/bmp/messages/headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ pub fn parse_per_peer_header(data: &mut Bytes) -> Result<BmpPerPeerHeader, Parse

// Validate that peer address is zero-filled as required by RFC 9069
if peer_addr_bytes != [0u8; 16] {
warn!("RFC 9069 violation: Local RIB peer address MUST be zero-filled, but found non-zero bytes");
warn!("RFC 9069 violation: Local RIB peer address MUST be zero-filled, but found non-zero bytes (parsing BMP Per-Peer Header)");
}

// Local RIB peer address is always zero-filled per RFC 9069
Expand All @@ -385,7 +385,7 @@ pub fn parse_per_peer_header(data: &mut Bytes) -> Result<BmpPerPeerHeader, Parse

// RFC 9069: Validate that peer BGP ID is non-zero for meaningful instances
if peer_bgp_id == Ipv4Addr::from(0) && peer_distinguisher != 0 {
warn!("RFC 9069: Local RIB peer BGP ID should be set to VRF instance router-id for non-global instances");
warn!("RFC 9069: Local RIB peer BGP ID should be set to VRF instance router-id for non-global instances (parsing BMP Per-Peer Header)");
}

let t_sec = data.read_u32()?;
Expand Down
6 changes: 3 additions & 3 deletions src/parser/bmp/messages/peer_up_notification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ pub fn parse_peer_up_notification(
}
});
if !has_multiprotocol_capability {
warn!("RFC 9069: Local RIB peer up notification should include multiprotocol capabilities in fabricated OPEN messages");
warn!("RFC 9069: Local RIB peer up notification should include multiprotocol capabilities in fabricated OPEN messages (parsing Peer Up Notification)");
}
}
}
Expand All @@ -115,7 +115,7 @@ pub fn parse_peer_up_notification(
// RFC 9069: VrTableName MUST be UTF-8 string of 1-255 bytes
if info_value.is_empty() || info_value.len() > 255 {
warn!(
"RFC 9069: VrTableName TLV length must be 1-255 bytes, found {} bytes",
"RFC 9069: VrTableName TLV length must be 1-255 bytes, found {} bytes (parsing Peer Up Notification)",
info_value.len()
);
}
Expand All @@ -132,7 +132,7 @@ pub fn parse_peer_up_notification(
// RFC 9069: Local RIB instances SHOULD include VrTableName TLV
if let Some(BmpPeerType::LocalRib) = peer_type {
if !has_vr_table_name {
warn!("RFC 9069: Local RIB peer up notification should include VrTableName TLV");
warn!("RFC 9069: Local RIB peer up notification should include VrTableName TLV (parsing Peer Up Notification)");
}
}
Ok(PeerUpNotification {
Expand Down
2 changes: 1 addition & 1 deletion src/parser/bmp/messages/route_monitoring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub fn parse_route_monitoring(
// RFC 9069: Local RIB MUST use 4-byte ASN encoding
if let Some(BmpPeerType::LocalRib) = peer_type {
if *asn_len != AsnLength::Bits32 {
warn!("RFC 9069 violation: Local RIB route monitoring MUST use 4-byte ASN encoding");
warn!("RFC 9069 violation: Local RIB route monitoring MUST use 4-byte ASN encoding (parsing Route Monitoring)");
}
}

Expand Down
5 changes: 4 additions & 1 deletion src/parser/mrt/messages/table_dump_v2/rib_afi_entries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ pub fn parse_rib_afi_entries(
let entry = match parse_rib_entry(data, is_add_path, &afi, &safi, prefix) {
Ok(entry) => entry,
Err(e) => {
warn!("early break due to error {}", e);
warn!(
"early break due to error {} while parsing RIB AFI entries",
e
);
break;
}
};
Expand Down
2 changes: 1 addition & 1 deletion src/parser/mrt/mrt_record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ impl MrtRecord {
let mut new_header = self.common_header;
if message_bytes.len() != new_header.length as usize {
warn!(
"message length {} does not match the length in the header {}",
"message length {} does not match the length in the header {} (encoding MRT record)",
message_bytes.len(),
new_header.length
);
Expand Down
Loading