-
Notifications
You must be signed in to change notification settings - Fork 459
ADD PATH
ADD-PATH is a BGP capability (RFC 7911) that allows a BGP speaker to advertise multiple paths for the same NLRI (Network Layer Reachability Information) without the need for additional BGP sessions. ExaBGP provides full ADD-PATH support for most address families, enabling path diversity, multipath load balancing, and improved convergence in BGP networks.
- What is ADD-PATH?
- How ADD-PATH Works
- ExaBGP ADD-PATH Capabilities
- Why Use ADD-PATH?
- Configuration
- API Usage
- Use Cases
- Path Identifiers
- Monitoring and Verification
- Limitations and Considerations
- Common Errors and Solutions
- See Also
- References
ADD-PATH (defined in RFC 7911) enables BGP to advertise multiple paths for the same network prefix to a single peer. Without ADD-PATH, BGP can only send one "best path" per prefix to each neighbor, even if multiple viable paths exist.
Traditional BGP behavior:
Route Reflector (RR)
β
ββ Receives 3 paths for 10.0.0.0/8:
β 1. via AS 100 (best path)
β 2. via AS 200
β 3. via AS 300
β
ββ Advertises ONLY best path to clients:
βββΆ Client 1: 10.0.0.0/8 via AS 100
βββΆ Client 2: 10.0.0.0/8 via AS 100
βββΆ Client 3: 10.0.0.0/8 via AS 100
Result: Clients lose path diversity!
Problems:
- Path diversity loss: Clients only see RR's best path, not alternatives
- Suboptimal routing: Client's best path may differ from RR's best path
- BGP wedgies: Persistent routing loops in certain topologies
- Slow convergence: Only one path available; failure requires full re-convergence
With ADD-PATH enabled:
Route Reflector (RR) with ADD-PATH
β
ββ Receives 3 paths for 10.0.0.0/8:
β 1. via AS 100 (Path ID: 1)
β 2. via AS 200 (Path ID: 2)
β 3. via AS 300 (Path ID: 3)
β
ββ Advertises ALL paths to clients:
βββΆ Client 1: 10.0.0.0/8 via AS 100 (ID:1)
10.0.0.0/8 via AS 200 (ID:2)
10.0.0.0/8 via AS 300 (ID:3)
Result: Clients have full path visibility and diversity!
Benefits:
- β Path diversity preserved: Clients see multiple paths
- β Optimal routing: Each client selects its own best path
- β Faster convergence: Backup paths pre-installed
- β Load balancing: Multipath support for traffic engineering
ADD-PATH extends BGP UPDATE messages to include a Path Identifier for each NLRI:
Traditional BGP UPDATE:
βββββββββββββββββββββββββββββββββββ
β Prefix: 10.0.0.0/8 β
β Next-hop: 192.168.1.1 β
β AS Path: 100 200 β
βββββββββββββββββββββββββββββββββββ
ADD-PATH BGP UPDATE:
βββββββββββββββββββββββββββββββββββ
β Path ID: 1 β β NEW: Unique identifier
β Prefix: 10.0.0.0/8 β
β Next-hop: 192.168.1.1 β
β AS Path: 100 200 β
βββββββββββββββββββββββββββββββββββ
Multiple paths for same prefix:
βββββββββββββββββββββββββββββββββββ
β Path ID: 1 β
β Prefix: 10.0.0.0/8 β
β Next-hop: 192.168.1.1 β
β AS Path: 100 200 β
βββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββ
β Path ID: 2 β
β Prefix: 10.0.0.0/8 β
β Next-hop: 192.168.1.2 β
β AS Path: 100 300 β
βββββββββββββββββββββββββββββββββββ
Key Points:
- Path ID: 32-bit unsigned integer uniquely identifying the path
- Per-prefix uniqueness: Path IDs must be unique per prefix, per peer
- Opaque value: No semantic meaning; just an identifier
- Sender-assigned: Advertising router assigns Path IDs
[Session Establishment with ADD-PATH]
ExaBGP BGP Peer
β β
βββββ OPEN ββββββββββββββββββββββββββββββΆβ
β Capabilities: β
β - ADD-PATH: β
β AFI: IPv4 (1) β
β SAFI: Unicast (1) β
β Send/Receive: Both (3) β
β β
ββββββ OPEN ββββββββββββββββββββββββββββββ
β Capabilities: β
β - ADD-PATH: β
β AFI: IPv4 (1) β
β SAFI: Unicast (1) β
β Send/Receive: Both (3) β
β β
βββββ KEEPALIVE βββββββββββββββββββββββββΆβ
ββββββ KEEPALIVE βββββββββββββββββββββββββ
β β
β ADD-PATH negotiated for IPv4 unicast β
β Both peers can send/receive multiple β
β paths per prefix β
Send/Receive Values:
- 1: Receive only
- 2: Send only
- 3: Send and Receive (both)
Per-AFI/SAFI: ADD-PATH is negotiated separately for each address family.
ExaBGP provides full RFC 7911 ADD-PATH implementation:
β Send/Receive Support:
- Send multiple paths per prefix
- Receive multiple paths per prefix
- Send+Receive mode (bidirectional)
β Supported Address Families:
- β IPv4 Unicast
- β IPv4 Multicast
- β IPv6 Unicast
- β IPv6 Multicast
- β VPNv4 (L3VPN)
- β VPNv6 (L3VPN)
- β IPv4 FlowSpec
- β IPv6 FlowSpec
- β VPLS
β Not Yet Supported:
- β EVPN (planned)
- β MVPN
- β Route Target Constraint (RTC)
- β BGP-LS
β Path Identifier Management:
- Automatic Path ID assignment
- Manual Path ID specification via API
- Per-prefix Path ID tracking
β API Integration:
- Advertise routes with Path IDs
- Receive routes with Path IDs
- Withdraw specific paths by ID
Implementation:
src/exabgp/bgp/message/open/capability/addpath.py-
src/exabgp/bgp/neighbor.py(configuration) - NLRI encoding/decoding with Path IDs
RFC Compliance: RFC 7911 fully implemented
| Benefit | Without ADD-PATH | With ADD-PATH |
|---|---|---|
| Path Diversity | Only best path visible | All paths visible |
| Routing Optimality | RR's best path only | Each router picks best |
| Convergence | Single path; slow failover | Multiple paths; fast failover |
| Load Balancing | Limited (ECMP same AS-path) | Flexible (multiple AS-paths) |
| BGP Wedgies | Possible | Prevented |
| Path Exploration | Limited | Full topology visibility |
- Route Reflector deployments: Preserve path diversity to clients
- Multipath load balancing: Advertise multiple equal-cost paths
- Fast convergence: Pre-install backup paths for sub-second failover
- Anycast services: Advertise from multiple locations simultaneously
- Path diversity for resilience: Multiple independent paths for redundancy
Enable ADD-PATH for IPv4 unicast (send and receive):
neighbor 192.168.1.1 {
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
capability {
add-path send/receive; # Enable ADD-PATH bidirectionally
}
family {
ipv4 unicast;
}
api {
processes [ announce-paths ];
}
}
process announce-paths {
run python3 /etc/exabgp/api/addpath.py;
encoder text;
}Notes:
-
send/receive: Bidirectional ADD-PATH (most common) - ADD-PATH applies to all configured families
Only send multiple paths (don't receive):
neighbor 192.168.1.1 {
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
capability {
add-path send; # Send multiple paths only
}
family {
ipv4 unicast;
}
}When to use:
- ExaBGP advertises multiple paths (e.g., Route Reflector)
- Peer only needs to receive paths, not send multiple
Only receive multiple paths (don't send):
neighbor 192.168.1.1 {
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
capability {
add-path receive; # Receive multiple paths only
}
family {
ipv4 unicast;
}
}When to use:
- ExaBGP receives multiple paths from peer
- ExaBGP only sends single best path
ADD-PATH for IPv4 and IPv6:
neighbor 2001:db8::1 {
router-id 192.168.1.2;
local-address 2001:db8::2;
local-as 65001;
peer-as 65000;
capability {
add-path send/receive;
}
family {
ipv4 unicast;
ipv6 unicast;
ipv4 flow; # FlowSpec also supports ADD-PATH
}
}Notes:
- ADD-PATH negotiated per AFI/SAFI
- Not all families support ADD-PATH (see limitations)
Explicitly disable ADD-PATH:
neighbor 192.168.1.1 {
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
# No add-path directive = disabled (default)
family {
ipv4 unicast;
}
}Announce multiple paths for the same prefix:
#!/usr/bin/env python3
"""Advertise multiple paths using ADD-PATH"""
import sys
def announce_multiple_paths():
"""Announce 10.0.0.0/8 via two different next-hops"""
# Path 1: via 192.168.1.10 (Path ID: 1)
route1 = "announce route 10.0.0.0/8 next-hop 192.168.1.10 path-information 1"
sys.stdout.write(f"{route1}\n")
sys.stdout.flush()
# Path 2: via 192.168.1.20 (Path ID: 2)
route2 = "announce route 10.0.0.0/8 next-hop 192.168.1.20 path-information 2"
sys.stdout.write(f"{route2}\n")
sys.stdout.flush()
print("Announced 2 paths for 10.0.0.0/8", file=sys.stderr)
announce_multiple_paths()Syntax:
announce route <prefix> next-hop <ip> path-information <path-id>
Key Points:
-
path-information <id>: Specifies the Path ID (32-bit unsigned integer) - Must be unique per prefix
- If omitted, ExaBGP auto-assigns Path ID
Withdraw a specific path by Path ID:
#!/usr/bin/env python3
"""Withdraw specific path using ADD-PATH"""
import sys
def withdraw_specific_path():
"""Withdraw Path ID 1 for 10.0.0.0/8, keep Path ID 2"""
# Withdraw only path with ID 1
withdraw = "withdraw route 10.0.0.0/8 path-information 1"
sys.stdout.write(f"{withdraw}\n")
sys.stdout.flush()
print("Withdrew path ID 1 (path ID 2 remains active)", file=sys.stderr)
withdraw_specific_path()Without Path ID: Withdraws all paths for the prefix.
Advertise same prefix from multiple locations:
#!/usr/bin/env python3
"""Anycast service with ADD-PATH"""
import sys
def announce_anycast_paths():
"""Announce 1.1.1.1/32 from 3 data centers"""
paths = [
("1.1.1.1/32", "10.0.1.1", 1, "DC1"),
("1.1.1.1/32", "10.0.2.1", 2, "DC2"),
("1.1.1.1/32", "10.0.3.1", 3, "DC3"),
]
for prefix, nexthop, path_id, dc in paths:
route = f"announce route {prefix} next-hop {nexthop} path-information {path_id} community 65001:{path_id}"
sys.stdout.write(f"{route}\n")
sys.stdout.flush()
print(f"Announced {prefix} from {dc} (Path ID {path_id})", file=sys.stderr)
announce_anycast_paths()Process multiple received paths:
#!/usr/bin/env python3
"""Receive and process multiple paths via ADD-PATH"""
import sys
import json
def process_received_paths():
"""Process incoming routes with Path IDs"""
while True:
line = sys.stdin.readline().strip()
if not line:
break
try:
msg = json.loads(line)
if msg.get('type') == 'update':
if 'announce' in msg:
for afi_safi, announcements in msg['announce'].items():
for nexthop, prefixes in announcements.items():
for prefix_data in prefixes:
prefix = prefix_data.get('nlri')
path_id = prefix_data.get('path-id')
print(f"Received: {prefix} via {nexthop} (Path ID: {path_id})", file=sys.stderr)
except json.JSONDecodeError:
pass
process_received_paths()Use multiple paths for load balancing:
#!/usr/bin/env python3
"""ECMP load balancing with ADD-PATH"""
import sys
def announce_ecmp_paths():
"""Announce 4 equal-cost paths for load balancing"""
prefix = "192.168.0.0/16"
next_hops = [
"10.0.1.1",
"10.0.1.2",
"10.0.1.3",
"10.0.1.4",
]
for idx, nexthop in enumerate(next_hops, start=1):
route = (
f"announce route {prefix} "
f"next-hop {nexthop} "
f"path-information {idx} "
f"med 100 " # Same MED for ECMP
f"as-path [ 65001 ]"
)
sys.stdout.write(f"{route}\n")
sys.stdout.flush()
print(f"Announced {len(next_hops)} ECMP paths for {prefix}", file=sys.stderr)
announce_ecmp_paths()Scenario: Preserve path diversity in Route Reflector deployments.
Problem: Traditional RR only advertises best path to clients, hiding alternative paths.
Solution: Enable ADD-PATH on RR to advertise all paths to clients.
Architecture:
Internet
β
βββββββββΌββββββββ
β β β
PE1 PE2 PE3
β β β
βββββββββΌββββββββ
β
Route Reflector
(ExaBGP + ADD-PATH)
β
βββββββββΌββββββββ
β β β
Client1 Client2 Client3
Without ADD-PATH: Clients see only RR's best path
With ADD-PATH: Clients see paths from PE1, PE2, PE3
Configuration (Route Reflector):
# RR advertises multiple paths to clients
neighbor 192.168.1.10 { # Client 1
router-id 192.168.1.254;
local-address 192.168.1.254;
local-as 65001;
peer-as 65001; # iBGP
capability {
add-path send/receive;
}
family {
ipv4 unicast;
}
}Benefits:
- Clients have full path visibility
- Each client selects optimal path independently
- No BGP wedgies
- Faster convergence (backup paths pre-installed)
Scenario: Advertise multiple paths for ECMP load balancing.
Example:
#!/usr/bin/env python3
"""Load balancing with ADD-PATH"""
import sys
def setup_load_balancing():
"""Advertise prefix via 4 next-hops for ECMP"""
prefix = "10.0.0.0/8"
uplinks = [
("10.1.1.1", 1, "ISP-1"),
("10.1.1.2", 2, "ISP-2"),
("10.1.1.3", 3, "ISP-3"),
("10.1.1.4", 4, "ISP-4"),
]
for nexthop, path_id, isp in uplinks:
route = (
f"announce route {prefix} "
f"next-hop {nexthop} "
f"path-information {path_id} "
f"as-path [ 65001 ]"
)
sys.stdout.write(f"{route}\n")
sys.stdout.flush()
print(f"Path {path_id}: {prefix} via {isp} ({nexthop})", file=sys.stderr)
setup_load_balancing()Result: Traffic distributed across 4 uplinks using ECMP.
Scenario: Pre-install backup paths for sub-second convergence.
Architecture:
Primary Path: ExaBGP βββΆ Router A βββΆ Destination
Backup Path: ExaBGP βββΆ Router B βββΆ Destination
ADD-PATH: Both paths advertised simultaneously
Router pre-installs both, uses primary, switches to backup instantly on failure
Example:
#!/usr/bin/env python3
"""Primary + backup paths with ADD-PATH"""
import sys
import time
import subprocess
def check_primary_health():
"""Check if primary path is healthy"""
try:
result = subprocess.run(
["ping", "-c", "1", "-W", "1", "10.0.1.1"],
capture_output=True
)
return result.returncode == 0
except:
return False
def announce_paths_with_failover():
"""Announce primary + backup, adjust weights based on health"""
primary_healthy = check_primary_health()
if primary_healthy:
# Primary: lower MED (preferred)
primary = "announce route 192.168.0.0/16 next-hop 10.0.1.1 path-information 1 med 50"
backup = "announce route 192.168.0.0/16 next-hop 10.0.2.1 path-information 2 med 100"
else:
# Primary failed: set higher MED
primary = "announce route 192.168.0.0/16 next-hop 10.0.1.1 path-information 1 med 200"
backup = "announce route 192.168.0.0/16 next-hop 10.0.2.1 path-information 2 med 50"
sys.stdout.write(f"{primary}\n")
sys.stdout.write(f"{backup}\n")
sys.stdout.flush()
# Monitor and adjust
while True:
announce_paths_with_failover()
time.sleep(10)Scenario: Advertise anycast IP from multiple PoPs.
Example:
#!/usr/bin/env python3
"""Anycast DNS with ADD-PATH"""
import sys
def announce_anycast_dns():
"""Announce 8.8.8.8 from 3 geographic locations"""
anycast_ip = "8.8.8.8/32"
pops = [
("10.1.1.1", 1, "US-East", 65001),
("10.2.1.1", 2, "EU-West", 65002),
("10.3.1.1", 3, "APAC", 65003),
]
for nexthop, path_id, location, asn in pops:
route = (
f"announce route {anycast_ip} "
f"next-hop {nexthop} "
f"path-information {path_id} "
f"as-path [ {asn} ] "
f"community 65000:{path_id}"
)
sys.stdout.write(f"{route}\n")
sys.stdout.flush()
print(f"Anycast {anycast_ip} from {location} (Path {path_id})", file=sys.stderr)
announce_anycast_dns()Result: All 3 paths advertised; routers select nearest PoP.
Automatic assignment (ExaBGP assigns IDs):
# No path-information specified - ExaBGP auto-assigns
sys.stdout.write("announce route 10.0.0.0/8 next-hop 192.168.1.1\n")Manual assignment (explicit Path ID):
# Manually specify Path ID
sys.stdout.write("announce route 10.0.0.0/8 next-hop 192.168.1.1 path-information 42\n")Per RFC 7911:
- 32-bit unsigned integer (0 to 4,294,967,295)
- Unique per prefix, per peer (not globally unique)
- Opaque value (no semantic meaning)
- Sender-assigned (advertising router controls)
Best Practices:
- Use sequential IDs (1, 2, 3, ...) for simplicity
- Use meaningful IDs for debugging (e.g., PoP number)
- Avoid Path ID 0 (some implementations treat as invalid)
- Document Path ID scheme
Path IDs must remain stable for a given path:
- Don't change Path ID unless path changes
- Consistent IDs across restarts (if possible)
- Withdraw old ID before announcing new ID for same prefix
Monitor received paths with Path IDs:
#!/usr/bin/env python3
"""Monitor ADD-PATH routes"""
import sys
import json
paths_per_prefix = {}
while True:
line = sys.stdin.readline().strip()
if not line:
break
try:
msg = json.loads(line)
if msg.get('type') == 'update':
# Process announcements
if 'announce' in msg:
for afi_safi, announcements in msg['announce'].items():
for nexthop, prefixes in announcements.items():
for prefix_data in prefixes:
prefix = prefix_data.get('nlri')
path_id = prefix_data.get('path-id', 'N/A')
if prefix not in paths_per_prefix:
paths_per_prefix[prefix] = []
paths_per_prefix[prefix].append(path_id)
print(f"ADD-PATH: {prefix} via {nexthop} (ID: {path_id})", file=sys.stderr)
# Process withdrawals
if 'withdraw' in msg:
for afi_safi, withdrawals in msg['withdraw'].items():
for prefix_data in withdrawals:
prefix = prefix_data.get('nlri')
path_id = prefix_data.get('path-id', 'N/A')
print(f"WITHDRAW: {prefix} Path ID {path_id}", file=sys.stderr)
# Periodically report paths per prefix
for prefix, path_ids in paths_per_prefix.items():
if len(path_ids) > 1:
print(f"Multi-path: {prefix} has {len(path_ids)} paths: {path_ids}", file=sys.stderr)
except json.JSONDecodeError:
passEnable ADD-PATH logging:
[exabgp.log]
level = INFO
packets = true
message = trueLog output:
INFO Peer 192.168.1.1: ADD-PATH capability negotiated (send/receive)
INFO Peer 192.168.1.1: Received UPDATE with Path ID 1 for 10.0.0.0/8
INFO Peer 192.168.1.1: Received UPDATE with Path ID 2 for 10.0.0.0/8
INFO Peer 192.168.1.1: 2 paths for 10.0.0.0/8
Verify ADD-PATH negotiation:
# Check capability in logs
grep -i "add-path" /var/log/exabgp.log
# Verify Path IDs in UPDATE messages
grep "Path ID" /var/log/exabgp.logTest multiple path advertisement:
#!/usr/bin/env python3
import sys
# Announce 2 paths
sys.stdout.write("announce route 10.0.0.0/8 next-hop 192.168.1.1 path-information 1\n")
sys.stdout.write("announce route 10.0.0.0/8 next-hop 192.168.1.2 path-information 2\n")
sys.stdout.flush()
# Verify peer receives both paths-
Address Family Support
- β EVPN: Not yet supported (planned)
- β MVPN: Not yet supported
- β BGP-LS: Not yet supported
- β All other families supported
-
Path ID Management
- User must track Path IDs in API processes
- No automatic Path ID deduplication
- Path ID scope limited to per-prefix, per-peer
-
Memory Overhead
- Multiple paths stored per prefix
- More routes in RIB (N paths Γ M prefixes)
- Consider memory capacity
-
CPU Overhead
- More UPDATE messages to process
- Path selection runs for each path
- Consider CPU capacity for high path counts
-
Peer Support
- Both peers must negotiate ADD-PATH capability
- Verify vendor support and limitations
- Test before production deployment
-
Path Explosion
- Large networks: many paths per prefix possible
- Limit paths advertised (e.g., best N paths)
- Monitor path counts
β Do:
- Start with send/receive mode for flexibility
- Use meaningful Path IDs for debugging
- Monitor path counts per prefix
- Test with small scale before full deployment
- Document Path ID assignment scheme
β Don't:
- Advertise unlimited paths (memory/CPU risk)
- Change Path IDs unnecessarily
- Assume all vendors support all features
- Deploy without testing peer behavior
Symptom: ADD-PATH configured but not negotiated.
Logs:
WARNING Peer 192.168.1.1: ADD-PATH capability not negotiated
Causes:
- Peer does not support ADD-PATH (RFC 7911)
- Peer has ADD-PATH disabled
- AFI/SAFI mismatch
Solutions:
# Verify ExaBGP configuration
neighbor 192.168.1.1 {
capability {
add-path send/receive; # Ensure enabled
}
family {
ipv4 unicast; # Must match peer
}
}
# Check peer configuration
# Cisco:
router bgp 65000
neighbor 192.168.1.2 activate
address-family ipv4 unicast
neighbor 192.168.1.2 advertise additional-paths all
# Juniper:
protocols {
bgp {
group peers {
family inet {
unicast {
add-path {
receive;
send {
path-count 6;
}
}
}
}
}
}
}Symptom: Same Path ID used for different paths to same prefix.
Causes:
- API process bug
- Path ID not updated on path change
- Race condition in Path ID assignment
Solutions:
#!/usr/bin/env python3
"""Properly manage Path IDs"""
import sys
class PathManager:
def __init__(self):
self.next_path_id = 1
self.prefix_paths = {} # prefix -> {nexthop: path_id}
def announce_path(self, prefix, nexthop):
"""Announce path with unique Path ID"""
if prefix not in self.prefix_paths:
self.prefix_paths[prefix] = {}
if nexthop in self.prefix_paths[prefix]:
# Re-use existing Path ID
path_id = self.prefix_paths[prefix][nexthop]
else:
# Assign new Path ID
path_id = self.next_path_id
self.next_path_id += 1
self.prefix_paths[prefix][nexthop] = path_id
route = f"announce route {prefix} next-hop {nexthop} path-information {path_id}"
sys.stdout.write(f"{route}\n")
sys.stdout.flush()
return path_id
def withdraw_path(self, prefix, nexthop):
"""Withdraw specific path"""
if prefix in self.prefix_paths and nexthop in self.prefix_paths[prefix]:
path_id = self.prefix_paths[prefix][nexthop]
withdraw = f"withdraw route {prefix} path-information {path_id}"
sys.stdout.write(f"{withdraw}\n")
sys.stdout.flush()
del self.prefix_paths[prefix][nexthop]
# Use PathManager to avoid duplicate Path IDs
pm = PathManager()
pm.announce_path("10.0.0.0/8", "192.168.1.1")
pm.announce_path("10.0.0.0/8", "192.168.1.2")Symptom: Withdrawn path still appears at peer.
Causes:
- Path ID not specified in withdraw
- Incorrect Path ID
- Peer issue
Solutions:
#!/usr/bin/env python3
"""Correct path withdrawal with Path ID"""
import sys
# INCORRECT: Withdraws all paths for prefix
sys.stdout.write("withdraw route 10.0.0.0/8\n")
sys.stdout.flush()
# CORRECT: Withdraws specific path by ID
sys.stdout.write("withdraw route 10.0.0.0/8 path-information 1\n")
sys.stdout.flush()
# Verify Path ID matches announced path
# Announce: path-information 42
# Withdraw: path-information 42 (must match!)Symptom: Memory or CPU exhaustion from too many paths.
Causes:
- No limit on paths per prefix
- Path explosion in large network
- API process announcing excessive paths
Solutions:
#!/usr/bin/env python3
"""Limit paths per prefix"""
import sys
class LimitedPathManager:
MAX_PATHS_PER_PREFIX = 4 # Limit to 4 paths
def __init__(self):
self.prefix_paths = {} # prefix -> [(nexthop, path_id), ...]
def announce_path(self, prefix, nexthop, path_id):
"""Announce path with limit enforcement"""
if prefix not in self.prefix_paths:
self.prefix_paths[prefix] = []
# Check limit
if len(self.prefix_paths[prefix]) >= self.MAX_PATHS_PER_PREFIX:
# Remove oldest path
old_nexthop, old_path_id = self.prefix_paths[prefix].pop(0)
withdraw = f"withdraw route {prefix} path-information {old_path_id}"
sys.stdout.write(f"{withdraw}\n")
sys.stdout.flush()
print(f"Removed oldest path (ID {old_path_id}) due to limit", file=sys.stderr)
# Announce new path
self.prefix_paths[prefix].append((nexthop, path_id))
route = f"announce route {prefix} next-hop {nexthop} path-information {path_id}"
sys.stdout.write(f"{route}\n")
sys.stdout.flush()
# Enforce path limit
lpm = LimitedPathManager()- Route Refresh - Route refresh capability
- Graceful Restart - Graceful restart with multiple paths
- API Commands - API command reference
- Configuration Syntax - Configuration guide
- Anycast Management - Anycast with ADD-PATH
- RFC 7911: Advertisement of Multiple Paths in BGP (ADD-PATH)
- RFC 4271: BGP-4 base specification
- RFC 4456: BGP Route Reflection
- RFC Support - All implemented RFCs
- RFC Information - Detailed RFC implementation list
-
Source Code:
src/exabgp/bgp/message/open/capability/addpath.py - Capability Type: 69 (ADD-PATH)
- ExaBGP Version: 4.x, 5.x/main
π» 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)