Skip to content

From 5.x to 6.x

Thomas Mangin edited this page Feb 2, 2026 · 3 revisions

Migration from ExaBGP 5.x to 6.0.0

Complete guide for upgrading from ExaBGP 5.x to 6.0.0 (main branch)

⚠️ BREAKING CHANGES: ExaBGP 6.0.0 introduces breaking changes from 5.x

ExaBGP 6.0.0 brings modernization and new features, but requires careful migration planning.

Key Changes:

  • ❌ Python 3.7-3.11 dropped (Python 3.12+ required)
  • ⚠️ Async reactor is now the default (no option to switch to legacy mode)
  • ⚠️ BGP-LS JSON API field changes (ip, sr-adj, remote-router-id)
  • βœ… New shell completion (Bash, Zsh, Fish)
  • βœ… Enhanced interactive CLI
  • βœ… Health monitoring API commands
  • βœ… Migration tool for config and API conversion

Table of Contents


Overview

Release: ExaBGP 6.0.0 (main branch)

Severity: 🟑 MEDIUM - Breaking changes, but migration tools available

Timeline: ExaBGP 6.0.0 becomes the new development branch. ExaBGP 5.0.0 remains LTS for stability.

Changes: Async reactor default, Python 3.12+, BGP-LS JSON changes, new CLI features


Should You Upgrade?

βœ… YES - Upgrade to 6.0.0 If:

  • βœ… You want the async reactor for modern event loop integration
  • βœ… You need shell completion (Bash, Zsh, Fish)
  • βœ… You want enhanced CLI with tab completion and JSON pretty-printing
  • βœ… You need health monitoring API commands
  • βœ… You're already on Python 3.12+
  • βœ… You can test thoroughly before production deployment

⏸️ WAIT - Stay on 5.x If:

  • ⏸️ You cannot upgrade to Python 3.12+
  • ⏸️ You're using BGP-LS JSON API (field names changed - see below)
  • ⏸️ You need guaranteed stability for production
  • ⏸️ You cannot test the migration thoroughly

Recommendation: Test 6.0.0 in staging first. ExaBGP 5.x remains a stable LTS option.


What Changed

Breaking Changes Summary

Area Change Impact
Python 3.12+ required (3.7-3.11 dropped) πŸ”΄ CRITICAL - System upgrade needed
Reactor Async mode now default (generators still work) 🟒 LOW - Test your workloads
BGP-LS JSON ip β†’ prefix (CIDR notation) πŸ”΄ HIGH - Parser updates required
BGP-LS JSON sr-adj β†’ sr-adjs (array) πŸ”΄ HIGH - Parser updates required
BGP-LS JSON remote-router-id β†’ remote-router-ids (array) πŸ”΄ HIGH - Parser updates required

New Major Features

  • βœ… Async Reactor Default - Modern async/await event loop
  • βœ… Shell Completion - Bash, Zsh, Fish support
  • βœ… Enhanced CLI - Tab completion, JSON pretty-printing, inline help
  • βœ… Health Monitoring - session ping and daemon status commands
  • βœ… Migration Tool - Automatic config and API conversion
  • βœ… Type Annotations - Better IDE support and type safety
  • βœ… Python 3.12/3.13/3.14 - Full support for latest Python versions

Breaking Changes

Python Version Requirements

ExaBGP 5.x

  • βœ… Python 3.8+ minimum
  • βœ… Python 3.13 supported

ExaBGP 6.0.0

  • ❌ Python 3.7-3.11 dropped
  • βœ… Python 3.12+ minimum
  • βœ… Python 3.13 and 3.14 supported

Migration Action

# Check your Python version
python3 --version

# If < 3.12, upgrade Python first
# Ubuntu/Debian:
sudo apt install python3.12

# RHEL/CentOS/Fedora:
sudo dnf install python3.12

# macOS:
brew install [email protected]

# Verify
python3.12 --version

Impact: If you're on Python 3.8-3.11, you must upgrade Python before upgrading ExaBGP.


Async Reactor Now Default

What Changed

ExaBGP 6.0.0 uses a modern async/await-based event loop as the default reactor. The separate "legacy reactor" mode toggle has been removed - all execution now goes through the unified async system.

Why This Matters

  • Performance: Better event loop integration using Python's native asyncio
  • Modern: Uses Python's native async/await patterns
  • Backward Compatible: Generator-based callbacks still work (they run inside asyncio.run())
  • Tested: Comprehensive test coverage (72/72 functional tests, 1,376 unit tests)

Migration Action

  1. Test your workloads - most users won't notice a difference since generators still work
  2. Report issues on GitHub if you encounter any problems
  3. There is no option to switch back to a separate legacy reactor mode
  4. Your existing generator-based API scripts should continue to work unchanged

