Skip to content

ExaBGP CLI

Thomas Mangin edited this page Jan 19, 2026 · 2 revisions

ExaBGP CLI Tool

The ExaBGP command-line interface (CLI) provides tools for running, testing, and managing ExaBGP instances. This guide covers all CLI options and usage patterns.

Table of Contents

Overview

Important: ExaBGP does NOT manipulate the routing table (RIB/FIB). The CLI tool is used to start ExaBGP, validate configurations, and control operational behavior.

Basic Syntax

exabgp [options] <configuration-file>

Common Use Cases

  • Start ExaBGP: exabgp /etc/exabgp/exabgp.conf
  • Validate config: exabgp validate /etc/exabgp/exabgp.conf (5.x)
  • Enable debugging: exabgp --debug /etc/exabgp/exabgp.conf
  • Check version: exabgp version

Basic Usage

Starting ExaBGP

# Start with configuration file
exabgp /etc/exabgp/exabgp.conf

# Start with full path
exabgp /etc/exabgp/exabgp.conf

# Start in foreground (no daemon)
exabgp /etc/exabgp/exabgp.conf

# Start with environment overrides
env exabgp.daemon.daemonize=false exabgp /etc/exabgp/exabgp.conf

Systemd Integration

# Start via systemd
sudo systemctl start exabgp

# Enable on boot
sudo systemctl enable exabgp

# Check status
sudo systemctl status exabgp

# View logs
sudo journalctl -u exabgp -f

Docker Usage

# Run ExaBGP in Docker
docker run -v /etc/exabgp:/etc/exabgp:ro \
           -v /var/run/exabgp:/var/run/exabgp \
           --net=host \
           ghcr.io/exa-networks/exabgp:latest \
           /etc/exabgp/exabgp.conf

Command-Line Arguments

Version Information

# Display ExaBGP version
exabgp --version

# Output:
# ExaBGP 5.0.0

Help Information

# Display help message
exabgp --help

# Display detailed help
exabgp --help-all

Configuration File

# Specify configuration file (required)
exabgp /etc/exabgp/exabgp.conf

# Using environment variable
export EXABGP_CONF=/etc/exabgp/exabgp.conf
exabgp $EXABGP_CONF

Validation Mode

# Validate configuration without starting ExaBGP (ExaBGP 5.x)
exabgp validate /etc/exabgp/exabgp.conf

# No output on success (exit code 0)
# Error messages printed to stderr on failure (exit code 1)

# Check exit code
if exabgp validate /etc/exabgp/exabgp.conf; then
    echo "Configuration valid"
else
    echo "Configuration invalid"
fi

# For ExaBGP 4.x, use:
# exabgp --test /etc/exabgp/exabgp.conf

Debug Mode

# Enable debug output
exabgp --debug /etc/exabgp/exabgp.conf

# Enable specific debug categories
env exabgp.log.level=DEBUG exabgp /etc/exabgp/exabgp.conf

# Debug network traffic
env exabgp.log.network=true exabgp /etc/exabgp/exabgp.conf

Decode Mode

# Decode BGP packets from file
exabgp --decode /path/to/bgp-packets.bin

# Decode with specific address family
exabgp --decode /path/to/bgp-packets.bin --family ipv4

Performance Options

# Run without forking (for containerized environments)
env exabgp.daemon.daemonize=false exabgp /etc/exabgp/exabgp.conf

# Disable privileges drop (not recommended)
env exabgp.daemon.user='' exabgp /etc/exabgp/exabgp.conf

Shell Completion (6.0.0+)

ExaBGP 6.0.0 introduces dynamic shell completion for Bash, Zsh, and Fish shells.

Installation

# Auto-detect shell and install
exabgp shell install

# Install for specific shell
exabgp shell install bash
exabgp shell install zsh
exabgp shell install fish

Manual Installation

# Bash
exabgp shell completion bash > ~/.local/share/bash-completion/completions/exabgp

# Zsh
exabgp shell completion zsh > ~/.zsh/completions/_exabgp

# Fish
exabgp shell completion fish > ~/.config/fish/completions/exabgp.fish

Features

After installation, you can:

  • Tab-complete subcommands: exabgp <TAB>
  • Tab-complete options: exabgp --<TAB>
  • Tab-complete configuration files: exabgp /etc/exabgp/<TAB>.conf

Example

$ exabgp <TAB>
validate   shell      migrate    healthcheck   version

$ exabgp shell <TAB>
install    completion

$ exabgp validate /etc/exa<TAB>
/etc/exabgp/exabgp.conf

Configuration Migration (6.0.0+)

ExaBGP 6.0.0 includes a built-in migration tool for converting configurations and API commands.

Configuration Migration

# Migrate configuration from 5.0 to 6.0 (main)
exabgp migrate conf -f 5 -t main /etc/exabgp/exabgp.conf

