NetGauze BGP Pkt
BGP-4 Protocol representation and wire format serialization/deserialization (serde)
Overview
NetGauze BGP Pkt is library to represent BGP-4 Packets. It aims to achieve 4 goals
- Extensive support for the various BGP related RFCs.
See Supported BGP-4 Protocol features.
- Rust native representation of BGP protocol that makes it hard to construct an incorrect BGP packet. We achieve that
by heavily relying on the rich type system provided by Rust.
- Native BGP wire-protocol Serializing/deserialization (serde) is optional. In addition to support the
well-known serde library This to make this library useful for building wider range
of applications.
- Extensive testing. This includes testing using unit tests extracted from real packets traces and fuzzing.
Example
To run example: cargo run --example bgp
use std::io::Cursor;
use std::net::Ipv4Addr;
use netgauze_bgp_pkt::capabilities::*;
use netgauze_bgp_pkt::open::*;
use netgauze_bgp_pkt::*;
use netgauze_iana::address_family::*;
use netgauze_parse_utils::{ReadablePDUWithOneInput, Span, WritablePDU};
pub fn main() {
// Construct a new BGP message
let msg = BgpMessage::Open(BgpOpenMessage::new(
100,
180,
Ipv4Addr::new(5, 5, 5, 5),
vec![
BgpOpenMessageParameter::Capabilities(vec![BgpCapability::MultiProtocolExtensions(
MultiProtocolExtensionsCapability::new(AddressType::Ipv4Unicast),
)]),
BgpOpenMessageParameter::Capabilities(vec![BgpCapability::MultiProtocolExtensions(
MultiProtocolExtensionsCapability::new(AddressType::Ipv4MplsLabeledVpn),
)]),
BgpOpenMessageParameter::Capabilities(vec![BgpCapability::CiscoRouteRefresh]),
BgpOpenMessageParameter::Capabilities(vec![BgpCapability::RouteRefresh]),
BgpOpenMessageParameter::Capabilities(vec![BgpCapability::FourOctetAs(
FourOctetAsCapability::new(100),
)]),
BgpOpenMessageParameter::Capabilities(vec![BgpCapability::ExtendedNextHopEncoding(
ExtendedNextHopEncodingCapability::new(vec![
ExtendedNextHopEncoding::new(AddressType::Ipv4Unicast, AddressFamily::IPv6),
ExtendedNextHopEncoding::new(AddressType::Ipv4Multicast, AddressFamily::IPv6),
ExtendedNextHopEncoding::new(
AddressType::Ipv4MplsLabeledVpn,
AddressFamily::IPv6,
),
]),
)]),
],
));
println!("JSON representation of BGP packet: {}", serde_json::to_string(&msg).unwrap());
// Serialize the message into it's BGP binary format
let mut buf: Vec<u8> = vec![];
let mut cursor = Cursor::new(&mut buf);
msg.write(&mut cursor).unwrap();
assert_eq!(
buf,
vec![
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 83,
1, 4, 0, 100, 0, 180, 5, 5, 5, 5, 54, 2, 6, 1, 4, 0, 1, 0, 1, 2, 6, 1, 4, 0, 1, 0, 128,
2, 2, 128, 0, 2, 2, 2, 0, 2, 6, 65, 4, 0, 0, 0, 100, 2, 20, 5, 18, 0, 1, 0, 1, 0, 2, 0,
1, 0, 2, 0, 2, 0, 1, 0, 128, 0, 2
]
);
// Deserialize the message from binary format
let (_, msg_back) = BgpMessage::from_wire(Span::new(&buf), true).unwrap();
assert_eq!(msg, msg_back);
}
Supported BGP Protocol features
Supported message types
Message Type |
RFCs |
notes |
Open |
RFC 4271 |
See below for the supported capabilities |
Update |
RFC 4271 |
See below for the supported path attributes |
Notification |
RFC 4271 |
See below for the supported notif sub-codes |
KeepAlive |
RFC 4271 |
|
RouteRefresh |
RFC 2918 and RFC 7313 |
See below for the supported Route refresh ops |
Supported Capabilities In BGP Open message
Capability |
RFCs |
Notes |
MultiProtocolExtensions (MP-BGP) |
RFC 4760 |
See MP-BGP supported address families below |
RouteRefresh |
RFC 2918 |
|
EnhancedRouteRefresh |
RFC 7313 |
|
Add Path |
RFC 7911 |
|
Extended Message |
RFC 8654 |
|
Four Octet AS Number |
RFC 6793 |
|
Extended Next Hop Encoding |
RFC 8950 |
|
Multiple Labels |
RFC 8277 |
|
BGP Role |
RFC 9234 |
|
Experimental |
RFC 8810 |
Capabilities with codes 239-254 are marked as experimental, we read their values as Vec |
Unrecognized |
RFC 5492 |
We carry the capability code and the u8 vector for it's value |
Supported Path Attributes In BGP Update message
Path Attribute |
RFCs |
Well-known |
Optional |
transitive |
Notes |
Origin |
RFC 4271 |
Yes |
No |
Yes |
|
AS_PATH |
RFC 4271 and RFC 6793 |
Yes |
No |
Yes |
|
NEXT_HOP |
RFC 4271 |
Yes |
No |
Yes |
|
MultiExitDiscriminator (MED) |
RFC 4271 |
Yes |
Yes |
No |
|
Local Preference (LocalPref) |
RFC 4271 |
Yes |
|
Yes |
|
Atomic Aggregate |
RFC 4271 |
Yes |
Yes |
Yes |
|
Aggregator |
RFC 4271 |
Yes |
Yes |
Yes |
|
Communities |
RFC 1997 |
No |
Yes |
Yes |
|
Extended Communities |
RFC 4360 |
No |
Yes |
Yes |
|
Extended Communities IPv6 |
RFC 5701 |
No |
Yes |
Yes |
|
Large Communities |
RFC 8092 |
No |
Yes |
Yes |
|
Originator |
RFC 4456 |
No |
Yes |
No |
|
Cluster List |
RFC 4456 |
No |
Yes |
No |
|
Four Octet AS_PATH |
RFC 6793 |
No |
Yes |
Yes |
|
MP_REACH_NLRI |
RFC 4760 |
No |
Yes |
No |
|
MP_UNREACH_NLRI |
RFC 4760 |
No |
Yes |
No |
|
BGP-LS (link-state) |
RFC 7752 |
No |
Yes |
No |
|
Only To Customer (OTC) |
RFC 9234 |
No |
Yes |
Yes |
|
Accumulated IGP Metric (AIGP) |
RFC 7311 |
No |
Yes |
No |
|
BGP Prefix-SID |
RFC 8669 and RFC 9252 |
No |
Yes |
Yes |
|
UnknownAttribute |
|
N/A |
N/A |
N/A |
Catch all attribute that will read and keep the value as a Vec |
MP-BGP supported address families
RFC |
Address Family (AFI) |
Subsequence Address Family (SAFI) |
Notes |
|
1 = IPv4 |
1 = Unicast |
|
|
1 = IPv4 |
2 = Multicast |
|
RFC 8277 |
1 = IPv4 |
4 = MPLS Labeled Unicast |
NLRI with MPLS Labels |
RFC 4364 |
1 = IPv4 |
128 = MPLS-labeled VPN address |
|
RFC 4684 |
1 = IPv4 |
132 = Route Target constrains |
|
|
2 = IPv6 |
1 = Unicast |
|
|
2 = IPv6 |
2 = Multicast |
|
RFC 8277 |
2 = IPv6 |
4 = MPLS Labeled Unicast |
|
RFC 4659 |
2 = IPv4 |
128 = MPLS-labeled VPN address |
|
RFC 7752 and RFC RFC9086 |
16388 = BGP LS |
71 = BGP LS |
|
RFC 7752 and RFC RFC9086 |
16388 = BGP LS |
72 = BGP LS VPN |
|
RFC 7432 and RFC 9552 |
25 = L2 VPN |
70 = BGP EVPNs |
Route types from 1 till 5 are supported |
Supported BGP Error Notification Codes
Supported Message Header Error Notification Sub-Codes
Supported Open Message Notification Sub-Codes
Supported Update Message Notification Sub-Codes
Supported BGP Finite State Machine Notification Sub-Codes
Capability |
RFCs |
Notes |
Unspecified Error |
RFC 6608 |
|
Receive Unexpected Message in OpenSent State |
RFC 6608 |
|
Receive Unexpected Message in OpenConfirm State |
RFC 6608 |
|
Receive Unexpected Message in Established State |
RFC 6608 |
|
Supported Cease Notification Sub-Codes
Development documentation
#![no_main]
use libfuzzer_sys::fuzz_target;
use netgauze_bgp_pkt::BgpMessage;
fuzz_target!(|data: BgpMessage| {
// Some fuzzing target that accepts BgpMessage as input and need to be fuzzed
});