BGP-LS JSON API Changes

1. IP Reachability TLV

ExaBGP 5.x (Old):

{
  "bgp-ls": {
    "ip": "10.134.2.88"
  }
}

ExaBGP 6.0.0 (New):

{
  "bgp-ls": {
    "prefix": "10.134.2.88/30"
  }
}

Changes:

  • Key renamed from ip to prefix
  • Now includes prefix length in CIDR notation

2. Adjacency SID

ExaBGP 5.x (Old - duplicate keys):

{
  "bgp-ls": {
    "sr-adj": {"sid": 100, "flags": "0x80"},
    "sr-adj": {"sid": 200, "flags": "0x40"}
  }
}

ExaBGP 6.0.0 (New - array):

{
  "bgp-ls": {
    "sr-adjs": [
      {"sid": 100, "flags": "0x80"},
      {"sid": 200, "flags": "0x40"}
    ]
  }
}

Changes:

  • Key renamed from sr-adj to sr-adjs
  • Now outputs as array of objects instead of duplicate keys
  • Valid JSON (no duplicate keys)

3. Remote Router ID

ExaBGP 5.x (Old - duplicate keys):

{
  "bgp-ls": {
    "remote-router-id": "192.0.2.1",
    "remote-router-id": "2001:db8::1"
  }
}

ExaBGP 6.0.0 (New - array):

{
  "bgp-ls": {
    "remote-router-ids": ["192.0.2.1", "2001:db8::1"]
  }
}

Changes:

  • Key renamed from remote-router-id to remote-router-ids
  • IPv4 and IPv6 router IDs merged into single array
  • Valid JSON (no duplicate keys)

Migration Action

Update your BGP-LS JSON parsers:

# Old 5.x parser
ip_prefix = data['bgp-ls']['ip']
adj_sid = data['bgp-ls']['sr-adj']  # Only gets last duplicate
router_id = data['bgp-ls']['remote-router-id']  # Only gets last duplicate

# New 6.0.0 parser
ip_prefix = data['bgp-ls']['prefix']  # Now includes /length
adj_sids = data['bgp-ls']['sr-adjs']  # Array of all SIDs
for sid in adj_sids:
    print(f"SID: {sid['sid']}, Flags: {sid['flags']}")
router_ids = data['bgp-ls']['remote-router-ids']  # Array of all IDs

New Features in 6.0.0

Shell Completion

Dynamic completion generation for Bash, Zsh, and Fish:

# Auto-detect shell and install
exabgp shell install

# Or specify shell
exabgp shell install bash
exabgp shell install zsh
exabgp shell install fish

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

Features:

  • Complete subcommands and options
  • Complete .conf files
  • Auto-detects current shell

Enhanced Interactive CLI

The exabgp-cli tool has been significantly improved:

# Start CLI
exabgpcli

# Features:
# - Intelligent tab completion for commands and neighbors
# - JSON pretty-printing for responses
# - Command descriptions and help text
# - '?' key for inline help
# - Graceful signal handling (Ctrl+C)

Dual Transport Support:

  • Unix sockets (default)
  • Named pipes (for legacy compatibility)

Health Monitoring API

New API commands for health monitoring:

# Health check ping - lightweight, responds with pong + daemon UUID
sys.stdout.write("session ping\n")
sys.stdout.flush()
# Response: {"pong": "daemon-uuid", "active": true}

# Daemon status - full status info
sys.stdout.write("daemon status\n")
sys.stdout.flush()
# Response includes: version, UUID, PID, uptime, peer states

Type Annotations

Comprehensive type annotations have been added throughout the codebase:

  • Better IDE support (autocomplete, error detection)
  • Static type checking with mypy
  • Improved documentation
  • Fewer runtime type errors

Migration Tool

ExaBGP 6.0.0 includes a built-in migration tool for automatic conversion:

Configuration Migration

# Migrate configuration file
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 and wrap API scripts with bridge (see Bridge Mode below)
exabgp migrate conf -f 4 -t main --wrap-api old-config.conf

API Command Migration

# Migrate API commands
exabgp migrate api -f 5 -t main

# Interactive mode - enter commands to convert
> 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

Bridge Mode (--exec)

The --exec option enables bidirectional API transformation, allowing legacy scripts to run unchanged with ExaBGP 6.0.0. This is the recommended approach when you have complex scripts that would be difficult to modify.

How Bridge Mode Works

ExaBGP 6.0.0 (main)
    β”‚
    β”‚ sends v6 JSON events
    β–Ό
[stdin: reverse transform v6 β†’ v4]
    β”‚
    β–Ό
old-script.py (expects v4 format)
    β”‚
    β”‚ outputs v4 commands
    β–Ό