# Show what would change (dry run)
exabgp migrate conf -f 5 -t main --dry-run /etc/exabgp/exabgp.conf

# Migrate from 4.x to 5.x
exabgp migrate conf -f 4 -t 5 /etc/exabgp/exabgp.conf

# Migrate in place (creates backup with timestamp)
exabgp migrate conf -f 4 -t main -i /etc/exabgp/exabgp.conf
# Creates: exabgp.conf.20250119-143022.bak

# Show verbose transformation details
exabgp migrate conf -f 4 -t main -v /etc/exabgp/exabgp.conf

API Command Migration

# Interactive API command conversion
exabgp migrate api -f 5 -t main

# Enter 5.x commands, get 6.x equivalents:
> announce route 10.0.0.0/24 next-hop 1.2.3.4
peer * announce route 10.0.0.0/24 next-hop 1.2.3.4

> neighbor 192.0.2.1 announce route 10.0.0.0/24 next-hop self
peer 192.0.2.1 announce route 10.0.0.0/24 next-hop self

> show neighbor
peer show

Bridge Mode for Legacy Scripts (--exec)

The --exec option allows legacy scripts to run unchanged with ExaBGP 6.0.0 by providing bidirectional API transformation:

# Run legacy v4 script with automatic transformation
exabgp migrate api -f 4 -t main --exec /path/to/legacy-script.py

How it works:

  1. Script outputs v4 commands β†’ Bridge transforms to v6 β†’ ExaBGP receives v6
  2. ExaBGP sends v6 JSON β†’ Bridge transforms to v4 β†’ Script receives v4
ExaBGP (v6) ←→ [Bridge] ←→ Legacy Script (v4)

Example: A legacy script that outputs:

print('announce route 10.0.0.0/24 next-hop 1.2.3.4')
print('shutdown')

Gets transformed to:

peer * announce route 10.0.0.0/24 next-hop 1.2.3.4
daemon shutdown

Automatic Script Wrapping (--wrap-api)

When migrating configurations, use --wrap-api to automatically wrap run commands with the bridge:

# Migrate config AND wrap scripts with bridge
exabgp migrate conf -f 4 -t main --wrap-api old-config.conf

This transforms:

# Before
run /path/to/script.py;

# After
run exabgp migrate api -f 4 -t main --exec /path/to/script.py;

Complete migration workflow:

# Migrate config with script wrapping and pipe directly to ExaBGP
exabgp migrate conf -f 4 -t main --wrap-api old-config.conf | exabgp server -

Command Migration Examples

5.x Format 6.0.0 Format
announce route ... peer * announce route ...
neighbor <ip> announce ... peer <ip> announce ...
shutdown daemon shutdown
enable-ack session ack enable
show neighbor peer show

Migration Tool Options Summary

exabgp migrate conf - Configuration file migration:

Options:
  -f, --from      Source version (3.4, 4, 5)
  -t, --to        Target version (4, 5, main)
  -o, --output    Output file (default: stdout)
  -i, --inplace   Modify in place (creates .YYYYMMDD-HHMMSS.bak)
  -n, --dry-run   Show changes without applying
  -v, --verbose   Show each transformation
  -w, --wrap-api  Wrap run commands with API migration bridge

exabgp migrate api - API command migration:

Options:
  -f, --from      Source API version (4, 5)
  -t, --to        Target API version (5, main)
  -v, --verbose   Show each transformation
  -e, --exec      Execute command with bidirectional transformation

Configuration Validation

Basic Validation

# Validate configuration syntax
exabgp --test /etc/exabgp/exabgp.conf

# Exit codes:
# 0 = configuration valid
# 1 = configuration invalid

Automated Validation

#!/bin/bash
# /usr/local/bin/validate-and-reload.sh

CONFIG="/etc/exabgp/exabgp.conf"

# Validate configuration
if exabgp --test "$CONFIG"; then
    echo "Configuration valid"
    systemctl reload exabgp
    echo "ExaBGP reloaded"
else
    echo "Configuration invalid - NOT reloading"
    exit 1
fi

Pre-Deployment Validation

#!/bin/bash
# /usr/local/bin/pre-deploy-check.sh

set -e

CONFIG="/etc/exabgp/staging/exabgp.conf"

echo "=== ExaBGP Configuration Pre-Deployment Check ==="

# 1. Syntax validation
echo -n "Checking syntax... "
if exabgp --test "$CONFIG" > /dev/null 2>&1; then
    echo "βœ“ PASS"
else
    echo "βœ— FAIL"
    exabgp --test "$CONFIG"
    exit 1
fi

# 2. Check for required files
echo -n "Checking included files... "
MISSING=$(grep "^include" "$CONFIG" | awk '{print $2}' | sed 's/;$//' | while read f; do
    [ ! -f "$f" ] && echo "$f"
done)

