RustyBGP Documentation

repository·master·Indexed 20 days ago

https://github.com/osrg/rustybgp

A high-performance BGP implementation written in Rust and optimized for multicore systems. Designed as a drop-in replacement for GoBGP, it supports the same gRPC API and configuration formats. It features direct Linux kernel integration for FIB management, supporting IPv4, IPv6, VRF, ECMP, and Nexthop Tracking (NHT). The implementation includes support for BFD liveness detection, TTL Security, BMP servers, RPKI server settings, and Zebra integration.

Tokens
40.9K
Snippets
121
Records
195
Agent score
69%

What's inside RustyBGP

  1. Understand RustyBGP kernel integration and limitations

    master

    RustyBGP is a Linux-only implementation that integrates directly with the Linux kernel for FIB (Forwarding Information Base) management, rather than using Zebra/FRR.

    Kernel Integration Features

    • Route injection and withdrawal: Supports IPv4, IPv6, and VRF.
    • ECMP: Supports multiple nexthops via RTA_MULTIPATH.
    • Nexthop tracking (NHT): Monitors nexthop reachability and automatically withdraws affected routes.
    • Connected route redistribution: Detects interface address changes and injects connected routes into BGP.

    Unsupported GoBGP Features

    If you are migrating from GoBGP, note that the following are not supported in RustyBGP:

    • VPLS
    • MPLS VPN Multicast
    • EVPN control plane (Note: EVPN Types 1–5 NLRI relay is supported, but RT-based MAC-VRF import/export is not).
  2. Install and run RustyBGP

    master

    To use RustyBGP, download the latest nightly binary for your architecture (x86_64 or aarch64), extract it, and run the rustybgpd daemon. You can use your existing GoBGP configuration files with the -f flag.

    RustyBGP is designed as a drop-in replacement for GoBGP, supporting the same gRPC API and configuration format, allowing you to use existing GoBGP tooling and CLI commands to manage the daemon.

    # Download and extract the x86_64 binary
    curl -LO https://github.com/osrg/rustybgp/releases/download/nightly/rustybgp-nightly-linux-x86_64.tar.gz
    tar xf rustybgp-nightly-linux-x86_64.tar.gz
    
    # Start the daemon using a GoBGP configuration file
    sudo ./rustybgpd -f gobgpd.conf
  3. Setup the pyang plugin for RustyBGP

    master

    This plugin allows you to generate config/gen.rs from OpenConfig YANG files using pyang.

    Prerequisites

    • Python 3
    • Git

    Environment Setup

    1. Define your source and project directories:

      export SOURCE=$HOME/git
      export RUSTYBGP=$SOURCE/rustybgp
    2. Clone the required repositories:

      cd $SOURCE
      git clone https://github.com/osrg/public
      git clone https://github.com/osrg/yang
      git clone https://github.com/osrg/pyang
    3. Initialize the pyang environment:

      cd $SOURCE/pyang
      source ./env.sh
    $ SOURCE=$HOME/git
    $ RUSTYBGP=$SOURCE/rustybgp
    
    $ cd $SOURCE
    $ git clone https://github.com/osrg/public
    $ git clone https://github.com/osrg/yang
    $ git clone https://github.com/osrg/pyang
    
    $ cd $SOURCE/pyang
    $ source ./env.sh
  4. Generate config/gen.rs from YANG files

    master

    Use the pyang binary with the RustyBGP plugin directory to generate Rust code from OpenConfig YANG models.

    Command Structure:

    • Set PYTHONPATH=. to ensure local modules are discoverable.
    • Use --plugindir to point to $RUSTYBGP/tools/pyang_plugins.
    • Use multiple -p flags to include the necessary YANG search paths (standard IETF, public models, BGP models, and policy models).
    • Use -f rust to specify the Rust output format.
    • Provide the target YANG files as arguments.
    • Redirect the output to $RUSTYBGP/config/src/generate.rs.
    $ PYTHONPATH=. ./bin/pyang \
    --plugindir $RUSTYBGP/tools/pyang_plugins \
    -p $SOURCE/yang/standard/ietf/RFC \
    -p $SOURCE/public/release/models \
    -p $SOURCE/public/release/models/bgp \
    -p $SOURCE/public/release/models/policy \
    -f rust \
    $SOURCE/public/release/models/policy/openconfig-routing-policy.yang \
    $SOURCE/public/release/models/bgp/openconfig-bgp.yang \
    $RUSTYBGP/tools/pyang_plugins/gobgp.yang > \$RUSTYBGP/config/src/generate.rs
  5. Use BMP Message Types

    master

    The Message enum represents the different types of BMP messages that can be encoded. The primary variants are:

    • RouteMonitoring: Contains a PerPeerHeader, a BGP update message, and an addpath boolean.
    • StatsReports: BMP statistics reports.
    • PeerDown: Contains a PerPeerHeader and a PeerDownReason.
    • PeerUp: Contains a PerPeerHeader, local/remote IP addresses and ports, and both local and remote OPEN messages.
    • Initiation: A list of Type-Length-Value (TLV) pairs used for BMP session initiation.
    • Termination: Signals the end of a BMP session.
    • RouteMirroring: Used for route mirroring functionality.
    // Example: Creating a Route Monitoring message
    let msg = Message::RouteMonitoring {
        header: my_per_peer_header,
        update: my_bgp_update_message,
        addpath: false,
    };
  6. Perform EVPN Type-2 best-path selection

    master

    For L2VPN_EVPN family, the routing table implements specialized best-path selection for Type-2 NLRI (MAC/IP Advertisement) based on MAC Mobility sequences.

    Selection logic:

    1. Higher Sequence Wins: A path with a higher MAC Mobility sequence number (found in the Extended Community) is preferred over a path with a lower sequence.
    2. Mobility vs. No Mobility: A path carrying a MAC Mobility sequence is preferred over a path that does not carry the MAC Mobility attribute.
    3. Tie-breaking: If sequence numbers are equal (or absent), the selection falls back to standard BGP best-path selection (e.g., lowest router-id).
  7. Filter RIB entries by prefix and lookup type

    master

    Use PrefixFilter to match prefixes in the RIB using different semantics via LookupType:

    • Exact: Only exact prefix matches.
    • Longer: Matches RIB entries that are equally or more specific than the query prefix (the RIB prefix is contained within the query prefix).
    • Shorter: Matches RIB entries that are equally or less specific than the query prefix (the RIB prefix contains the query prefix).
  8. Configure Graceful Restart (GR) and Long-Lived Graceful Restart (LLGR)

    master

    RustyBGP supports both Graceful Restart (RFC 4724) and Long-Lived Graceful Restart (RFC 9494) for peer stability during restarts.

    Graceful Restart (GR)

    To enable GR, configure the following:

    • restart_time: The time (in seconds, max 4095) advertised in the OPEN message.
    • notification_enabled: If true, GR applies to NOTIFICATION and Hold Timer expiry (RFC 8538).
    • families: A list of BGP families to include in the GR capability.

    Long-Lived Graceful Restart (LLGR)

    To enable LLGR, configure:

    • families: A list of tuples containing the Family and a stale_time (in seconds, max ~16 million) for each family.
  9. Manage RPKI client state and metrics

    master

    The RpkiState struct tracks the operational status and metrics of RPKI sessions. It uses atomic types to allow thread-safe updates of session information and message counts.

    Key metrics tracked include:

    • uptime / downtime: Unix timestamps of session status changes.
    • up: Boolean indicating if the session is currently active.
    • serial: The current RPKI serial number.
    • received_ipv4 / received_ipv6: Counts of received IP prefixes by version.
    • Message counters: serial_notify, serial_query, reset_query, cache_response, end_of_data, cache_reset, error.
  10. Define SR Segment Lists and Segments

    master

    An SrPolicySegmentList contains a sequence of SrSegment objects.

    Segments can be:

    • SrSegment::TypeA: An SR-MPLS label (Sub-sub-TLV 1).
    • SrSegment::TypeB: An SRv6 SID (Sub-sub-TLV 13). If the 0x40 flag is set in the segment flags, an endpoint_behavior is also included.

    Segment lists can optionally include a weight via SrWeight (Sub-sub-TLV 9).

    use rustybgp_packet::tunnel_encap::{SrPolicySegmentList, SrSegment, SrWeight};
    use std::net::Ipv6Addr;
    
    let segment_list = SrPolicySegmentList {
        weight: Some(SrWeight { flags: 0, weight: 10 }),
        segments: vec![
            SrSegment::TypeA { flags: 0, label: 16001 },
            SrSegment::TypeB {
                flags: 0x40, // Includes endpoint behavior
                sid: Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1),
                endpoint_behavior: Some(behavior),
            },
        ],
    };
  11. Define routing policies using RoutingPolicy

    master

    Routing policies in RustyBGP are structured using a RoutingPolicy object, which contains two main components: defined-sets for reusable attribute groups and policy-definitions for the actual logic.

    Policies are composed of policy-definitions, which contain a sequence of statements. Each statement consists of conditions (to match specific attributes) and actions (to determine the route disposition).

    {
      "defined-sets": {
        "prefix-sets": [
          {
            "prefix-set-name": "MY_PREFIXES",
            "prefix-list": [
              { "ip-prefix": "10.0.0.0/8", "masklength-range": "8..16" }
            ]
          }
        ]
      },
      "policy-definitions": [
        {
          "name": "IMPORT_POLICY",
          "statements": [
            {
              "name": "ALLOW_INTERNAL",
              "conditions": { "match-prefix-set": { "name": "MY_PREFIXES" } },
              "actions": { "accept": true }
            }
          ]
        }
      ]
    }
  12. Work with EVPN NLRI variants

    master

    The EvpnNlri enum represents the different types of EVPN Network Layer Reachability Information (NLRI) defined in RFC 7432 and RFC 9136. It supports five route types:

    1. Type-1: Ethernet Auto-Discovery (EthernetAutoDiscovery): Used for mass withdrawal and aliasing.
    2. Type-2: MAC/IP Advertisement (MacIpAdvertisement): Advertises MAC and optional IP addresses.
    3. Type-3: Inclusive Multicast Ethernet Tag (InclusiveMulticastEthernetTag): Used for BUM traffic replication.
    4. Type-4: Ethernet Segment (EthernetSegment): Used for Designated Forwarder election.
    5. Type-5: IP Prefix (EthernetIpPrefix): Advertises IP prefixes (RFC 9136).

    You can decode an EVPN route from a reader using EvpnNlri::decode(r) and encode it using EvpnNlri::encode(&mut dst).

    use crate::evpn::EvpnNlri;
    use std::io::Cursor;
    
    // Example: Decoding a raw byte slice into an EVPN NLRI
    let raw_data: &[u8] = &[0x03, 0x11, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x20, 0xc0, 0x02, 0x01, 0x02];
    let mut cursor = Cursor::new(raw_data);
    let nlri = EvpnNlri::decode(&mut cursor).expect("Failed to decode");