Configure BGP routing with FRRouting to implement dynamic network routing, automatic failover, and high availability for enterprise network infrastructure with route filtering and policy management.
Prerequisites
- Root or sudo access
- Multiple network interfaces
- Basic understanding of routing concepts
- Network connectivity to BGP peers
What this solves
BGP (Border Gateway Protocol) routing with FRRouting enables automatic network failover, dynamic route advertisement, and redundant connectivity for enterprise networks. This setup provides high availability by automatically switching traffic between multiple network paths when links fail, eliminating single points of failure. You need this when managing complex network topologies, connecting to multiple ISPs, or implementing redundant data center connectivity.
Step-by-step installation
Update system packages
Start by updating your package manager to ensure you get the latest versions of all packages.
sudo apt update && sudo apt upgrade -y
Install FRRouting
Install FRRouting daemon which provides BGP, OSPF, and other routing protocols. This installs the main routing engine and command-line tools.
sudo apt install -y frr frr-pythontools
Enable BGP daemon
Configure FRRouting to enable the BGP daemon. Edit the daemons file to activate BGP routing capabilities.
bgpd=yes
ospfd=no
ospf6d=no
ripd=no
ripngd=no
isisd=no
pimd=no
ldpd=no
nhrpd=no
eigrpd=no
babeld=no
sharpd=no
pbrd=no
staticd=yes
bfdd=no
fabricd=no
vrrpd=no
pathd=no
Configure system IP forwarding
Enable IP forwarding to allow the router to forward packets between network interfaces. This is essential for BGP routing functionality.
echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf
echo 'net.ipv6.conf.all.forwarding=1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Start and enable FRRouting
Start the FRRouting service and enable it to start automatically on boot. Verify the service is running correctly.
sudo systemctl enable --now frr
sudo systemctl status frr
Configure BGP peering and route advertisement
Access FRRouting shell
Connect to the FRRouting configuration shell to configure BGP settings. This provides a Cisco-like interface for router configuration.
sudo vtysh
Configure basic BGP settings
Set up your BGP router with autonomous system number and router ID. Replace AS65001 with your actual AS number and use your router's primary IP as router ID.
configure terminal
router bgp 65001
bgp router-id 203.0.113.1
bgp log-neighbor-changes
Configure BGP neighbors
Add BGP neighbors (peers) with their IP addresses and AS numbers. This example shows peering with two different routers for redundancy.
neighbor 203.0.113.10 remote-as 65002
neighbor 203.0.113.10 description "Primary ISP Router"
neighbor 203.0.113.20 remote-as 65003
neighbor 203.0.113.20 description "Secondary ISP Router"
neighbor 203.0.113.10 update-source 203.0.113.1
neighbor 203.0.113.20 update-source 203.0.113.1
Configure network advertisements
Advertise your network prefixes to BGP peers. Add the networks you want to announce to other routers.
network 192.168.1.0/24
network 10.0.0.0/16
exit
Set up route filtering and policies
Create prefix lists for filtering
Define prefix lists to control which routes are accepted or advertised. This improves security and prevents route leaks.
ip prefix-list ALLOW-LOCAL-NETS seq 10 permit 192.168.1.0/24
ip prefix-list ALLOW-LOCAL-NETS seq 20 permit 10.0.0.0/16
ip prefix-list DENY-DEFAULT seq 10 deny 0.0.0.0/0
ip prefix-list DENY-DEFAULT seq 20 permit any
Create route maps for policy control
Configure route maps to apply filtering policies and modify route attributes. This controls traffic flow and implements routing policies.
route-map FILTER-OUT permit 10
match ip address prefix-list ALLOW-LOCAL-NETS
set local-preference 200
exit
route-map FILTER-IN permit 10
match ip address prefix-list DENY-DEFAULT
set weight 100
exit
Apply filters to BGP neighbors
Apply the route maps to BGP neighbors to control inbound and outbound route advertisements.
router bgp 65001
neighbor 203.0.113.10 route-map FILTER-OUT out
neighbor 203.0.113.10 route-map FILTER-IN in
neighbor 203.0.113.20 route-map FILTER-OUT out
neighbor 203.0.113.20 route-map FILTER-IN in
Implement BGP failover and redundancy
Configure BGP timers for faster failover
Reduce BGP keepalive and hold timers for faster detection of neighbor failures. This improves failover speed but increases network overhead.
neighbor 203.0.113.10 timers 10 30
neighbor 203.0.113.20 timers 10 30
Set path preferences with local preference
Configure different local preferences to control primary and backup path selection. Higher values are preferred for outbound traffic.
route-map PRIMARY-PATH permit 10
set local-preference 200
exit
route-map BACKUP-PATH permit 10
set local-preference 100
exit
neighbor 203.0.113.10 route-map PRIMARY-PATH in
neighbor 203.0.113.20 route-map BACKUP-PATH in
Configure MED for inbound traffic control
Use Multi-Exit Discriminator (MED) to influence how external networks reach you. Lower MED values are preferred by remote routers.
route-map SET-MED-PRIMARY permit 10
set metric 50
exit
route-map SET-MED-BACKUP permit 10
set metric 100
exit
neighbor 203.0.113.10 route-map SET-MED-PRIMARY out
neighbor 203.0.113.20 route-map SET-MED-BACKUP out
Enable BGP graceful restart
Configure graceful restart to maintain forwarding during BGP session restarts. This reduces traffic loss during maintenance or brief outages.
bgp graceful-restart
bgp graceful-restart stalepath-time 360
bgp graceful-restart restart-time 120
Save configuration
Save the running configuration to ensure changes persist after reboot.
write memory
exit
Monitor BGP sessions and troubleshoot
Set up BGP logging
Configure detailed BGP logging to monitor session states and troubleshoot issues. This helps identify routing problems and track changes.
sudo vtysh -c "configure terminal" -c "log file /var/log/frr/bgp.log" -c "log record-priority" -c "write memory"
Configure log rotation
Set up log rotation to prevent BGP logs from consuming excessive disk space.
/var/log/frr/*.log {
daily
missingok
rotate 14
compress
notifempty
create 644 frr frr
postrotate
systemctl reload frr
endscript
}
Verify your setup
sudo vtysh -c "show ip bgp summary"
sudo vtysh -c "show ip bgp neighbors"
sudo vtysh -c "show ip route bgp"
sudo vtysh -c "show ip bgp"
ping -c 4 203.0.113.10
traceroute 8.8.8.8
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| BGP neighbors in Idle state | Firewall blocking TCP 179 | Configure firewall: sudo ufw allow 179 |
| Routes not being advertised | Networks not in routing table | Add static routes or configure IGP |
| Slow failover times | Default BGP timers too high | Reduce timers with timers 10 30 |
| Route filtering not working | Incorrect prefix-list syntax | Verify with show ip prefix-list |
| Session flapping | Network instability or timer mismatch | Check network connectivity and timer configuration |
| Memory usage high | Too many routes in table | Implement route filtering and summarization |
Next steps
- Configure Linux system firewall with nftables for BGP traffic
- Install and configure HAProxy for high availability load balancing
- Configure OSPF with FRRouting for internal dynamic routing
- Implement network monitoring with SNMP and BGP metrics
- Configure BIRD BGP routing daemon for advanced routing policies
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# FRRouting BGP Installation Script
# Usage: sudo ./install-frr-bgp.sh <router-ip> <as-number> [peer1-ip:peer1-as] [peer2-ip:peer2-as]
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Logging functions
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# Usage message
usage() {
echo "Usage: $0 <router-ip> <as-number> [peer1-ip:peer1-as] [peer2-ip:peer2-as]"
echo "Example: $0 203.0.113.1 65001 203.0.113.10:65002 203.0.113.20:65003"
exit 1
}
# Cleanup on error
cleanup() {
log_error "Installation failed. Cleaning up..."
systemctl stop frr 2>/dev/null || true
systemctl disable frr 2>/dev/null || true
}
trap cleanup ERR
# Check arguments
if [ $# -lt 2 ]; then
usage
fi
ROUTER_IP="$1"
AS_NUMBER="$2"
PEER1="${3:-}"
PEER2="${4:-}"
# Validate IP address
validate_ip() {
if [[ ! $1 =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
log_error "Invalid IP address: $1"
exit 1
fi
}
validate_ip "$ROUTER_IP"
# Check prerequisites
if [ "$EUID" -ne 0 ]; then
log_error "Please run as root or with sudo"
exit 1
fi
# Auto-detect distribution
log_info "[1/8] Detecting distribution..."
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update && apt upgrade -y"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
;;
*)
log_error "Unsupported distribution: $ID"
exit 1
;;
esac
else
log_error "Cannot detect distribution"
exit 1
fi
log_info "Detected distribution: $ID using $PKG_MGR"
# Update system packages
log_info "[2/8] Updating system packages..."
if [ "$PKG_MGR" = "apt" ]; then
apt update && apt upgrade -y
else
$PKG_UPDATE
fi
# Install FRRouting
log_info "[3/8] Installing FRRouting..."
if [ "$PKG_MGR" = "apt" ]; then
# Add FRR repository for latest version
curl -s https://deb.frrouting.org/frr/keys.asc | apt-key add -
echo deb https://deb.frrouting.org/frr $(lsb_release -s -c) frr-stable | tee -a /etc/apt/sources.list.d/frr.list
apt update
$PKG_INSTALL frr frr-pythontools
else
$PKG_INSTALL frr frr-pythontools
fi
# Configure FRRouting daemons
log_info "[4/8] Configuring FRRouting daemons..."
cat > /etc/frr/daemons << EOF
bgpd=yes
ospfd=no
ospf6d=no
ripd=no
ripngd=no
isisd=no
pimd=no
ldpd=no
nhrpd=no
eigrpd=no
babeld=no
sharpd=no
pbrd=no
staticd=yes
bfdd=no
fabricd=no
vrrpd=no
pathd=no
EOF
chown frr:frr /etc/frr/daemons
chmod 644 /etc/frr/daemons
# Enable IP forwarding
log_info "[5/8] Enabling IP forwarding..."
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
echo 'net.ipv6.conf.all.forwarding=1' >> /etc/sysctl.conf
sysctl -p
# Start and enable FRRouting
log_info "[6/8] Starting FRRouting service..."
systemctl enable frr
systemctl start frr
sleep 3
# Configure BGP
log_info "[7/8] Configuring BGP..."
cat > /tmp/frr_config << EOF
configure terminal
router bgp ${AS_NUMBER}
bgp router-id ${ROUTER_IP}
bgp log-neighbor-changes
EOF
# Add BGP peers if provided
if [ -n "$PEER1" ]; then
IFS=':' read -r PEER1_IP PEER1_AS <<< "$PEER1"
validate_ip "$PEER1_IP"
cat >> /tmp/frr_config << EOF
neighbor ${PEER1_IP} remote-as ${PEER1_AS}
neighbor ${PEER1_IP} description "BGP Peer 1"
neighbor ${PEER1_IP} update-source ${ROUTER_IP}
EOF
fi
if [ -n "$PEER2" ]; then
IFS=':' read -r PEER2_IP PEER2_AS <<< "$PEER2"
validate_ip "$PEER2_IP"
cat >> /tmp/frr_config << EOF
neighbor ${PEER2_IP} remote-as ${PEER2_AS}
neighbor ${PEER2_IP} description "BGP Peer 2"
neighbor ${PEER2_IP} update-source ${ROUTER_IP}
EOF
fi
# Add basic prefix lists and route maps
cat >> /tmp/frr_config << EOF
exit
ip prefix-list ALLOW-LOCAL-NETS seq 10 permit 192.168.0.0/16 le 24
ip prefix-list ALLOW-LOCAL-NETS seq 20 permit 10.0.0.0/8 le 24
ip prefix-list DENY-DEFAULT seq 10 deny 0.0.0.0/0
ip prefix-list DENY-DEFAULT seq 20 permit any
route-map FILTER-OUT permit 10
match ip address prefix-list ALLOW-LOCAL-NETS
set local-preference 200
exit
route-map FILTER-IN permit 10
match ip address prefix-list DENY-DEFAULT
set weight 100
exit
write memory
EOF
# Apply configuration
vtysh < /tmp/frr_config
rm -f /tmp/frr_config
# Configure firewall
if command -v ufw >/dev/null 2>&1; then
ufw allow 179/tcp comment "BGP"
elif command -v firewall-cmd >/dev/null 2>&1; then
firewall-cmd --permanent --add-port=179/tcp
firewall-cmd --reload
fi
# Verification
log_info "[8/8] Verifying installation..."
if systemctl is-active --quiet frr; then
log_info "FRRouting service is running"
else
log_error "FRRouting service is not running"
exit 1
fi
# Check BGP status
BGP_STATUS=$(vtysh -c "show bgp summary" 2>/dev/null || echo "BGP not ready")
if [[ "$BGP_STATUS" == *"BGP router identifier"* ]]; then
log_info "BGP is configured and running"
else
log_warn "BGP may not be fully initialized yet"
fi
log_info "FRRouting BGP installation completed successfully!"
log_info "Router ID: $ROUTER_IP"
log_info "AS Number: $AS_NUMBER"
log_info ""
log_info "To configure additional settings, use: sudo vtysh"
log_info "To check BGP status: sudo vtysh -c 'show bgp summary'"
log_info "To view routes: sudo vtysh -c 'show ip route'"
Review the script before running. Execute with: bash install.sh