focl / focld

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
# Build
# Install binaries (optional)
Basic Configuration
Create focl.toml:
[]
= 65001
= "192.0.2.1"
= true
= "0.0.0.0:179"
= "/tmp/focld.sock"
= "info"
[[]]
= "upstream"
= "192.0.2.2"
= 65002
= 179
= 90
= "secretpassword" # Optional: TCP-MD5 authentication
[[]]
= "203.0.113.0/24"
= "192.0.2.1"
[]
= false
Running
# Start the daemon
# Or using cargo
# Control commands
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:
[]
= 65001
= "192.0.2.1"
= true
= "0.0.0.0:179"
# IPv4 peer with MD5
[[]]
= "upstream-v4"
= "192.0.2.2"
= 65002
= "ChangeThisToStrongPassword123!"
# IPv6 peer with MD5
[[]]
= "upstream-v6"
= "2001:db8::1"
= 65002
= "ChangeThisToStrongPassword123!"
# Announce IPv4 prefix
[[]]
= "203.0.113.0/24"
# Announce IPv6 prefix
[[]]
= "2001:db8:1000::/48"
= "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
# Integration tests with GoBGP
Code Quality
# Formatting
# Linting
# All checks (as run in CI)
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
- bgpkit-parser - MRT/BGP/BMP parsing library
- monocle - BGP looking glass and analysis tool
- bgpkit-broker - BGP data indexing service
Contributing
Contributions are welcome! This is an experimental project and we appreciate help making it more robust. Please ensure:
- Code passes
cargo fmtandcargo clippy - Tests pass:
cargo test - Interop tests pass with at least one external BGP implementation
- Documentation is updated for new features
- Any production-readiness improvements are clearly documented
Support
- GitHub Issues: https://github.com/bgpkit/focl/issues
- Discord: https://discord.com/invite/XDaAtZsz6b