ExaBGP Documentation

repository·main·Indexed 25 days ago

https://github.com/exa-networks/exabgp

A programmable BGP implementation that allows users to control BGP networks via Python scripts or external programs through a JSON API. Designed for DDoS mitigation, traffic engineering, and anycast management, ExaBGP focuses on protocol implementation without manipulating the local FIB. Documentation covers installation via pip, Docker, and Debian packages, as well as RIB benchmarking, API functional testing, and a BGP Route Reflector lab for AS-PATH based filtering.

Tokens
69.3K
Snippets
165
Records
338
Agent score
81%

What's inside ExaBGP

  1. What is ExaBGP and its core use cases

    main

    ExaBGP is a BGP routing protocol implementation designed for the control plane. It focuses on BGP protocol control and does NOT perform FIB (Forwarding Information Base) manipulation.

    Common use cases include:

    • Cross-datacenter failover solutions
    • Network attack mitigation (e.g., deploying blackhole or Flowspec rules)
    • Network information gathering (using BGP-LS and Add-Path)
    • Route manipulation and policy control
  2. Security hardening: Input validation and error sanitization

    main

    ExaBGP is undergoing a security hardening process focused on two main areas: hardening the configuration/API layers against malformed input and preventing information leakage through error messages.

    Input Validation Goals

    • Configuration Parser Validation: Reject invalid configurations early in src/exabgp/configuration/ using type, range, format, and semantic validation.
    • API Command Parsing: Validate commands in src/exabgp/reactor/api/command/.

    Error Sanitization Goals

    • Prevent Information Leakage: Ensure external-facing APIs (JSON/Text) and CLI outputs do not expose internal file paths, stack traces, or system information.
    • Sanitization Rules:
      • No file paths in API responses.
      • No stack traces in API responses (log these internally instead).
      • Use generic error messages for invalid input (e.g., "invalid command" instead of detailed parsing errors).
      • Avoid version leakage in responses.
  3. ExaBGP Overview and Capabilities

    main

    ExaBGP is a Software Defined Networking (SDN) tool that allows engineers to control networks from commodity servers using the BGP protocol.

    Key Capabilities:

    • Route Announcement: Announce IPv4, IPv6, VPN, or FlowSpec routes (useful for DDoS protection) via configuration files.
    • Message Transformation: Transform BGP messages into plain text or JSON formats, making it easy for scripts to manipulate data and report peer announcements.
    • Protocol Support: Supports IPv4, IPv6, MPLS, VPLS, BGP-LS, FlowSpec, and more.
  4. Plan for Neighbor Naming implementation

    main

    This document outlines the technical plan for implementing neighbor naming and aliasing in ExaBGP. The goal is to allow users to assign human-readable names (aliases) to BGP neighbors, which can then be used in configuration, API commands, and registry lookups instead of relying solely on IP addresses or connection identifiers.

    Implementation Summary

    ComponentChange
    src/exabgp/bgp/neighbor/neighbor.pyAdd alias field and include it in JSON output
    src/exabgp/bgp/neighbor/settings.pyAdd alias to neighbor settings
    src/exabgp/configuration/neighbor/__init__.pyAdd name to the configuration schema
    src/exabgp/configuration/neighbor/parser.pyAdd validation for neighbor names
    src/exabgp/reactor/loop.pyAdd a name registry to track neighbors by name
    src/exabgp/configuration/configuration.pyImplement validation to ensure name uniqueness
    src/exabgp/reactor/api/command/limit.pySupport name-based selectors for limiting commands
    src/exabgp/reactor/api/command/peer.pyAdd commands for managing neighbor names
    src/exabgp/reactor/api/command/registry.pyRegister new name-related commands
    src/exabgp/reactor/api/command/neighbor.pyInclude names in the show command output
  5. What is ExaBGP and how does it differ from traditional BGP daemons?

    main

    ExaBGP is a BGP implementation designed for network engineers and developers to interact with BGP networks via a simple API using Python scripts or external programs.

    Key Difference: Unlike traditional BGP daemons (such as BIRD or FRRouting), ExaBGP does not manipulate the Forwarding Information Base (FIB). It focuses purely on BGP protocol implementation and provides an API for external processes to control routing.

  6. Implement flow control with early returns and guard clauses

    main

    To reduce nesting and improve readability, follow these patterns:

    • Early Returns: Return or raise exceptions as soon as a condition is met to avoid deep if/else blocks.
    • Guard Clauses: Use them for input validation.
    • Loop Flow Control: Use continue instead of deep nesting inside loops.
    • De-indent Final Actions: Once a branch is handled (via return or continue), the main logic should be at the base indentation level of the function/loop.
    # Early return pattern
    def process_message(self, data):
        if not data:
            return None
        if len(data) < HEADER_LEN:
            raise InvalidMessage('insufficient data')
        return self._parse(data)
    
    # Loop pattern
    for item in items:
        if skip_condition(item):
            continue
        # Main logic is de-indented
        process_item(item)
  7. Use Action Enums for Configuration Schema

    main

    ExaBGP has transitioned from string-based action dispatch to an explicit enum-based system for configuration schemas. While the action field in schemas remains a str for backward compatibility, new code and schema definitions should use the explicit target, operation, and key fields provided by the Leaf and LeafList classes. This enables better IDE autocompletion and more robust validation.

    Key Enums:

    • ActionTarget: Defines what the action is targeting.
    • ActionOperation: Defines the operation to perform (e.g., SET, APPEND).
    • ActionKey: Defines the specific key or dimension of the action.

    Note on Leaf vs LeafList defaults:

    • Leaf defaults to the SET operation.
    • LeafList defaults to the APPEND operation.
  8. Understand the Route Reflector Lab filtering logic

    main

    The lab uses a Filter API Process (scripts/filter_api.py) that communicates with ExaBGP via STDIN/STDOUT using JSON. The filter examines the aspath attribute of incoming routes and applies the following logic:

    AS in PathOrganizationAction
    15169GoogleForward to Client1 (127.0.0.2)
    8075MicrosoftForward to Client2 (127.0.0.3)
    13335CloudflareDropped
    19281Quad9Dropped

    Message Flow Example:

    1. Upstream sends an UPDATE with AS-PATH [15169, 65001].
    2. ExaBGP passes a JSON object to the Filter API via STDIN: {"type": "update", "nlri": "8.8.8.0/24", "attributes": {"aspath": [{"asns": [15169, 65001]}]}}
    3. Filter API responds via STDOUT with an announce command: announce route 8.8.8.0/24 next-hop 10.0.0.1 as-path [ 15169 65001 ]
    4. ExaBGP forwards the UPDATE to the designated client.
  9. Batch multiple BGP announcements using the `group` command

    main

    The group command allows you to batch multiple BGP announcements (or withdrawals) into a single BGP UPDATE message. This is useful for reducing the total number of UPDATE messages sent during bulk operations, ensuring atomic updates, and achieving exact wire-format reproduction for multi-NLRI (Network Layer Reachability Information) updates.

    Semantics

    1. Buffering: Commands within a group are collected and not sent immediately.
    2. Processing: When group end is reached (or a newline in single-line syntax), ExaBGP groups the buffered commands by compatible attributes (family, next-hop, and other attributes).
    3. Transmission:
      • Matching NLRIs are packed into a single UPDATE message.
      • If attributes differ between commands, multiple separate UPDATE messages are produced.
      • Withdrawals can be mixed with announcements within the same group to produce a single UPDATE containing both sections.
    ### Multi-line Example
    ```text
    group start
    announce ipv4 mcast-vpn shared-join rp 10.99.199.1 group 239.251.255.228 rd 65000:99999 source-as 65000 next-hop 10.10.6.3 extended-community [target:192.168.94.12:5]
    announce ipv4 mcast-vpn source-join source 10.99.12.2 group 239.251.255.228 rd 65000:99999 source-as 65000 next-hop 10.10.6.3 extended-community [target:192.168.94.12:5]
    group end
  10. Understand the IP class hierarchy and AFI attribute behavior

    main

    In ExaBGP's IP implementation, the afi (Address Family Identifier) attribute behaves differently depending on the specific IP class being used. This is handled via attribute shadowing to maintain compatibility between class constants and instance variables:

    • IPv4 and IPv6: The afi attribute is a class attribute (e.g., AFI.ipv4 or AFI.ipv6).
    • IPSelf: The afi attribute is an instance variable set during __init__ (can be either ipv4 or ipv6).
    • IP.NoNextHop: The afi attribute is set to AFI.undefined.

    When working with these classes, be aware that IPv4 and IPv6 use the attribute at the class level, while other subclasses may rely on instance-specific values.

  11. How RIB memory optimisation works via interning

    main

    ExaBGP uses an interning strategy to reduce the memory footprint of the Routing Information Base (RIB). Instead of duplicating identical objects (NLRI, Attributes, NextHops) across multiple neighbors, the system uses global pools to share references to immutable objects.

    The Optimisation Model

    1. Immutability Requirement: All objects being interned (NLRI, AttributeCollection, IP) must be immutable. This allows multiple routes to safely share the same object instance without risk of side effects.
    2. Interning Pools: Specialized classes (e.g., NLRIPool, AttributePool) maintain a WeakValueDictionary of existing objects. When a new object is created, the system checks the pool using a unique index (via .index()). If a match exists, the cached instance is returned instead of the new one.
    3. Reference-Based Storage: The OutgoingRIB is updated to store references to these interned objects rather than full Route copies, significantly reducing memory usage when many neighbors receive identical updates.