[stdout: forward transform v4 β†’ v6]
    β”‚
    β–Ό
ExaBGP 6.0.0 (main)

Key benefit: Your legacy v4/v5 scripts work without any code changes.

Using Bridge Mode

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

# This will:
# 1. Transform script's v4 output β†’ v6 commands for ExaBGP
# 2. Transform ExaBGP's v6 JSON β†’ v4 JSON for the script

Example: Legacy v4 Script

Your original v4 script might look like this:

#!/usr/bin/env python3
import sys
import json

# Output v4-style commands (no peer selector)
print('announce route 10.0.0.0/24 next-hop 1.2.3.4', flush=True)
print('withdraw route 10.0.1.0/24', flush=True)
print('shutdown', flush=True)

# Read v4-style JSON input
for line in sys.stdin:
    data = json.loads(line)
    # Process v4 format JSON...

With bridge mode, this script works unchanged:

exabgp migrate api -f 4 -t main --exec /path/to/legacy-script.py

The bridge transforms:

  • Output: announce route ... β†’ peer * announce route ...
  • Output: shutdown β†’ daemon shutdown
  • Input: v6 JSON keys β†’ v4 JSON keys (e.g., sr-capability-flags β†’ sr_capability_flags)

Automatic Configuration Wrapping (--wrap-api)

The --wrap-api flag automatically wraps run commands in your configuration with the bridge:

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

This transforms configuration entries:

# Before (in 4.x config)
run /path/to/script.py;

# After (migrated with --wrap-api)
run exabgp migrate api -f 4 -t main --exec /path/to/script.py;

Bridge Transformation Details

Forward Transform (script output β†’ ExaBGP):

v4 Command v6 Command
announce route ... peer * announce route ...
withdraw route ... peer * withdraw route ...
neighbor 1.2.3.4 announce ... peer 1.2.3.4 announce ...
shutdown daemon shutdown
reload daemon reload
show adj-rib out rib show out
show neighbor peer show

Reverse Transform (ExaBGP JSON β†’ script):

v6 JSON Key v4 JSON Key Context
sr-capability-flags sr_capability_flags bgp-ls
interface-addresses interface-address bgp-ls
neighbor-addresses neighbor-address bgp-ls
prefix ip ip-reachability-tlv

When to Use Bridge Mode

βœ… Use bridge mode when:

  • You have complex legacy scripts that are difficult to modify
  • You need to migrate quickly with minimal risk
  • You want to test 6.0.0 without modifying working scripts
  • Your scripts use BGP-LS JSON that needs key transformation

⚠️ Consider updating scripts instead when:

  • Scripts are simple and easy to modify
  • You want to eliminate the bridge overhead
  • You're starting fresh with no legacy code

API Command Format Changes

ExaBGP 6.0.0 uses a "target-first" command format:

5.x Command 6.0.0 Command
announce route 10.0.0.0/24... peer * announce route 10.0.0.0/24...
neighbor 192.0.2.1 announce... peer 192.0.2.1 announce...
shutdown daemon shutdown
status daemon status
enable-ack session ack enable
disable-ack session ack disable
show neighbor peer show
show adj-rib in rib show in
show adj-rib out rib show out

Note: The 5.x format is still accepted for backward compatibility, but the 6.0.0 format is recommended.


Migration Steps

Step 1: Verify Python Version

# Check Python version
python3 --version

# Must be 3.12 or higher
# Recommended: 3.12 or 3.13

If Python < 3.12, upgrade Python first.

Step 2: Backup Configuration

# Backup current config
cp /etc/exabgp/exabgp.conf /etc/exabgp/exabgp.conf.5.x.bak

# Backup API programs
cp -r /etc/exabgp/programs /etc/exabgp/programs.5.x.bak

Step 3: Run Migration Tool

# Migrate configuration
exabgp migrate conf -f 5 -t main /etc/exabgp/exabgp.conf

# Review changes
diff /etc/exabgp/exabgp.conf.5.x.bak /etc/exabgp/exabgp.conf

Step 4: Update JSON Parsers (If Using BGP-LS)

If you're using BGP-LS with JSON encoder, update your parsers for the new field names:

# Update field names
# ip -> prefix
# sr-adj -> sr-adjs
# remote-router-id -> remote-router-ids

Step 5: Install ExaBGP 6.0.0

# From PyPI (when released)
pip3 install --upgrade exabgp

# Or from source (main branch)
git clone https://github.com/Exa-Networks/exabgp.git
cd exabgp
git checkout main
pip3 install .

Step 6: Validate Configuration

# Validate configuration
exabgp validate /etc/exabgp/exabgp.conf

Step 7: Test in Staging

# Start ExaBGP with updated config
exabgp /etc/exabgp/exabgp.conf

