3 releases (breaking)

0.3.0 Jan 31, 2024
0.2.0 Oct 9, 2023
0.1.0 Mar 5, 2023

#4 in #bgp

Download history 21/week @ 2024-01-29 106/week @ 2024-02-12 39/week @ 2024-02-19 41/week @ 2024-02-26 24/week @ 2024-03-11 2/week @ 2024-03-18 68/week @ 2024-04-01

94 downloads per month
Used in 4 crates (3 directly)

Apache-2.0

1MB
19K SLoC

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

  1. Extensive support for the various BGP related RFCs. See Supported BGP-4 Protocol features.
  2. 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.
  3. 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.
  4. 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
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
Route Reflection 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
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 Unicast
RFC 4684 1 = IPv4 132 = Route Target constrains
2 = IPv6 1 = Unicast
2 = IPv6 2 = Multicast
RFC 8277 2 = IPv6 4 = MPLS Labeled Unicast NLRI with MPLS Labels
RFC 4659 2 = IPv4 128 = MPLS Labeled Unicast
RFC 7432 and RFC9136 25 = L2 VPN 70 = BGP EVPNs Route types from 1 till 5 are supported

Supported Notification Sub-Codes

Capability RFCs Notes
Reserved
Maximum Number of Prefixes Reached RFC 4486
Administrative Shutdown RFC 4486
Peer De-configured RFC 4486
Administrative Reset RFC 4486
Connection Rejected RFC 4486
Other Configuration Change RFC 4486
Connection Collision Resolution RFC 4486
Out of Resources RFC 4486
Hard Reset RFC 8538
BFD Down RFC 9384

Development documentation

  • Running Packet Serde benchmarks* cargo bench --features bench

  • Using this library to fuzz other code accepting BgpMessage

#![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
});

Dependencies

~0.6–13MB
~127K SLoC