-
Notifications
You must be signed in to change notification settings - Fork 460
From 4.x to 5.x
Complete guide for upgrading from ExaBGP 4.x to 5.0.0
β οΈ BREAKING CHANGES: ExaBGP 5.0.0 introduces breaking changes from 4.xExaBGP 5.0.0 is a major release (November 2024) with 871 commits and significant improvements, but requires careful migration planning.
Key Changes:
- β Python 2 completely removed (Python 3.8+ required)
β οΈ JSON API format changes (AS-PATH, BGP-LS fields)β οΈ Configuration syntax changes (route-refresh, FlowSpec)β οΈ Deprecated features removed (Prefix-SID Type-2/4)- β Major protocol enhancements (SRv6, BGP-MUP, RFC 9072)
- β Security fixes (TOCTOU vulnerability)
- Overview
- Should You Upgrade?
- What Changed
- Breaking Changes
- New Features in 5.0.0
- Migration Steps
- Testing Your Migration
- Rollback Plan
- Common Issues
Release: ExaBGP 5.0.0 (November 2024)
Severity: π΄ HIGH - Breaking changes require careful migration
Timeline: ExaBGP 5.0.0 is the new LTS (Long-Term Support). ExaBGP 4.x enters maintenance mode (critical fixes only, no new features).
Changes: 871 commits, 920 files changed, largest release in ExaBGP history
- β You need SRv6 (Segment Routing over IPv6) support
- β You need BGP-MUP (Mobile User Plane) support
- β You want the TOCTOU security vulnerability fix
- β You need RFC 9072 (Extended Optional Parameters Length)
- β You want latest protocol features and improvements
- β You can test thoroughly before production deployment
- βΈοΈ You cannot test the migration thoroughly
- βΈοΈ You're using JSON API parsers (need updates for AS-PATH format)
- βΈοΈ You're using BGP-LS with JSON (field names changed)
- βΈοΈ You're using Prefix-SID Type-2 or Type-4 (removed in 5.0.0)
- βΈοΈ Your systems use Python < 3.8
Recommendation: Test 5.0.0 in staging first. ExaBGP 4.x remains in maintenance mode for critical fixes.
| Area | Change | Impact |
|---|---|---|
| Python | 3.8+ required (2.x removed) | π΄ CRITICAL - System upgrade needed |
| JSON API | AS-PATH format changed | π΄ HIGH - Parser updates required |
| BGP-LS JSON | Field names changed | π΄ HIGH - Parser updates required |
| CLI |
--test flag β validate subcommand |
π‘ MEDIUM - Scripts must be updated |
| Configuration | route-refresh, FlowSpec syntax | π‘ MEDIUM - Config updates needed |
| Prefix-SID | Type-2/4 removed | π‘ MEDIUM - Only if using these types |
| tcp.once | Replaced by tcp.attempts | π’ LOW - Env var only, internal/debug |
- β SRv6 - Complete Segment Routing over IPv6 support
- β BGP-MUP - Mobile User Plane SAFI (draft-mpmz-bess-mup-safi-02)
- β RFC 9072 - Extended Optional Parameters Length
- β RFC 6514 - MCAST-VPN Route Types 5, 6, 7
- β ACK Runtime Control - disable-ack, enable-ack, silence-ack commands
- β
Neighbor Wildcards -
neighbor * announce ...syntax - β Security Fixes - TOCTOU race condition fixed
- β Official Docker Images - ghcr.io/exa-networks/exabgp:5.0.0
- β Python 2.7 (deprecated but supported)
- β Python 3.6+
- β Python 2.x completely removed
- β Python 3.8+ minimum (3.9+ recommended)
- β Python 3.13 tested and supported
# Check your Python version
python3 --version
# If < 3.8, upgrade Python first
# Ubuntu/Debian:
sudo apt install python3.9
# RHEL/CentOS:
sudo dnf install python39
# macOS:
brew install [email protected]Impact: If you're on Python 2.7 or 3.6/3.7, you must upgrade Python before upgrading ExaBGP.
ExaBGP 4.x (Old Format):
{
"type": "update",
"neighbor": {
"address": {
"local": "192.168.1.1",
"peer": "192.168.1.2"
}
},
"attribute": {
"as-path": [65001, 65002, 65003]
}
}ExaBGP 5.0.0 (New Format):
{
"type": "update",
"neighbor": {
"address": {
"local": "192.168.1.1",
"peer": "192.168.1.2"
}
},
"attribute": {
"as-path": "[ 65001 65002 65003 ]"
}
}Important: The string format encodes AS_PATH segment types using different bracket styles:
| Brackets | Segment Type | Description |
|---|---|---|
( ) |
AS_SEQUENCE | Ordered list of ASNs (most common) |
[ ] |
AS_SET | Unordered set of ASNs (route aggregation) |
{( )} |
CONFED_SEQUENCE | Confederation sequence |
{[ ]} |
CONFED_SET | Confederation set |
Example with multiple segment types:
{
"attribute": {
"as-path": "[ 65001 65002 ] ( 65003 65004 65005 )"
}
}This represents an AS_SET [65001, 65002] followed by an AS_SEQUENCE (65003, 65004, 65005).
Migration Action: Update your JSON parsers to handle AS-PATH as a string instead of an array.
Python Example (Simple - treats all as sequence):
# Old 4.x parser
as_path = data['attribute']['as-path'] # List[int]
for asn in as_path:
print(asn)
# New 5.0.0 parser (simple - extracts all ASNs)
as_path_str = data['attribute']['as-path'] # str: "[ 65001 65002 ]"
as_path = [int(asn) for asn in as_path_str.replace('[', '').replace(']', '').replace('(', '').replace(')', '').replace('{', '').replace('}', '').split()]
for asn in as_path:
print(asn)Python Example (Advanced - preserves segment types):
import re
def parse_as_path(as_path_str):
"""Parse AS_PATH string preserving segment types"""
segments = []
# Match each segment with its bracket type
pattern = r'(\{?\[|\{?\()\s*([\d\s]+)\s*(\]?\}|\)?\})'
for match in re.finditer(pattern, as_path_str):
open_bracket = match.group(1)
asns = [int(asn) for asn in match.group(2).split()]
# Determine segment type
if open_bracket == '[':
segment_type = 'AS_SET'
elif open_bracket == '(':
segment_type = 'AS_SEQUENCE'
elif open_bracket == '{[':
segment_type = 'CONFED_SET'
elif open_bracket == '{(':
segment_type = 'CONFED_SEQUENCE'
segments.append({'type': segment_type, 'asns': asns})
return segments
# Example
as_path_str = "[ 65001 65002 ] ( 65003 65004 )"
segments = parse_as_path(as_path_str)
# Result: [
# {'type': 'AS_SET', 'asns': [65001, 65002]},
# {'type': 'AS_SEQUENCE', 'asns': [65003, 65004]}
# ]ExaBGP 4.x (Old):
{
"bgp-ls": {
"sr_capability_flags": "0x80",
"interface-address": ["192.168.1.1"],
"neighbor-address": ["192.168.1.2"]
}
}ExaBGP 5.0.0 (New):
{
"bgp-ls": {
"sr-capability-flags": "0x80",
"interface-addresses": ["192.168.1.1"],
"neighbor-addresses": ["192.168.1.2"]
}
}Changes:
-
sr_capability_flagsβsr-capability-flags(underscore to hyphen) -
interface-addressβinterface-addresses(singular to plural) -
neighbor-addressβneighbor-addresses(singular to plural) - Extended Communities: Removed
Lprefix from target field
Migration Action: Update BGP-LS JSON parsers to use new field names.
ExaBGP 4.x:
# Old syntax (space separator)
route refreshExaBGP 5.0.0:
# New syntax (hyphenated)
route-refreshMigration Action: Update any scripts or configurations using route refresh to route-refresh.
ExaBGP 4.x:
flow route {
match {
fragment not-a-fragment;
}
then {
discard;
}
}ExaBGP 5.0.0:
flow route {
match {
fragment !is-fragment;
}
then {
discard;
}
}Migration Action: Update FlowSpec configurations:
-
not-a-fragmentβ!is-fragment
tcp.attempts is an internal/debugging option. Not recommended for production use.
ExaBGP 4.x (environment variable):
export exabgp.tcp.once=true # Try to connect only onceExaBGP 5.0.0 (environment variable):
export exabgp.tcp.attempts=1 # Number of connection attempts (0 = infinite)Migration Action: Replace environment variable exabgp.tcp.once=true with exabgp.tcp.attempts=1.
Correct Configuration Methods:
-
Environment variable:
export exabgp.tcp.attempts=1 -
INI configuration:
[exabgp.tcp]section withattempts = 1 -
NOT a neighbor-level option: Do not use
neighbor { tcp { attempts } }syntax
--test flag no longer exists in ExaBGP 5.x.
ExaBGP 4.x:
exabgp --test /etc/exabgp/exabgp.confExaBGP 5.0.0:
exabgp validate /etc/exabgp/exabgp.confMigration Action: Update all scripts and documentation that use exabgp --test to use exabgp validate instead.
Impact: Any automation scripts, CI/CD pipelines, or documentation that references --test will fail and must be updated.
ExaBGP 4.x:
- β Prefix-SID Type-1 (Label-Index)
β οΈ Prefix-SID Type-2 (deprecated)- β Prefix-SID Type-3 (Originator SRGB)
β οΈ Prefix-SID Type-4 (deprecated)
ExaBGP 5.0.0:
- β Prefix-SID Type-1 (Label-Index)
- β Prefix-SID Type-2 REMOVED
- β Prefix-SID Type-3 (Originator SRGB)
- β Prefix-SID Type-4 REMOVED
- β Prefix-SID Type-5 (NEW - SRv6 Locator)
- β Prefix-SID Type-6 (NEW - SRv6 Endpoint Behavior)
Migration Action: If using Type-2 or Type-4, migrate to Type-1/3 or new Type-5/6.
ExaBGP 4.x:
- Hostname (FQDN) capability sent by default
ExaBGP 5.0.0:
- Hostname capability NOT sent by default
- Must explicitly enable if needed
Migration Action: If you rely on hostname capability, explicitly enable it:
neighbor 192.168.1.1 {
capability {
hostname enable; # Explicitly enable
}
}ExaBGP 4.x:
- Syslog facility:
syslog
ExaBGP 5.0.0:
- Syslog facility:
daemon
Migration Action: Update syslog filters if you're parsing ExaBGP logs.
Complete support for SRv6:
# Announce SRv6 route with End.X SID
announce route 2001:db8::/48 next-hop 2001:db8::1 \
prefix-sid srv6-l3-service 2001:db8:100::1 endpoint-behavior End.DT6New SRv6 TLVs:
- β SRv6 Capabilities TLV
- β SRv6 Locator TLV
- β SRv6 End.X SID TLV
- β SRv6 LAN End.X SID TLV
- β SRv6 Endpoint Behavior TLV
- β SRv6 SID NLRI
See: SRv6 and MUP Documentation
Support for draft-mpmz-bess-mup-safi-02:
# Announce MUP route
announce mup isd 100.64.0.1 session-transformed 2001:db8:mup::1Features:
- β MUP SAFI
- β MUP Extended Community
- β Source Address in MUP Type 1 ST Route
- β Improved MUP Type2SessionTransformedRoute encoding
- β RFC 9072 - Extended Optional Parameters Length for BGP OPEN
- β RFC 6514 - MCAST-VPN Route Types 5, 6, 7
- β RFC 8203 - Shutdown communication improvements
- β draft-abraitis-bgp-version-capability - Software version capability
ExaBGP 4.x:
- ACK control via environment variable only
ExaBGP 5.0.0:
- β¨ NEW: Runtime control commands
# Disable ACK for this connection
sys.stdout.write("disable-ack\n")
sys.stdout.flush()
# Re-enable ACK
sys.stdout.write("enable-ack\n")
sys.stdout.flush()
# Temporarily suppress ACK messages
sys.stdout.write("silence-ack\n")
sys.stdout.flush()See: API Overview - ACK Feature
# Announce to ALL neighbors
sys.stdout.write("neighbor * announce route 100.10.0.0/24 next-hop self\n")
sys.stdout.flush()# Multiple concurrent CLI instances
exabgp --pipename cli1 --run /etc/exabgp/exabgp.conf
# JSON output for neighbor info
exabgpcli show neighbor jsonNew options:
# Set IP addresses on physical interfaces
exabgp healthcheck --ip-ifname
# Debounce flapping routes
exabgp healthcheck --debounce 5
# Exact loopback interface label matching
exabgp healthcheck --label-exact-matchFeatures:
- Path ID support for advertised routes
- Per-neighbor route filtering
- Automatic announcement of user-defined loopback IPs
Official Docker images:
# Pull official image
docker pull ghcr.io/exa-networks/exabgp:5.0.0
# Run ExaBGP in container
docker run -d --name exabgp \
-v /etc/exabgp:/etc/exabgp \
ghcr.io/exa-networks/exabgp:5.0.0- β TOCTOU Vulnerability Fixed - Time-of-Check-Time-of-Use race condition in configuration parser
- β Configuration Reload Fix (#1340) - API process state consistency
# Check Python version
python3 --version
# Must be 3.8 or higher
# Recommended: 3.9 or higherIf Python < 3.8, upgrade Python first.
# Backup current config
cp /etc/exabgp/exabgp.conf /etc/exabgp/exabgp.conf.4.x.bak
# Update config syntax if needed:
# - route refresh β route-refresh
# - not-a-fragment β !is-fragment
# - tcp.once β tcp.attempts (env var only, internal/debug)
# Validate configuration (ExaBGP 5.x - BREAKING CHANGE)
exabgp validate /etc/exabgp/exabgp.conf
# Note: --test flag from 4.x no longer exists in 5.x
# 4.x: exabgp --test /etc/exabgp/exabgp.conf
# 5.x: exabgp validate /etc/exabgp/exabgp.confIf using JSON encoder:
# Update AS-PATH parsing
# OLD: as_path = data['attribute']['as-path'] # List[int]
# NEW: as_path_str = data['attribute']['as-path'] # str
# Update BGP-LS field names
# OLD: sr_capability_flags, interface-address, neighbor-address
# NEW: sr-capability-flags, interface-addresses, neighbor-addresses# Search config for removed features
grep -E "Type-2|Type-4" /etc/exabgp/exabgp.conf
# Search for tcp.once
grep "tcp.once" /etc/exabgp/exabgp.confIf found, update to supported alternatives.
# From PyPI
pip3 install --upgrade exabgp==5.0.0
# Or from source
git clone https://github.com/Exa-Networks/exabgp.git
cd exabgp
git checkout 5.0.0
pip3 install .# Start ExaBGP with your updated config
exabgp /etc/exabgp/exabgp.conf
# Monitor logs for errors
tail -f /var/log/exabgp.log
# Verify BGP sessions establish
exabgpcli show neighbor summary# Test your API programs
# - Verify ACK handling still works
# - Verify JSON parsing (if using JSON encoder)
# - Test route announcements/withdrawals
# - Check error handlingOnly after thorough testing:
# Deploy to production
# Monitor closely for first 24 hours
# Have rollback plan ready- Configuration syntax valid:
exabgp validate /etc/exabgp/exabgp.conf(5.x) - No deprecated syntax (route refresh, not-a-fragment)
- No Prefix-SID Type-2 or Type-4 usage
- Hostname capability explicitly enabled if needed
- Updated CLI from
--testflag (4.x) tovalidatesubcommand (5.x)
- JSON parser handles AS-PATH as string
- BGP-LS JSON parser uses new field names
- ACK handling still works
- Route announcements work
- Route withdrawals work
- Error handling works
- BGP sessions establish successfully
- Routes announced correctly
- Health checks work (if using healthcheck module)
- Logs parsed correctly (syslog facility changed to
daemon) - Monitoring/alerting still works
If issues occur, rollback to 4.x:
# 1. Stop ExaBGP 5.0.0
systemctl stop exabgp
# 2. Restore 4.x configuration
cp /etc/exabgp/exabgp.conf.4.x.bak /etc/exabgp/exabgp.conf
# 3. Reinstall 4.x
pip3 install exabgp==4.2.22
# 4. Restart ExaBGP
systemctl start exabgp
# 5. Verify sessions
exabgpcli show neighbor summaryImportant: Keep your 4.x configuration backed up until 5.0.0 is validated in production.
Symptom:
SyntaxError: invalid syntax
Cause: Python < 3.8
Solution:
# Upgrade Python to 3.8+
# Ubuntu/Debian:
sudo apt install python3.9
pip3.9 install exabgp==5.0.0Symptom:
TypeError: 'str' object is not iterableCause: AS-PATH is now string, not array
Solution:
# Update parser
as_path_str = data['attribute']['as-path'] # str: "[ 65001 65002 ]"
as_path = [int(asn) for asn in as_path_str.strip('[]').split()]Symptom:
KeyError: 'sr_capability_flags'Cause: Field names changed (underscore β hyphen, singular β plural)
Solution:
# Update field names
sr_flags = data['bgp-ls']['sr-capability-flags'] # Changed
iface_addrs = data['bgp-ls']['interface-addresses'] # ChangedSymptom:
Error: unknown command 'route refresh'
Cause: Syntax changed to route-refresh
Solution:
# Update config
sed -i 's/route refresh/route-refresh/g' /etc/exabgp/exabgp.confSymptom:
Error: Prefix-SID Type-2 not supported
Cause: Type-2 and Type-4 removed in 5.0.0
Solution: Migrate to Type-1, Type-3, Type-5, or Type-6
| Feature | 4.x | 5.0.0 | Compatible? |
|---|---|---|---|
| Configuration | 4.x syntax | 5.0.0 syntax | |
| Text API | Text encoder | Text encoder | β Compatible |
| JSON API | 4.x JSON | 5.0.0 JSON | β AS-PATH changed |
| Python | 2.7, 3.6+ | 3.8+ only | β Python 2 removed |
| ACK Feature | β (env var only) | β (+ runtime control) | β Compatible |
| FlowSpec | 4.x syntax | 5.0.0 syntax | |
| Prefix-SID | Type 1-4 | Type 1,3,5,6 | β Type 2/4 removed |
| Your Situation | Recommendation | Action |
|---|---|---|
| Python < 3.8 | βΈοΈ Wait | Upgrade Python first |
| Using JSON API | Update parsers before upgrading | |
| Using BGP-LS JSON | Update field names in parsers | |
| Using Text API only | β Safe to upgrade | Test config syntax |
| Need SRv6 | β Upgrade | SRv6 only in 5.0.0 |
| Need BGP-MUP | β Upgrade | BGP-MUP only in 5.0.0 |
| Security-conscious | β Upgrade | TOCTOU fix in 5.0.0 |
| Production-critical | βΈοΈ Test first | Validate in staging |
For New Deployments: Use ExaBGP 5.0.0 (latest stable)
For Existing 4.x Users:
- β Test thoroughly in staging environment
β οΈ Update JSON parsers if using JSON encoderβ οΈ Update configurations for syntax changes- β Upgrade Python to 3.8+ if needed
- β Deploy to production with rollback plan ready
ExaBGP 5.0.0 is now the LTS release. ExaBGP 4.x enters maintenance mode (critical fixes only).
If you're migrating from 4.x and want to go directly to 6.0.0 (main), you can use the bridge mode feature to run your legacy scripts unchanged:
# Run legacy v4 scripts with ExaBGP 6.0.0
exabgp migrate api -f 4 -t main --exec /path/to/legacy-script.py
# Or migrate config with automatic script wrapping
exabgp migrate conf -f 4 -t main --wrap-api old-config.conf | exabgp server -The bridge provides bidirectional transformation:
- Script outputs v4 commands β transformed to v6 for ExaBGP
- ExaBGP sends v6 JSON β transformed to v4 for the script
See: 5.x β 6.x Migration Guide - Bridge Mode for complete details.
- Breaking Changes Reference - Complete breaking changes list
- Migration Guide - Main migration entry page
- 5.x β 6.x Migration - Continue to 6.0.0 with bridge mode
- Installation Guide - Installing 5.0.0
- Version Differences - Detailed comparison
- API Overview - API changes and new features
- SRv6 Documentation - New SRv6 features
π» 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)