# Monitor logs for errors
tail -f /var/log/exabgp.log

# Verify BGP sessions establish
exabgpcli peer show

Step 8: Test Async Reactor

# Test with async reactor
exabgp /etc/exabgp/exabgp.conf

Step 9: Install Shell Completion (Optional)

# Install shell completion
exabgp shell install

Step 10: Deploy to Production

Only after thorough testing:

# Deploy to production
# Monitor closely for first 24 hours
# Have rollback plan ready

Testing Your Migration

Configuration Testing Checklist

  • Configuration syntax valid: exabgp validate /etc/exabgp/exabgp.conf
  • No deprecated syntax
  • Migration tool ran successfully

API Testing Checklist

  • JSON parsers handle new BGP-LS field names (if applicable)
  • ACK handling still works
  • Route announcements work
  • Route withdrawals work
  • Error handling works

Reactor Testing Checklist

  • Async reactor works correctly
  • No performance regressions
  • Report any issues on GitHub

Integration Testing Checklist

  • BGP sessions establish successfully
  • Routes announced correctly
  • Health checks work (if using healthcheck module)
  • CLI commands work (exabgpcli)
  • Monitoring/alerting still works

Rollback Plan

If issues occur, rollback to 5.x:

# 1. Stop ExaBGP 6.0.0
systemctl stop exabgp

# 2. Restore 5.x configuration
cp /etc/exabgp/exabgp.conf.5.x.bak /etc/exabgp/exabgp.conf

# 3. Reinstall 5.x
pip3 install exabgp==5.0.0

# 4. Restart ExaBGP
systemctl start exabgp

# 5. Verify sessions
exabgpcli show neighbor summary

Important: Keep your 5.x configuration backed up until 6.0.0 is validated in production.


Common Issues

Issue 1: Python Version Too Old

Symptom:

Python 3.12+ required, found 3.11

Cause: Python < 3.12

Solution:

# Upgrade Python to 3.12+
# Ubuntu/Debian:
sudo apt install python3.12
pip3.12 install exabgp

Issue 2: Async Reactor Issues

Symptom: Unexpected behavior or errors with async operations

Cause: Async reactor is the only mode in 6.0.0

Solution:

  1. Report the issue on GitHub with detailed reproduction steps
  2. Include debug output: exabgp --debug /etc/exabgp/exabgp.conf
  3. Check for any blocking operations in your API scripts

Issue 3: BGP-LS JSON Parser Fails

Symptom:

KeyError: 'ip'

Cause: Field renamed to prefix

Solution:

# Update parser
prefix = data['bgp-ls']['prefix']  # Now "10.134.2.88/30"

Issue 4: BGP-LS Adjacency SID Missing

Symptom:

KeyError: 'sr-adj'

Cause: Field renamed to sr-adjs (array)

Solution:

# Update parser
adj_sids = data['bgp-ls']['sr-adjs']  # Now an array
for sid in adj_sids:
    print(sid)

Issue 5: Remote Router ID Missing

Symptom:

KeyError: 'remote-router-id'

Cause: Field renamed to remote-router-ids (array)

Solution:

# Update parser
router_ids = data['bgp-ls']['remote-router-ids']  # Now an array

Version Compatibility Matrix

Feature 5.x 6.0.0 Compatible?
Configuration 5.x syntax 6.0.0 syntax βœ… Compatible (migration tool available)
Text API Text encoder Text encoder βœ… Compatible
JSON API 5.x JSON 6.0.0 JSON ⚠️ BGP-LS fields changed
Python 3.8+ 3.12+ only ❌ 3.8-3.11 removed
Reactor Generator-based Async (default) βœ… Generators still work inside async

Upgrade Decision Matrix

Your Situation Recommendation Action
Python < 3.12 ⏸️ Wait Upgrade Python first
Using BGP-LS JSON ⚠️ Test carefully Update parsers before upgrading
Using Text API only βœ… Safe to upgrade Test async reactor
Need shell completion βœ… Upgrade Only in 6.0.0
Need health monitoring API βœ… Upgrade Only in 6.0.0
Production-critical ⏸️ Test first Validate in staging

Recommendation

For New Deployments: Use ExaBGP 6.0.0 (latest development)

For Existing 5.x Users:

  1. βœ… Test thoroughly in staging environment
  2. ⚠️ Update BGP-LS JSON parsers if using JSON encoder
  3. βœ… Upgrade Python to 3.12+ if needed
  4. βœ… Test async reactor (default)
  5. βœ… Deploy to production with rollback plan ready

ExaBGP 6.0.0 is the development branch. ExaBGP 5.x remains LTS (Long-Term Support) for production stability.


See Also


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

Clone this wiki locally