-
Notifications
You must be signed in to change notification settings - Fork 462
Neighbor Configuration
Complete reference for configuring BGP neighbors in ExaBGP
- Overview
- Basic Neighbor Configuration
- Required Parameters
- Optional Parameters
- iBGP vs eBGP Configuration
- Family Declarations
- TCP Settings
- Timers and Keepalives
- Capabilities Negotiation
- Multiple Neighbors
- Common Neighbor Patterns
- Common Mistakes
- Troubleshooting
- See Also
A neighbor is a BGP peer that ExaBGP establishes a session with. Each neighbor configuration defines:
- Session parameters: Router ID, AS numbers, addresses
- Transport settings: TCP MD5, TTL, ports
- Protocol features: Address families, capabilities
- API integration: Which processes to attach
- Static routes: Optionally announce static routes
Basic neighbor structure:
neighbor <peer-ip> {
# Required parameters
router-id <id>;
local-address <ip>;
local-as <asn>;
peer-as <asn>;
# Optional configuration
family { ... }
capability { ... }
api { ... }
static { ... }
}The simplest possible neighbor configuration requires only 4 parameters:
neighbor 192.168.1.1 {
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
}This creates:
- An eBGP session (different AS numbers)
- IPv4 unicast only (default family)
- Standard timers (hold-time: 180s)
- No API integration
- No static routes
A more realistic production configuration:
neighbor 192.168.1.1 {
# Identity
description "Core Router - Primary";
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
# Timers
hold-time 180;
# Security
md5-password "SecurePassword123";
ttl-security 255;
# Address families
family {
ipv4 unicast;
ipv6 unicast;
}
# Capabilities
capability {
route-refresh;
graceful-restart;
}
# API integration
api {
processes [ announce-routes ];
}
}These four parameters are mandatory for every neighbor:
Your BGP router identifier - must be unique across your network.
router-id 192.168.1.2;Requirements:
- Must be in IPv4 address format (even for IPv6-only sessions)
- Must be unique for this BGP speaker
- Typically set to:
- Loopback interface IP
- Primary local address
- Any unique IPv4 address
Example:
# Using loopback IP as router-id
neighbor 192.168.1.1 {
router-id 10.0.0.1; # Loopback address
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
}Common mistake:
# WRONG: Different router-id per neighbor (unless you really need this)
neighbor 192.168.1.1 {
router-id 192.168.1.2; # ID changes per neighbor
# ...
}
neighbor 192.168.2.1 {
router-id 192.168.2.2; # Different ID
# ...
}
# CORRECT: Same router-id across all neighbors
neighbor 192.168.1.1 {
router-id 10.0.0.1; # Same ID
# ...
}
neighbor 192.168.2.1 {
router-id 10.0.0.1; # Same ID
# ...
}IP address to bind to - must be reachable by the peer.
local-address 192.168.1.2;Requirements:
- Must exist on a local interface
- Must be routable by the peer
- Can be different from router-id
IPv6 example:
neighbor 2001:db8::1 {
router-id 10.0.0.1; # Still IPv4 format
local-address 2001:db8::2; # IPv6 local address
local-as 65001;
peer-as 65000;
}Loopback addresses:
# iBGP sessions often use loopback addresses
neighbor 10.0.0.2 {
router-id 10.0.0.1;
local-address 10.0.0.1; # Loopback
local-as 65001;
peer-as 65001; # iBGP
multihop 5; # Required for non-direct connection
}Your AS number (Autonomous System Number).
local-as 65001;Requirements:
- Range: 1 to 4294967295
- Private AS: 64512-65534 (16-bit) or 4200000000-4294967294 (32-bit)
- Public AS: Assigned by RIR (ARIN, RIPE, APNIC, etc.)
AS number types:
# 16-bit AS (legacy)
local-as 65001;
# 32-bit AS (4-byte ASN, RFC 6793)
local-as 4200000000;
# Public AS example
local-as 13335; # Cloudflare ASPrivate AS ranges:
- 16-bit private: 64512 - 65534
- 32-bit private: 4200000000 - 4294967294
- Reserved: 0, 23456, 65535
Peer's AS number.
peer-as 65000;Determines session type:
-
peer-asβlocal-asβ eBGP (external BGP) -
peer-as=local-asβ iBGP (internal BGP)
Examples:
# eBGP session
neighbor 192.168.1.1 {
local-as 65001;
peer-as 65000; # Different AS = eBGP
# ...
}
# iBGP session
neighbor 10.0.0.2 {
local-as 65001;
peer-as 65001; # Same AS = iBGP
# ...
}Human-readable description of the neighbor.
description "Core Router - Primary Link";Example:
neighbor 192.168.1.1 {
description "ISP Transit - Provider A - 10Gbps";
# ...
}Best practices:
- Include router hostname
- Note link type/capacity
- Include contact info if external peer
Explicit peer IP address (normally inferred from neighbor line).
peer-address 192.168.1.1;Usually not needed - use only for advanced scenarios like:
- Passive BGP sessions
- NAT traversal
- Testing
Example (rare usage):
neighbor 0.0.0.0 {
peer-address 192.168.1.1; # Actual peer IP
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
}BGP hold timer in seconds. Session drops if no keepalive/update received for this duration.
hold-time 180;Default: 180 seconds
Valid range: 0 (disabled, not recommended) or 3-65535
Keepalive interval: Automatically set to hold-time / 3
Examples:
# Standard hold-time (default)
hold-time 180; # Keepalive every 60 seconds
# Shorter hold-time for faster failure detection
hold-time 90; # Keepalive every 30 seconds
# Longer hold-time for unstable links
hold-time 240; # Keepalive every 80 secondsImportant:
- Both peers negotiate the minimum hold-time
- Setting too low can cause flapping on unstable links
- Setting too high delays failure detection
Group multiple route updates into single UPDATE message.
group-updates true; # Enable (default)
group-updates false; # DisableDefault: true
When to disable:
- Testing individual route announcements
- Debugging route updates
- Working with peers that have issues with grouped updates
External BGP - between different autonomous systems.
neighbor 203.0.113.1 {
description "ISP Transit Provider";
router-id 192.0.2.1;
local-address 192.0.2.1;
local-as 65001;
peer-as 65000; # Different AS = eBGP
# eBGP settings
hold-time 90;
md5-password "secret123";
family {
ipv4 unicast;
ipv6 unicast;
}
# eBGP automatically sets:
# - next-hop to self
# - TTL = 1 (unless multihop)
# - AS-PATH prepended with local-as
}eBGP characteristics:
- TTL = 1 by default (directly connected)
- AS-PATH is modified
- Next-hop changed to self
- No synchronization required
Internal BGP - within the same autonomous system.
neighbor 10.0.0.2 {
description "iBGP Route Reflector Client";
router-id 10.0.0.1;
local-address 10.0.0.1; # Loopback
local-as 65001;
peer-as 65001; # Same AS = iBGP
# iBGP settings
multihop 5; # Required for loopback peering
family {
ipv4 unicast;
ipv6 unicast;
}
capability {
route-refresh;
}
# iBGP characteristics:
# - next-hop NOT changed by default
# - Local preference can be set
# - AS-PATH NOT modified
}iBGP characteristics:
- Next-hop preserved (not changed)
- AS-PATH not modified
- Local preference attribute used
- Requires full mesh or route reflectors
iBGP full mesh example:
# Router 1 configuration
neighbor 10.0.0.2 {
router-id 10.0.0.1;
local-address 10.0.0.1;
local-as 65001;
peer-as 65001;
multihop 5;
}
neighbor 10.0.0.3 {
router-id 10.0.0.1;
local-address 10.0.0.1;
local-as 65001;
peer-as 65001;
multihop 5;
}
# Need N*(N-1)/2 sessions for N routers
# 3 routers = 3 sessions per routerConfigure which address families (AFI/SAFI) are enabled for the session.
family {
ipv4 unicast;
ipv6 unicast;
}Default: If family block is omitted, only ipv4 unicast is enabled.
DDoS mitigation and traffic filtering.
family {
ipv4 flowspec;
ipv6 flowspec;
}See also: FlowSpec Overview
family {
ipv4 mpls-vpn;
ipv6 mpls-vpn;
}RFC 4364 - BGP/MPLS IP VPNs
See also: L3VPN Overview
family {
l2vpn evpn;
}RFC 7432 - Ethernet VPN for data center fabrics
See also: EVPN Overview
family {
ipv4 link-state;
ipv6 link-state;
}RFC 7752 - Link-State info for SDN controllers
See also: BGP-LS Overview
family {
l2vpn vpls;
}Virtual Private LAN Service
You can enable multiple address families simultaneously:
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;
ipv6 unicast;
ipv4 flowspec;
ipv6 flowspec;
ipv4 mpls-vpn;
l2vpn evpn;
}
}Important:
- Must configure
receivein API to get routes for each family - Peer must support the same families
- Negotiated during BGP OPEN
TCP MD5 signature (RFC 2385) for session security.
md5-password "SecurePassword123";Requirements:
- Must be configured identically on both peers
- Password is case-sensitive
- No length limit (but keep it reasonable)
Example:
neighbor 192.168.1.1 {
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
md5-password "mY$3cR3tP@ssw0rd!";
}Security note:
- Password stored in plaintext in config file
- Protect config file permissions:
chmod 600 /etc/exabgp/exabgp.conf - Consider using configuration management tools for secret distribution
Generalized TTL Security Mechanism (GTSM, RFC 5082).
ttl-security 255;How it works:
- Peer sends packets with TTL = 255
- Local router expects TTL β₯ configured value
- Prevents attacks from non-adjacent routers
Example:
neighbor 192.168.1.1 {
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
ttl-security 255; # Expect TTL >= 255 (directly connected)
}TTL security vs multihop:
- Cannot use both simultaneously
-
ttl-securityis for directly connected peers -
multihopis for non-adjacent peers
Allow eBGP sessions to non-directly connected peers.
multihop 5;Default: 1 (directly connected)
Valid range: 1-255
When to use:
- Loopback-to-loopback eBGP sessions
- Peering across intermediate routers
- iBGP sessions (typically use higher values)
Example - eBGP multihop:
neighbor 203.0.113.50 {
description "ISP Router Loopback";
router-id 192.0.2.1;
local-address 192.0.2.1; # Local loopback
local-as 65001;
peer-as 65000;
multihop 2; # Allow 1 hop between us
}Example - iBGP:
neighbor 10.0.0.2 {
router-id 10.0.0.1;
local-address 10.0.0.1; # Loopback
local-as 65001;
peer-as 65001; # iBGP
multihop 5; # Allow up to 5 hops
}Custom BGP ports (default: 179).
local-port 1790;
peer-port 179;Rarely needed - use only for:
- Testing multiple sessions on same IP
- Non-standard deployments
- Port forwarding scenarios
Example:
neighbor 192.168.1.1 {
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
local-port 1790; # ExaBGP binds to 1790
peer-port 179; # Peer listens on standard port
}Connection retry interval in seconds when session fails.
connect 30;Default: 30 seconds
Valid range: 1-65535
Example:
neighbor 192.168.1.1 {
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
connect 10; # Retry every 10 seconds on failure
}See hold-time in Optional Parameters section.
Summary:
hold-time 180; # Default: 180 seconds- Determines when session is considered dead
- Keepalive interval = hold-time / 3
- Negotiated to minimum of both peers
ExaBGP automatically manages keepalives based on hold-time.
You cannot manually configure keepalive interval - it's always hold-time / 3.
Examples:
| hold-time | keepalive interval |
|---|---|
| 90 | 30 seconds |
| 180 | 60 seconds |
| 240 | 80 seconds |
BGP capabilities are negotiated during OPEN message exchange.
Allow peer to request route table refresh.
capability {
route-refresh;
}RFC 2918 - Route Refresh Capability
Benefits:
- Peer can request full route table without session reset
- Useful for policy changes
Allow routes to persist during session restart.
capability {
graceful-restart;
}RFC 4724 - Graceful Restart Mechanism
With custom restart time:
capability {
graceful-restart 120; # 120 seconds restart time
}Benefits:
- Reduces routing churn during planned maintenance
- Preserves forwarding during control plane restart
Advertise/receive multiple paths to same destination.
capability {
add-path send/receive;
}RFC 7911 - Advertisement of Multiple Paths
Options:
-
send- Send multiple paths -
receive- Receive multiple paths -
send/receive- Both directions
Example:
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;
}
capability {
add-path receive; # Receive multiple paths from peer
}
}Enable 32-bit AS numbers.
capability {
asn4;
}RFC 6793 - Four-Octet AS Number Space
Automatically enabled when local-as or peer-as > 65535.
Support messages larger than 4096 bytes.
capability {
extended-message;
}RFC 8654 - Extended Message Support
Use cases:
- Large BGP UPDATE messages
- Many routes in single update
- Large communities
Allow multiple BGP sessions to same peer (experimental).
capability {
multi-session;
}Experimental feature - use with caution.
Combine capabilities:
neighbor 192.168.1.1 {
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
capability {
route-refresh;
graceful-restart 120;
add-path send/receive;
extended-message;
}
}neighbor 192.168.1.1 {
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
}
neighbor 192.168.2.1 {
router-id 192.168.1.2; # Same router-id
local-address 192.168.2.2; # Different local address
local-as 65001;
peer-as 65002;
}
neighbor 192.168.3.1 {
router-id 192.168.1.2; # Same router-id
local-address 192.168.3.2;
local-as 65001;
peer-as 65003;
}Important:
-
router-idshould be same across all neighbors (it identifies YOUR router) -
local-addressmust be appropriate for each link -
peer-asdetermines session type
Reduce duplication with templates:
# Define template
template {
neighbor common-settings {
router-id 192.168.1.2;
local-as 65001;
family {
ipv4 unicast;
}
capability {
route-refresh;
graceful-restart;
}
}
}
# Use template
neighbor 192.168.1.1 {
inherit common-settings;
local-address 192.168.1.2;
peer-as 65000;
description "Core Router 1";
}
neighbor 192.168.2.1 {
inherit common-settings;
local-address 192.168.2.2;
peer-as 65000;
description "Core Router 2";
}See also: Templates and Inheritance
process healthcheck {
run /etc/exabgp/api/healthcheck.py;
encoder text;
}
neighbor 192.168.1.1 {
description "Anycast Upstream Router";
router-id 10.0.0.1;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
family {
ipv4 unicast;
}
capability {
route-refresh;
}
api {
processes [ healthcheck ];
}
}Use case: Anycast IP announcement based on health checks
neighbor 10.0.0.2 {
description "Route Reflector Server";
router-id 10.0.0.1;
local-address 10.0.0.1; # Loopback
local-as 65001;
peer-as 65001; # iBGP
multihop 5;
family {
ipv4 unicast;
ipv6 unicast;
}
capability {
route-refresh;
graceful-restart 120;
}
}Use case: iBGP client to route reflector (eliminates full mesh)
process ddos-blocker {
run /etc/exabgp/api/ddos_blocker.py;
encoder text;
}
neighbor 192.168.1.1 {
description "FlowSpec Peer - Core Router";
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
family {
ipv4 flowspec;
}
api {
processes [ ddos-blocker ];
}
}Use case: Dynamic DDoS mitigation with FlowSpec
process announce-all {
run /etc/exabgp/api/announce.py;
encoder text;
}
process receive-all {
run /etc/exabgp/api/receive.py;
encoder json;
receive {
parsed;
updates;
}
}
neighbor 192.168.1.1 {
description "Multi-Protocol Peer";
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
family {
ipv4 unicast;
ipv6 unicast;
ipv4 flowspec;
ipv4 mpls-vpn;
l2vpn evpn;
}
capability {
route-refresh;
graceful-restart;
extended-message;
}
api {
processes [ announce-all, receive-all ];
}
}Use case: Advanced multi-service BGP peer
neighbor 203.0.113.1 {
description "ISP Transit - Primary (10Gbps)";
router-id 192.0.2.1;
local-address 192.0.2.1;
local-as 65001;
peer-as 174; # Cogent AS example
# Security
md5-password "SuperSecretPassword123!";
ttl-security 255;
# Fast failure detection
hold-time 90;
family {
ipv4 unicast;
ipv6 unicast;
}
capability {
route-refresh;
graceful-restart;
}
}Use case: Production internet transit with security
Wrong:
neighbor 192.168.1.1 {
local-as 65001;
peer-as 65000;
}Error:
Configuration error: missing router-id
Correct:
neighbor 192.168.1.1 {
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
}Wrong (usually):
neighbor 192.168.1.1 {
router-id 192.168.1.2; # Changes per neighbor
# ...
}
neighbor 192.168.2.1 {
router-id 192.168.2.2; # Different ID
# ...
}Correct:
neighbor 192.168.1.1 {
router-id 10.0.0.1; # Same ID for all neighbors
local-address 192.168.1.2;
# ...
}
neighbor 192.168.2.1 {
router-id 10.0.0.1; # Same ID
local-address 192.168.2.2;
# ...
}Explanation: router-id identifies your BGP speaker, not the peer. It should be consistent across all neighbor configurations.
Wrong:
neighbor 10.0.0.2 {
router-id 10.0.0.1;
local-address 10.0.0.1; # Loopback
local-as 65001;
peer-as 65001;
multihop 5;
# Missing: static routes or IGP to reach 10.0.0.2
}Problem: Session won't establish because 10.0.0.2 is not routable.
Correct:
# Ensure routing to peer loopback
ip route add 10.0.0.2/32 via 192.168.1.1Then configure:
neighbor 10.0.0.2 {
router-id 10.0.0.1;
local-address 10.0.0.1;
local-as 65001;
peer-as 65001;
multihop 5;
}Wrong:
neighbor 192.168.1.1 {
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
ttl-security 255;
multihop 5; # ERROR: Can't use both
}Error:
Configuration error: cannot use both ttl-security and multihop
Choose one:
# For directly connected: use ttl-security
ttl-security 255;
# For non-adjacent: use multihop
multihop 5;Wrong (for receiving routes):
process receive-routes {
run /etc/exabgp/api/receive.py;
encoder json;
receive {
parsed;
updates;
}
}
neighbor 192.168.1.1 {
router-id 192.168.1.2;
local-address 192.168.1.2;
local-as 65001;
peer-as 65000;
# Missing family declaration - will default to ipv4 unicast only
api {
processes [ receive-routes ];
}
}Problem: If peer sends IPv6 routes, you won't receive them.
Correct:
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;
ipv6 unicast; # Now you'll receive IPv6 routes
}
api {
processes [ receive-routes ];
}
}Router A:
neighbor 192.168.1.2 {
md5-password "Secret123";
# ...
}Router B (ExaBGP):
neighbor 192.168.1.1 {
md5-password "secret123"; # Case mismatch!
# ...
}Result: Session stuck in "Active" or "Connect" state - TCP connection fails silently.
Fix: Passwords must match exactly (case-sensitive).
Wrong:
# Trying to do iBGP but using different AS numbers
neighbor 10.0.0.2 {
router-id 10.0.0.1;
local-address 10.0.0.1;
local-as 65001;
peer-as 65002; # Different AS = eBGP, not iBGP!
multihop 5;
}Correct iBGP:
neighbor 10.0.0.2 {
router-id 10.0.0.1;
local-address 10.0.0.1;
local-as 65001;
peer-as 65001; # Same AS = iBGP
multihop 5;
}Symptom: Session stuck in "Active" or "Connect" state.
Checks:
- Network connectivity:
ping <peer-ip>- TCP port 179 reachable:
telnet <peer-ip> 179
nc -zv <peer-ip> 179- MD5 password match:
- Verify passwords are identical (case-sensitive)
- Check both peer configs
- Firewall rules:
# Allow BGP traffic
iptables -A INPUT -p tcp --dport 179 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 179 -j ACCEPT- Check ExaBGP logs:
exabgp.log.level=DEBUG exabgp /etc/exabgp/exabgp.confSymptom: Session repeatedly goes up and down.
Causes:
- Hold-time too short for unstable link:
# Increase hold-time
hold-time 240; # From default 180- Network path MTU issues:
# Test MTU
ping -M do -s 1472 <peer-ip>- Keepalive packets being dropped:
# Check packet loss
ping -c 100 <peer-ip>Symptom: Session up, but no routes received.
Checks:
- Family configuration:
# Ensure family is configured
family {
ipv4 unicast; # Must match what peer sends
}- API receive configuration:
process receive {
run /etc/exabgp/api/receive.py;
encoder json;
receive {
parsed; # Required to receive routes
updates; # Filter to only updates
}
}- Peer is sending routes:
- Check peer BGP table
- Verify peer export policy allows routes to you
Symptom: API sends routes, but peer doesn't receive them.
Checks:
- Process configured in neighbor:
neighbor 192.168.1.1 {
# ...
api {
processes [ announce-routes ]; # Must list process
}
}- API command format:
# Text API
echo "announce route 10.0.0.0/24 next-hop self" > /run/exabgp.in
# JSON API
echo '{"exabgp":"4.0","type":"update","neighbor":{"ip":"192.168.1.1","update":{"announce":{"ipv4 unicast":{"10.0.0.0/24":{"next-hop":"self"}}}}}}' > /run/exabgp.in- Session family supports route type:
family {
ipv4 unicast; # Required for IPv4 unicast routes
}Symptom: ExaBGP using high CPU or memory.
Optimizations:
- Enable group-updates:
group-updates true; # Group multiple routes per UPDATE- Reduce logging:
export exabgp.log.level=WARNING
export exabgp.log.routes=false
export exabgp.log.packets=false- Use text encoder (faster than JSON):
process my-process {
encoder text; # Faster than json
}- Configuration Syntax - Complete configuration reference
- Templates and Inheritance - Reduce configuration duplication
- Directives Reference - A-Z directive listing
- First BGP Session - Step-by-step setup guide
- API Overview - Process and API configuration
- Debugging - Troubleshooting guide
Ready to configure? Start with Quick Start Guide β
π» 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)