Skip to content
/ focl Public

A lightweight, Rust-based BGP speaker built on BGPKIT

License

Notifications You must be signed in to change notification settings

bgpkit/focl

Repository files navigation

focl / focld

logo

A lightweight, Rust-based BGP speaker built on BGPKIT libraries.

The project consists of:

  • focld - The BGP daemon that manages peer sessions and route exchange
  • focl - CLI frontend for controlling and monitoring the daemon

⚠️ EXPERIMENTAL SOFTWARE - NOT FOR PRODUCTION USE

This project is currently in early development and is intended for:

  • Research and experimentation
  • Testing and simulation environments
  • Demonstrating BGPKIT library capabilities

Do not use in production networks. The codebase lacks comprehensive testing, security hardening, and operational features required for production BGP deployments. For production use, consider established solutions like BIRD, FRR, or GoBGP.

Features

Current (Phase 1)

  • IPv4 and IPv6 unicast support
  • TCP-MD5 authentication (RFC 2385) for BGP session security
  • Static prefix announcements
  • Full BGP FSM with proper timers (hold/keepalive)
  • Active and passive peer modes
  • Route refresh capability
  • MRT archive support (BGP4MP, TableDumpV2)
  • S3 and local replication destinations
  • CLI control via Unix Domain Socket

In Progress / Planned

  • Graceful restart capability
  • eBGP multihop support
  • Import/export policy framework
  • Blackhole route support
  • BMP exporter
  • RPKI validation integration

Quick Start

Installation

# Clone the repository
git clone https://github.com/bgpkit/focl.git
cd focl

# Build
cargo build --release

# Install binaries (optional)
cargo install --path .

Basic Configuration

Create focl.toml:

[global]
asn = 65001
router_id = "192.0.2.1"
listen = true
listen_addr = "0.0.0.0:179"
control_socket = "/tmp/focld.sock"
log_level = "info"

[[peers]]
name = "upstream"
address = "192.0.2.2"
remote_as = 65002
remote_port = 179
hold_time_secs = 90
password = "secretpassword"  # Optional: TCP-MD5 authentication

[[prefixes]]
network = "203.0.113.0/24"
next_hop = "192.0.2.1"

[archive]
enabled = false

Running

# Start the daemon
focld --config focl.toml

# Or using cargo
cargo run --bin focld -- --config focl.toml

# Control commands
focl peer list
focl peer show 192.0.2.2
focl rib summary
focl rib out 192.0.2.2

Example: Dual-Stack Configuration

Here's an example configuration demonstrating dual-stack (IPv4/IPv6) support with MD5 authentication. This is for testing and learning purposes only - not for production deployment:

[global]
asn = 65001
router_id = "192.0.2.1"
listen = true
listen_addr = "0.0.0.0:179"

# IPv4 peer with MD5
[[peers]]
name = "upstream-v4"
address = "192.0.2.2"
remote_as = 65002
password = "ChangeThisToStrongPassword123!"

# IPv6 peer with MD5
[[peers]]
name = "upstream-v6"
address = "2001:db8::1"
remote_as = 65002
password = "ChangeThisToStrongPassword123!"

# Announce IPv4 prefix
[[prefixes]]
network = "203.0.113.0/24"

# Announce IPv6 prefix
[[prefixes]]
network = "2001:db8:1000::/48"
next_hop = "2001:db8::2"

See focl-vultr-example.toml for a complete production-style example with documentation IPs.

Architecture

┌─────────────────┐     IPC (Unix Domain Socket)      ┌─────────────────┐
│     focl        │  ───────────────────────────────> │     focld       │
│  CLI frontend   │        JSON/NDJSON protocol       │  BGP speaker    │
│                 │ <─────────────────────────────────│    daemon       │
└─────────────────┘                                   └─────────────────┘
                                                              │
                                    ┌─────────────────────────┼─────────────────────────┐
                                    │                         │                         │
                                    v                         v                         v
                              ┌──────────┐            ┌────────────┐            ┌────────────┐
                              │ Archive  │            │   BGP      │            │   Config   │
                              │ Service  │            │  Service   │            │   Store    │
                              └──────────┘            └────────────┘            └────────────┘

Dependencies

  • bgpkit-parser - BGP message parsing and MRT encoding
  • tokio - Async runtime
  • serde/toml - Configuration handling
  • libc - TCP-MD5 socket options (Linux only)

Platform Support

Feature Linux macOS FreeBSD Windows
BGP Speaker ?
IPv4/IPv6 ?
TCP-MD5 Auth
MRT Archival ?

Note: TCP-MD5 (RFC 2385) requires Linux kernel support

Development

Running Tests

# Unit tests
cargo test

# Integration tests with GoBGP
cd scripts/interop
./run_gobgp_smoke.sh        # Basic test
./run_gobgp_md5.sh          # MD5 authentication test (Linux only)

Code Quality

# Formatting
cargo fmt

# Linting
cargo clippy --all-features -- -D warnings

# All checks (as run in CI)
cargo fmt --check
cargo build --no-default-features
cargo build
cargo test
cargo clippy --all-features -- -D warnings
cargo clippy --no-default-features

Configuration Reference

Global Settings

Option Type Default Description
asn u32 required Local AS number
router_id string required Router ID (IPv4)
listen bool true Accept incoming connections
listen_addr string "0.0.0.0:179" Bind address
control_socket path "/tmp/focld.sock" CLI socket path
log_level string "info" Log level

Peer Settings

Option Type Default Description
address string required Peer IP address
remote_as u32 required Peer AS number
local_as u32 global.asn Override local AS
remote_port u16 179 Peer TCP port
hold_time_secs u16 90 BGP hold timer
connect_retry_secs u16 5 Reconnect interval
passive bool false Wait for peer to connect
password string none TCP-MD5 password
route_refresh bool true Enable route refresh

Prefix Settings

Option Type Default Description
network string required IP prefix (v4 or v6)
next_hop string auto Next-hop address

License

MIT

Related Projects

Contributing

Contributions are welcome! This is an experimental project and we appreciate help making it more robust. Please ensure:

  1. Code passes cargo fmt and cargo clippy
  2. Tests pass: cargo test
  3. Interop tests pass with at least one external BGP implementation
  4. Documentation is updated for new features
  5. Any production-readiness improvements are clearly documented

Support

About

A lightweight, Rust-based BGP speaker built on BGPKIT

Resources

License

Stars

Watchers

Forks

Packages

No packages published