Skip to content

From 4.x to 5.x

Thomas Mangin edited this page Mar 25, 2026 · 10 revisions

Migration from ExaBGP 4.x to 5.0.0

Complete guide for upgrading from ExaBGP 4.x to 5.0.0

⚠️ BREAKING CHANGES: ExaBGP 5.0.0 introduces breaking changes from 4.x

ExaBGP 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)

Table of Contents


Overview

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


Should You Upgrade?

✅ YES - Upgrade to 5.0.0 If:

  • ✅ 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

⏸️ WAIT - Stay on 4.x If:

  • ⏸️ 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.


What Changed

Breaking Changes Summary

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; --env flag → --env-file or EXABGP_ENVFILE env var 🟡 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

New Major Features

  • 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

Breaking Changes

Python Version Requirements

ExaBGP 4.x

  • ✅ Python 2.7 (deprecated but supported)
  • ✅ Python 3.6+

ExaBGP 5.0.0

  • Python 2.x completely removed
  • ✅ Python 3.8+ minimum (3.9+ recommended)
  • ✅ Python 3.13 tested and supported

Migration Action

# 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 python@3.9

Impact: If you're on Python 2.7 or 3.6/3.7, you must upgrade Python before upgrading ExaBGP.


JSON API Format Changes

1. AS-PATH Format Changed

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": {
      "0": { "element": "as-sequence", "value": [65001, 65002, 65003] }
    }
  }
}

Important: Each AS-PATH segment is a numbered object with element (segment type) and value (list of ASNs):

Element Segment Type Description
as-sequence AS_SEQUENCE Ordered list of ASNs (most common)
as-set AS_SET Unordered set of ASNs (route aggregation)
as-confed-sequence CONFED_SEQUENCE Confederation sequence
as-confed-set CONFED_SET Confederation set

Example with multiple segment types:

{
  "attribute": {
    "as-path": {
      "0": { "element": "as-set", "value": [65001, 65002] },
      "1": { "element": "as-sequence", "value": [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 structured object instead of an array.

Python Example (Simple - extracts all ASNs):

# 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 from structured format)
as_path_obj = data['attribute']['as-path']  # dict: {"0": {"element": "as-sequence", "value": [65001]}}
for segment in as_path_obj.values():
    for asn in segment['value']:
        print(asn)

Python Example (Advanced - preserves segment types):

def parse_as_path(as_path_obj):
    """Parse AS_PATH structured object preserving segment types"""
    segments = []
    for key in sorted(as_path_obj.keys(), key=int):
        segment = as_path_obj[key]
        segments.append({
            'type': segment['element'],  # "as-sequence", "as-set"
            'asns': segment['value'],    # [65001, 65002, ...]
        })
    return segments

# Example
as_path_obj = {"0": {"element": "as-set", "value": [65001, 65002]},
               "1": {"element": "as-sequence", "value": [65003, 65004]}}
segments = parse_as_path(as_path_obj)
# Result: [
#   {'type': 'as-set', 'asns': [65001, 65002]},
#   {'type': 'as-sequence', 'asns': [65003, 65004]}
# ]

2. BGP-LS Field Name Changes

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_flagssr-capability-flags (underscore to hyphen)
  • interface-addressinterface-addresses (singular to plural)
  • neighbor-addressneighbor-addresses (singular to plural)
  • Extended Communities: Removed L prefix from target field

Migration Action: Update BGP-LS JSON parsers to use new field names.


Configuration Syntax Changes

1. Route Refresh Command

ExaBGP 4.x:

# Old syntax (space separator)
route refresh

ExaBGP 5.0.0:

# New syntax (hyphenated)
route-refresh

Migration Action: Update any scripts or configurations using route refresh to route-refresh.

2. FlowSpec Fragment Syntax

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

3. TCP Connection Attempts

⚠️ Note: 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 once

ExaBGP 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 with attempts = 1
  • NOT a neighbor-level option: Do not use neighbor { tcp { attempts } } syntax

CLI Breaking Changes

Configuration Validation Command Changed

⚠️ BREAKING: The --test flag no longer exists in ExaBGP 5.x+.

ExaBGP 4.x (old):

# No longer works in 5.x+
exabgp --test /etc/exabgp/exabgp.conf

ExaBGP 5.x (new):

exabgp validate /etc/exabgp/exabgp.conf

ExaBGP 6.x (new):

exabgp configuration validate /etc/exabgp/exabgp.conf

Migration Action: Update all scripts and automation that use --test to use exabgp validate (5.x) or exabgp configuration validate (6.x).

Impact: Any automation scripts, CI/CD pipelines, or documentation that references --test will fail and must be updated.

Environment File Override Changed

⚠️ BREAKING: The --env / -e flags no longer exist in ExaBGP 5.x+.

ExaBGP 4.x (old):

# No longer works in 5.x+
exabgp --env=/etc/exabgp/exabgp.env /etc/exabgp/exabgp.conf

ExaBGP 5.x (new - requires 5.0.6+):

# Using CLI flag
exabgp --env-file /etc/exabgp/exabgp.env server /etc/exabgp/exabgp.conf

# Using environment variable (works with any version)
EXABGP_ENVFILE=/etc/exabgp/exabgp.env exabgp /etc/exabgp/exabgp.conf

Migration Action: Replace --env=<path> with --env-file <path> or set EXABGP_ENVFILE=<path>.


Deprecated Features Removed

1. Prefix-SID Type-2 and Type-4 Removed

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.

2. Hostname Capability Auto-Send

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
    }
}

3. Syslog Facility Changed

ExaBGP 4.x:

  • Syslog facility: syslog

ExaBGP 5.0.0:

  • Syslog facility: daemon

Migration Action: Update syslog filters if you're parsing ExaBGP logs.


New Features in 5.0.0

Protocol Extensions

SRv6 (Segment Routing over IPv6)

Complete support for SRv6:

# Announce SRv6 route with BGP Prefix SID (endpoint behavior as hex integer)
announce ipv4 mup mup-isd 10.0.1.0/24 rd 100:100 next-hop 2001::1 \
    extended-community [target:10:10] \
    bgp-prefix-sid-srv6 ( l3-service 2001:db8:1:1:: 0x48 [64,24,16,0,0,0] )

New 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

BGP-MUP (Mobile User Plane)

Support for draft-mpmz-bess-mup-safi-02:

# Announce MUP InterworkSegmentDiscovery route
announce ipv4 mup mup-isd 10.0.1.0/24 rd 100:100 next-hop 2001::1 \
    extended-community [target:10:10]

# Announce MUP Type1SessionTransformed route
announce ipv4 mup mup-t1st 192.168.0.1/32 rd 100:100 teid 12345 qfi 9 \
    endpoint 10.0.0.1 next-hop 10.0.0.2 extended-community [target:10:10]

MUP Route Types:

  • mup-isd - InterworkSegmentDiscoveryRoute
  • mup-dsd - DirectSegmentDiscoveryRoute
  • mup-t1st - Type1SessionTransformedRoute
  • mup-t2st - Type2SessionTransformedRoute

Features:

  • ✅ MUP SAFI (ipv4 mup, ipv6 mup)
  • ✅ MUP Extended Community
  • ✅ Source Address in MUP Type 1 ST Route
  • ✅ Improved MUP Type2SessionTransformedRoute encoding

RFC Implementations

  • 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

API Enhancements

ACK Runtime Control (NEW)

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

Neighbor Wildcards (NEW)

# Announce to ALL neighbors
sys.stdout.write("neighbor * announce route 100.10.0.0/24 next-hop self\n")
sys.stdout.flush()

CLI Improvements

# Multiple concurrent CLI instances
exabgp --pipename cli1 --run /etc/exabgp/exabgp.conf

# JSON output for neighbor info
exabgp-cli show neighbor json

Healthcheck Enhancements

New options:

# Set IP addresses on physical interfaces
exabgp healthcheck --ip-ifname

# Debounce flapping routes
exabgp healthcheck --debounce

# Exact loopback interface label matching
exabgp healthcheck --label-exact-match

Features:

  • Path ID support for advertised routes
  • Per-neighbor route filtering
  • Automatic announcement of user-defined loopback IPs

Container Support

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

See: Docker Deployment Guide

Security Fixes

  • TOCTOU Vulnerability Fixed - Time-of-Check-Time-of-Use race condition in configuration parser
  • Configuration Reload Fix (#1340) - API process state consistency

Migration Steps

Step 1: Verify Python Version

# Check Python version
python3 --version

# Must be 3.8 or higher
# Recommended: 3.9 or higher

If Python < 3.8, upgrade Python first.

Step 2: Test Configuration Syntax

# 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.conf
# 6.x:  exabgp configuration validate /etc/exabgp/exabgp.conf

Step 3: Update JSON API Parsers

If using JSON encoder:

# Update AS-PATH parsing
# OLD: as_path = data['attribute']['as-path']  # List[int]
# NEW: as_path_obj = data['attribute']['as-path']  # dict with element/value

# Update BGP-LS field names
# OLD: sr_capability_flags, interface-address, neighbor-address
# NEW: sr-capability-flags, interface-addresses, neighbor-addresses

Step 4: Check for Deprecated Features

# 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.conf

If found, update to supported alternatives.

Step 5: Install ExaBGP 5.0.0

# From PyPI
pip 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
pip install .

Step 6: Test in Staging

# 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
exabgp-cli show neighbor summary

Step 7: Validate API Programs

# Test your API programs
# - Verify ACK handling still works
# - Verify JSON parsing (if using JSON encoder)
# - Test route announcements/withdrawals
# - Check error handling

Step 8: 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 (5.x) or exabgp configuration validate (6.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 --test flag (4.x) to validate subcommand (5.x)

API Testing Checklist

  • 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

Integration Testing Checklist

  • 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

Rollback Plan

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
pip install exabgp==4.2.22

# 4. Restart ExaBGP
systemctl start exabgp

# 5. Verify sessions
exabgp-cli show neighbor summary

Important: Keep your 4.x configuration backed up until 5.0.0 is validated in production.


Common Issues

Issue 1: Python Version Too Old

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.0

Issue 2: JSON Parser Fails on AS-PATH

Symptom:

TypeError: 'int' object is not subscriptable

Cause: AS-PATH is now a structured object with segment types, not a flat array

Solution:

# Update parser
as_path_obj = data['attribute']['as-path']  # dict: {"0": {"element": "as-sequence", "value": [65001]}}
as_path = [asn for seg in as_path_obj.values() for asn in seg['value']]

Issue 3: BGP-LS JSON Fields Missing

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']  # Changed

Issue 4: Configuration Syntax Errors

Symptom:

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.conf

Issue 5: Prefix-SID Type-2/4 Errors

Symptom:

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


Version Compatibility Matrix

Feature 4.x 5.0.0 Compatible?
Configuration 4.x syntax 5.0.0 syntax ⚠️ Mostly (minor changes)
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 ⚠️ Fragment syntax changed
Prefix-SID Type 1-4 Type 1,3,5,6 ❌ Type 2/4 removed

Upgrade Decision Matrix

Your Situation Recommendation Action
Python < 3.8 ⏸️ Wait Upgrade Python first
Using JSON API ⚠️ Test carefully Update parsers before upgrading
Using BGP-LS JSON ⚠️ Test carefully 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

Recommendation

For New Deployments: Use ExaBGP 5.0.0 (latest stable)

For Existing 4.x Users:

  1. Test thoroughly in staging environment
  2. ⚠️ Update JSON parsers if using JSON encoder
  3. ⚠️ Update configurations for syntax changes
  4. Upgrade Python to 3.8+ if needed
  5. 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).


Migrating Directly to 6.0.0

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.


See Also


Clone this wiki locally