if [ -z "$MISSING" ]; then
    echo "βœ“ PASS"
else
    echo "βœ— FAIL - Missing files:"
    echo "$MISSING"
    exit 1
fi

# 3. Check for duplicate neighbors
echo -n "Checking for duplicate neighbors... "
DUPLICATES=$(grep -h "^neighbor" "$CONFIG" /etc/exabgp/conf.d/*.conf 2>/dev/null | awk '{print $2}' | sort | uniq -d)
if [ -z "$DUPLICATES" ]; then
    echo "βœ“ PASS"
else
    echo "βœ— FAIL - Duplicate neighbors:"
    echo "$DUPLICATES"
    exit 1
fi

echo "=== All checks passed ==="

Environment Variables

ExaBGP behavior can be controlled via environment variables.

Logging Variables

# Enable all logging
export exabgp.log.all=true

# Set log level (CRITICAL, ERROR, WARNING, INFO, DEBUG)
export exabgp.log.level=INFO

# Log to file
export exabgp.log.destination=/var/log/exabgp/exabgp.log

# Enable specific log categories
export exabgp.log.network=true
export exabgp.log.routes=true
export exabgp.log.timers=false

Daemon Variables

# Disable daemonization (run in foreground)
export exabgp.daemon.daemonize=false

# PID file location
export exabgp.daemon.pid=/var/run/exabgp/exabgp.pid

# User to run as
export exabgp.daemon.user=exabgp

API Variables

# Enable ACK feature (ExaBGP 5.x)
export exabgp.api.ack=true

# API encoder (text or json)
export exabgp.api.encoder=text

BGP Variables

# Disable BGP capabilities
export exabgp.bgp.openwait=60

# Maximum routes to accept
export exabgp.bgp.maximum_routes=10000

Complete Environment Example

#!/bin/bash
# /usr/local/bin/exabgp-with-env.sh

# Logging
export exabgp.log.all=true
export exabgp.log.level=INFO
export exabgp.log.destination=/var/log/exabgp/exabgp.log

# Daemon
export exabgp.daemon.daemonize=false
export exabgp.daemon.user=exabgp

# API
export exabgp.api.ack=true
export exabgp.api.encoder=text

# Start ExaBGP
exec exabgp /etc/exabgp/exabgp.conf

Interactive Mode

ExaBGP doesn't have a traditional interactive shell, but you can send commands via stdin.

Sending Commands to Running ExaBGP

# ExaBGP listens for commands on stdin
echo "announce route 198.51.100.0/24 next-hop 192.0.2.10" | socat - UNIX-CONNECT:/var/run/exabgp/exabgp.sock

Using Named Pipe

# Create named pipe
mkfifo /var/run/exabgp/commands

# ExaBGP reads from pipe (in configuration)
# process commands {
#     run /bin/cat /var/run/exabgp/commands;
# }

# Send commands
echo "announce route 198.51.100.0/24 next-hop self" > /var/run/exabgp/commands

Enhanced CLI (exabgpcli 6.0.0+)

ExaBGP 6.0.0 significantly improves the exabgpcli interactive command-line tool.

Features

  • Intelligent Tab Completion - Complete commands and neighbor addresses
  • JSON Pretty-Printing - Formatted JSON output for responses
  • Command Descriptions - Help text for all commands
  • Dual Transport Support - Unix sockets and named pipes
  • Inline Help - Press ? for context-sensitive help
  • Graceful Signal Handling - Clean exit with Ctrl+C

Starting exabgpcli

# Connect to running ExaBGP (default socket)
exabgpcli

# Connect with specific pipe name
exabgpcli --pipename my-instance

# Show help
exabgpcli --help

Interactive Commands

$ exabgpcli
ExaBGP CLI - Type '?' for help, TAB for completion

# Show daemon status
> daemon status
ExaBGP Daemon Status
====================
Version: 6.0.0
UUID: abc123-def456
PID: 12345
Uptime: 2h 30m 15s
Peers: 2
  - 192.0.2.1: established
  - 192.0.2.2: established

# Health check ping
> session ping
{"pong": "abc123-def456", "active": true}

# Show RIB
> rib show in
...

# Send route announcement
> peer * announce route 10.0.0.0/24 next-hop self
done

# Get help
> system help
Available API commands (v6 format):
- peer *|<ip> announce|withdraw route ...
- peer show|list
- rib show in|out
- daemon shutdown|status
- session ping|ack enable|disable|silence

Tab Completion Examples

# Complete commands
> peer <TAB>
*   192.0.2.1   192.0.2.2   show

# Complete subcommands
> peer * <TAB>
announce   withdraw

# Complete peer addresses
> peer 192.<TAB>
192.0.2.1   192.0.2.2

Multiple CLI Instances

ExaBGP 6.0.0 supports multiple CLI instances with different named pipes:

# Start ExaBGP with custom pipe name
exabgp --pipename production /etc/exabgp/exabgp.conf

# Connect with that pipe name
exabgpcli --pipename production

Transport Options

The CLI supports both Unix sockets (preferred) and named pipes:

# Unix socket (default, faster)
exabgpcli

# Named pipe (legacy compatibility)
exabgpcli --transport pipe

Operational Commands

Reloading Configuration

# Send SIGHUP to reload configuration
sudo systemctl reload exabgp

# Or manually
kill -HUP $(cat /var/run/exabgp/exabgp.pid)

Graceful Shutdown

# Graceful shutdown via systemd
sudo systemctl stop exabgp

# Or manually
kill -TERM $(cat /var/run/exabgp/exabgp.pid)

Force Kill

# Force kill (not recommended - may leave routes advertised)
sudo systemctl kill -s KILL exabgp

# Or manually
kill -9 $(cat /var/run/exabgp/exabgp.pid)

Checking Process Status

# Check if ExaBGP is running
if pgrep -x exabgp > /dev/null; then
    echo "ExaBGP is running"
else
    echo "ExaBGP is not running"
fi

# Check via systemd
systemctl is-active exabgp

# Get process details
ps aux | grep exabgp

Debugging Options

Enable Debug Logging

# Debug all categories
env exabgp.log.level=DEBUG exabgp /etc/exabgp/exabgp.conf

# Debug specific categories
env exabgp.log.network=true \
    exabgp.log.routes=true \
    exabgp.log.level=DEBUG \
    exabgp /etc/exabgp/exabgp.conf

Packet Capture

# Capture BGP packets with tcpdump
sudo tcpdump -i any -n port 179 -w /tmp/bgp-packets.pcap

# Decode with ExaBGP
exabgp --decode /tmp/bgp-packets.pcap

Verbose Output

# Run with verbose output
exabgp --debug /etc/exabgp/exabgp.conf 2>&1 | tee /tmp/exabgp-debug.log

Testing Configuration Changes

# Test configuration without affecting running instance
exabgp --test /etc/exabgp/exabgp.conf.new

# Compare configurations
diff /etc/exabgp/exabgp.conf /etc/exabgp/exabgp.conf.new

Best Practices

1. Always Validate Before Deploying

# ALWAYS validate first
exabgp --test /etc/exabgp/exabgp.conf

# Only deploy if validation passes
if [ $? -eq 0 ]; then
    systemctl reload exabgp
fi

2. Use Systemd for Production

# /etc/systemd/system/exabgp.service
[Unit]
Description=ExaBGP
Documentation=https://github.com/Exa-Networks/exabgp/wiki
After=network.target

[Service]
Type=simple
User=exabgp
Group=exabgp

# Environment variables
Environment=exabgp.log.all=true
Environment=exabgp.log.destination=/var/log/exabgp/exabgp.log
Environment=exabgp.daemon.daemonize=false

ExecStart=/usr/local/bin/exabgp /etc/exabgp/exabgp.conf
ExecReload=/bin/kill -HUP $MAINPID

Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

3. Monitor Logs

# Tail logs in real-time
tail -f /var/log/exabgp/exabgp.log

# Filter for errors
tail -f /var/log/exabgp/exabgp.log | grep -i error

# Monitor via journalctl
journalctl -u exabgp -f

4. Use Configuration Management

# Ansible example
- name: Deploy ExaBGP configuration
  template:
    src: exabgp.conf.j2
    dest: /etc/exabgp/exabgp.conf
    validate: 'exabgp --test %s'
  notify: Reload ExaBGP

5. Implement Health Checks

#!/bin/bash
# /usr/local/bin/check-exabgp-health.sh

# Check if ExaBGP is running
if ! pgrep -x exabgp > /dev/null; then
    echo "CRITICAL: ExaBGP is not running"
    exit 2
fi

# Check if BGP sessions are up
SESSION_COUNT=$(grep "Peer.*up" /var/log/exabgp/exabgp.log | tail -10 | wc -l)
if [ "$SESSION_COUNT" -eq 0 ]; then
    echo "WARNING: No BGP sessions established"
    exit 1
fi

echo "OK: ExaBGP is running with $SESSION_COUNT session(s)"
exit 0

6. Automate Restarts

# Systemd service with automatic restart
[Service]
Restart=always
RestartSec=10
StartLimitInterval=200
StartLimitBurst=5

7. Version Control

# Track configuration changes
cd /etc/exabgp
git init
git add exabgp.conf
git commit -m "Initial configuration"

# Before changes
git diff exabgp.conf

# After changes
git add exabgp.conf
git commit -m "Add new BGP neighbor"

See Also


πŸ‘» Ghost written by Claude (Anthropic AI)

Clone this wiki locally