-
Notifications
You must be signed in to change notification settings - Fork 459
From 3.4 to 4.x
Complete guide for upgrading from ExaBGP 3.x to 4.x
β οΈ CRITICAL: You MUST Upgrade from 3.xExaBGP 3.x uses Python 2, which is deprecated and no longer supported. Python 2 reached end-of-life on January 1, 2020 and receives no security updates.
All users must upgrade to ExaBGP 4.x or 5.0.0 for security and compatibility.
β οΈ Breaking Changes: ExaBGP 3.x β 4.x includes breaking changes requiring configuration and code updates.
βΉοΈ About ExaBGP 5.0.0: If you're considering upgrading beyond 4.x, note that ExaBGP 5.0.0 introduces additional breaking changes from 4.x (Python 3.8+, JSON API changes). See 4.x β 5.0.0 Migration Guide for details. Most users should upgrade to 4.x first, then decide if 5.0.0 is needed.
- Overview
- Should You Upgrade?
- What Changed
- Configuration Syntax Changes
- JSON Format Changes
- Command-Line Changes
- API Changes
- Migration Steps
- Testing Your Migration
- Rollback Plan
- Common Issues
Release: ExaBGP 4.0.0 (~2017)
Severity: π‘ MODERATE - Configuration and some API changes required
Timeline: ExaBGP 3.x is deprecated and no longer maintained. All users should upgrade to 4.x.
ExaBGP 3.x is built on Python 2, which is:
- β End-of-life since January 1, 2020
- β No security patches or updates
- β Removed from most modern Linux distributions
- β Incompatible with modern Python packages
All ExaBGP 3.x users must upgrade immediately for:
- β Security updates and patches
- β Python 3 support (Python 2 is dead)
- β New features (FlowSpec improvements, EVPN, BGP-LS, etc.)
- β Better performance and stability
- β Modern BGP features (ADD-PATH, extended next-hop, etc.)
- β Continued maintenance and support
| Area | Change | Impact |
|---|---|---|
| Configuration | Syntax changes | π΄ HIGH - Manual updates required |
| JSON Format | Output structure changed | π‘ MEDIUM - Parser updates needed |
| CLI Arguments | Some flags changed | π‘ MEDIUM - Script updates needed |
| API Commands | Minor syntax changes | π’ LOW - Most commands compatible |
- β Full FlowSpec support (RFC 5575)
- β EVPN support (RFC 7432)
- β BGP-LS support (RFC 7752)
- β ADD-PATH support (RFC 7911)
- β Extended next-hop (RFC 5549)
- β Python 3 support
- β Better error messages
- β Improved performance
The configuration file syntax changed significantly between 3.x and 4.x.
ExaBGP 3.x:
neighbor 192.168.1.1 {
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
# 3.x syntax
capability {
route-refresh;
graceful-restart 120;
}
}ExaBGP 4.x:
neighbor 192.168.1.1 {
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
# 4.x syntax - similar but some keywords changed
capability {
route-refresh enable;
graceful-restart 120;
}
}ExaBGP 3.x:
process announce {
run /usr/local/bin/announce.py;
}
neighbor 192.168.1.1 {
# ... neighbor config ...
process announce;
}ExaBGP 4.x:
process announce {
run /usr/local/bin/announce.py;
encoder text; # New: explicit encoder
}
neighbor 192.168.1.1 {
# ... neighbor config ...
api {
processes [ announce ]; # New: api block
}
}ExaBGP 3.x:
neighbor 192.168.1.1 {
# ... neighbor config ...
family {
ipv4 unicast;
ipv4 flow;
}
}ExaBGP 4.x:
neighbor 192.168.1.1 {
# ... neighbor config ...
family {
ipv4 unicast;
ipv4 flow;
}
}Note: Family syntax is similar, but some address family names changed.
If you use encoder json to receive BGP updates, the JSON format changed significantly.
ExaBGP 3.x JSON:
{
"type": "update",
"neighbor": "192.168.1.1",
"announce": {
"ipv4 unicast": {
"100.10.0.0/24": {
"next-hop": "192.168.1.2"
}
}
}
}ExaBGP 4.x JSON:
{
"exabgp": "4.2.25",
"time": 1699564800.0,
"type": "update",
"neighbor": {
"address": {
"local": "192.168.1.2",
"peer": "192.168.1.1"
},
"asn": {
"local": 65001,
"peer": 65000
},
"message": {
"update": {
"announce": {
"ipv4 unicast": {
"100.10.0.0/24": [
{
"next-hop": "192.168.1.2"
}
]
}
}
}
}
}
}Changes:
- More structured (nested
neighborobject) - Added metadata (
exabgp,time,asn) - Route attributes now in arrays
- More detailed peer information
Impact: Programs parsing JSON output need updates.
Some command-line arguments changed between 3.x and 4.x.
ExaBGP 3.x:
# 3.x command line
exabgp --debug /etc/exabgp/exabgp.conf
exabgp --helpExaBGP 4.x:
# 4.x command line (mostly compatible)
exabgp /etc/exabgp/exabgp.conf
exabgp --help
exabgp --versionEnvironment Variables (mostly compatible):
# Both 3.x and 4.x
export exabgp.daemon.user=exabgp
export exabgp.log.level=INFO
export exabgp.log.destination=stdout
# 4.x added
export exabgp.api.ack=trueMost API commands are compatible between 3.x and 4.x.
# These work identically in 3.x and 4.x
announce route 100.10.0.0/24 next-hop self
withdraw route 100.10.0.0/24
announce flow route { match { destination 100.10.0.0/24; } then { discard; } }# New in 4.x
announce attributes next-hop self nlri 100.10.0.0/24 100.20.0.0/24 # Bulk announcements
clear adj-rib out
flush adj-rib outExaBGP 3.x:
- No ACK responses
- Fire-and-forget commands
- No way to know if command succeeded
ExaBGP 4.x:
- ACK enabled by default
- Sends
done,error,shutdownresponses - Programs can verify command success
Migration Note: If your 3.x programs don't read STDIN, they will hang in 4.x unless you:
- Option 1: Update programs to read ACK responses (recommended)
-
Option 2: Disable ACK (choose based on ExaBGP version):
- Environment variable:
export exabgp.api.ack=false(4.x and 5.x) - Runtime command: Send
disable-ackorsilence-ack(5.x/main only)
- Environment variable:
See ACK Feature Documentation for details.
# Backup configuration
cp /etc/exabgp/exabgp.conf /etc/exabgp/exabgp.conf.3x.backup
# Backup API programs
tar czf /tmp/exabgp-api-programs-backup.tar.gz /usr/local/bin/exabgp-*
# Document current version
exabgp --version > /tmp/exabgp-version-3x.txtOption A: Using pip (recommended):
# Install ExaBGP 4.x
pip3 install exabgp
# Verify version
exabgp --version
# Should show: ExaBGP 4.2.xOption B: From source:
git clone https://github.com/Exa-Networks/exabgp.git
cd exabgp
git checkout 4.2 # Use latest 4.2.x tag
pip3 install .Automated conversion (if available):
# No official converter exists - manual updates requiredManual updates:
- Read through your 3.x configuration
- Check configuration syntax in Configuration Syntax Guide
- Update process blocks to use
api { }structure - Add
encoderdirective to process blocks - Verify family statements
Example conversion:
Before (3.x):
process announce {
run /usr/local/bin/announce.py;
}
neighbor 192.168.1.1 {
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
family {
ipv4 unicast;
}
process announce;
}After (4.x):
process announce {
run /usr/local/bin/announce.py;
encoder text; # Added
}
neighbor 192.168.1.1 {
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
family {
ipv4 unicast;
}
api { # Changed
processes [ announce ];
}
}# Test configuration parsing
exabgp --test /etc/exabgp/exabgp.conf
# If errors occur, check:
# - Process block syntax (api { } structure)
# - encoder directives
# - Family statementsIf you use encoder json and parse JSON output:
Update JSON parser:
# 3.x parser
def parse_3x(line):
msg = json.loads(line)
if msg['type'] == 'update':
routes = msg['announce']['ipv4 unicast']
# ...
# 4.x parser
def parse_4x(line):
msg = json.loads(line)
if msg['type'] == 'update':
routes = msg['neighbor']['message']['update']['announce']['ipv4 unicast']
# ...If your programs don't read STDIN:
Option 1 - Disable ACK (simpler, but no error feedback):
# Environment variable (works on 4.x and 5.x)
export exabgp.api.ack=false
exabgp /etc/exabgp/exabgp.conf
# OR runtime command (5.x/main only)
# Send: disable-ack or silence-ackOption 2 - Update programs to read ACK (recommended):
#!/usr/bin/env python3
import sys
import select
import time
def wait_for_ack(expected_count=1, timeout=30):
"""
Wait for ACK responses with polling loop (new in 4.x).
ExaBGP may not respond immediately, so we poll with sleep.
Handles both text and JSON encoder formats.
"""
import json
received = 0
start_time = time.time()
while received < expected_count:
if time.time() - start_time >= timeout:
return False
ready, _, _ = select.select([sys.stdin], [], [], 0.1)
if ready:
line = sys.stdin.readline().strip()
# Parse response (could be text or JSON)
answer = None
if line.startswith('{'):
try:
data = json.loads(line)
answer = data.get('answer')
except:
pass
else:
answer = line
if answer == "done":
received += 1
elif answer == "error":
return False
elif answer == "shutdown":
raise SystemExit(0)
else:
time.sleep(0.1)
return True
# Send command
sys.stdout.write("announce route 100.10.0.0/24 next-hop self\n")
sys.stdout.flush()
# Read ACK (new in 4.x, with robust polling)
if not wait_for_ack():
sys.exit(1) # Command failed# Start ExaBGP 4.x
exabgp /etc/exabgp/exabgp.conf
# Verify:
# 1. Configuration loads without errors
# 2. BGP session establishes
# 3. API programs run without hanging
# 4. Routes are announced correctly
# 5. Updates are received correctly (if using JSON)Check logs:
tail -f /var/log/exabgp.logDeployment strategy:
-
Rolling upgrade (if possible):
- Upgrade one ExaBGP instance at a time
- Verify BGP sessions and routes
- Move to next instance
-
Blue/Green deployment:
- Run 4.x alongside 3.x
- Gradually shift traffic to 4.x
- Retire 3.x when stable
-
Maintenance window:
- Schedule downtime
- Upgrade all instances
- Verify before restoring service
Configuration:
- Configuration file loads without errors
- All neighbors defined correctly
- Process blocks use correct syntax
- Families match your requirements
BGP Sessions:
- Sessions establish successfully
- Routes are exchanged
- Attributes are correct (next-hop, AS-PATH, etc.)
- FlowSpec rules work (if using)
API Programs:
- Programs start without errors
- Commands are accepted
- Programs don't hang
- ACK responses handled (if enabled)
- JSON parsing works (if using)
Monitoring:
- Logs show no errors
- Route counts match expectations
- No unexpected BGP session resets
- API programs remain running
Quick rollback:
# Stop ExaBGP 4.x
systemctl stop exabgp
# Reinstall 3.x
pip uninstall exabgp
pip install exabgp==3.4.30 # Last 3.x version
# Restore configuration
cp /etc/exabgp/exabgp.conf.3x.backup /etc/exabgp/exabgp.conf
# Restart
systemctl start exabgpVerify rollback:
exabgp --version
# Should show: ExaBGP 3.4.x
# Check BGP sessions
exabgpcli show neighbor summarySymptom:
ERROR: Could not parse configuration
ERROR: Syntax error at line X
Solution:
- Check process block uses
api { processes [ ... ]; }syntax - Ensure
encoderdirective present in process blocks - Verify neighbor blocks use correct keywords
Symptom:
- API program starts but becomes unresponsive
- ExaBGP stops processing commands
Cause: ACK feature enabled (default in 4.x), but program doesn't read responses
Solution:
Option 1 - Disable ACK:
# Environment variable (works on 4.x and 5.x)
export exabgp.api.ack=false
exabgp /etc/exabgp/exabgp.conf
# OR runtime command (5.x/main only)
# Send: disable-ack or silence-ackOption 2 - Read ACK responses:
# Add ACK handling to your program
import select
ready, _, _ = select.select([sys.stdin], [], [], 5.0)
if ready:
response = sys.stdin.readline().strip()Symptom:
KeyError: 'announce'
KeyError: 'neighbor'
Cause: JSON structure changed in 4.x
Solution: Update JSON parser to use new structure:
# 3.x path
msg['announce']['ipv4 unicast']
# 4.x path
msg['neighbor']['message']['update']['announce']['ipv4 unicast']Symptom:
- API program runs
- No errors in logs
- Routes not appearing on router
Possible causes:
- ACK responses not read - Program hangs, commands not processed
- Family mismatch - Neighbor not configured for correct address family
- Next-hop unreachable - Router can't reach next-hop IP
- BGP session not established - Check session state
Debug:
# Check ExaBGP logs
tail -f /var/log/exabgp.log
# Check BGP session
exabgpcli show neighbor 192.168.1.1
# Check process is running
ps aux | grep announce.py| Feature | 3.x | 4.x |
|---|---|---|
| Configuration Syntax | Old format | New format (breaking) |
| JSON Output | Simple structure | Detailed structure (breaking) |
| ACK Responses | β No | β Yes (default) |
| Python 2 | β Supported | |
| Python 3 | β Fully supported | |
| FlowSpec | Basic | Full RFC 5575 |
| EVPN | β No | β Yes (RFC 7432) |
| BGP-LS | β No | β Yes (RFC 7752) |
| ADD-PATH | β No | β Yes (RFC 7911) |
| Extended Next-Hop | β No | β Yes (RFC 5549) |
| Performance | Good | Better |
| Maintenance | β Deprecated | β Active |
Monitor for 24-48 hours:
- BGP sessions remain stable
- Routes are correct
- No unexpected session resets
- API programs remain running
- No memory leaks
- Logs show no errors
- Document your 4.x configuration
- Update runbooks with 4.x commands
- Train team on 4.x differences
- Update monitoring/alerting for 4.x
Once stable on 4.x:
- Stay on 4.x for production (recommended)
- Consider 5.x/main only if you need bleeding-edge features
- 4.x and 5.x are fully compatible (no breaking changes)
- Version Differences - Complete 3.x vs 4.x comparison
- Configuration Syntax - 4.x configuration reference
- API Overview - 4.x API documentation
- Common Pitfalls - Troubleshooting guide
- GitHub Issues: https://github.com/Exa-Networks/exabgp/issues
- Slack: https://exabgp.slack.com/
- Mailing List: See GitHub repo
- Migration Guide - Main migration entry page
- Breaking Changes Reference - All breaking changes
- 4.x to 5.x Migration - Upgrading to development branch (optional)
π» Ghost written by Claude (Anthropic AI)
π Home
π Getting Started
π§ API
π‘οΈ Use Cases
π Address Families
βοΈ Configuration
π Operations
π Reference
- Architecture
- BGP State Machine
- Communities (RFC)
- Extended Communities
- BGP Ecosystem
- Capabilities (AFI/SAFI)
- RFC Support
π Migration
π Community
π External
- GitHub Repo β
- Slack β
- Issues β
π» Ghost written by Claude (Anthropic AI)