Set up FRRouting with route maps and prefix lists to control BGP route advertisement, implement traffic engineering, and create sophisticated routing policies for enterprise networks.
Prerequisites
- Root or sudo access
- Basic understanding of BGP and routing concepts
- Network interfaces configured with IP addresses
- Understanding of AS numbers and BGP communities
What this solves
FRRouting route maps and prefix lists give you precise control over BGP routing policies. Use them to filter routes based on prefixes, modify BGP attributes for traffic engineering, and implement complex routing decisions across your network infrastructure.
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 package along with essential networking tools for BGP routing management.
sudo apt install -y frr frr-pythontools iproute2 net-tools
Enable BGP daemon
Configure FRRouting to enable the BGP daemon which is required for route maps and prefix lists.
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
bfdd=no
fabricd=no
vrrpd=no
pathd=no
Start and enable FRRouting
Start the FRRouting service and enable it to automatically start on boot.
sudo systemctl enable --now frr
sudo systemctl status frr
Create and configure prefix lists
Access FRRouting configuration shell
Connect to the FRRouting configuration interface to create prefix lists and route maps.
sudo vtysh
Create basic prefix lists
Define prefix lists to match specific network ranges. This example creates lists for internal networks and customer routes.
configure terminal
!
ip prefix-list INTERNAL_NETWORKS seq 10 permit 10.0.0.0/8 le 24
ip prefix-list INTERNAL_NETWORKS seq 20 permit 172.16.0.0/12 le 24
ip prefix-list INTERNAL_NETWORKS seq 30 permit 192.168.0.0/16 le 24
!
ip prefix-list CUSTOMER_ROUTES seq 10 permit 203.0.113.0/24
ip prefix-list CUSTOMER_ROUTES seq 20 permit 198.51.100.0/24
ip prefix-list CUSTOMER_ROUTES seq 30 permit 198.51.101.0/24
!
ip prefix-list DEFAULT_ROUTE seq 10 permit 0.0.0.0/0
!
ip prefix-list DENY_ALL seq 10 deny any
Create advanced prefix lists with length matching
Use prefix length operators to match routes more precisely. The le (less than or equal) and ge (greater than or equal) operators control subnet matching.
!
ip prefix-list AGGREGATE_ROUTES seq 10 permit 10.0.0.0/8 ge 16 le 20
ip prefix-list HOST_ROUTES seq 10 permit 0.0.0.0/0 ge 32
ip prefix-list SMALL_SUBNETS seq 10 permit 0.0.0.0/0 ge 28
!
ip prefix-list TRANSIT_PREFIXES seq 10 deny 10.0.0.0/8 le 32
ip prefix-list TRANSIT_PREFIXES seq 20 deny 172.16.0.0/12 le 32
ip prefix-list TRANSIT_PREFIXES seq 30 deny 192.168.0.0/16 le 32
ip prefix-list TRANSIT_PREFIXES seq 40 permit any
Configure route maps with filtering policies
Create basic route map for prefix filtering
Route maps apply policies to matched prefixes. This example filters internal networks and sets BGP attributes.
!
route-map FILTER_INTERNAL permit 10
match ip address prefix-list INTERNAL_NETWORKS
set local-preference 200
set community 65001:100
!
route-map FILTER_INTERNAL deny 20
Create route map for customer traffic engineering
Implement traffic engineering by modifying BGP attributes like AS-path prepending and MED values for different customer routes.
!
route-map CUSTOMER_POLICY permit 10
match ip address prefix-list CUSTOMER_ROUTES
set metric 100
set as-path prepend 65001 65001
set community 65001:200
!
route-map CUSTOMER_POLICY permit 20
match ip address prefix-list DEFAULT_ROUTE
set local-preference 50
!
route-map CUSTOMER_POLICY deny 30
Create route map for transit provider policies
Configure different policies for multiple transit providers to control route advertisement and path selection.
!
route-map TRANSIT_IN permit 10
match ip address prefix-list TRANSIT_PREFIXES
set local-preference 150
set community 65001:300
!
route-map TRANSIT_OUT permit 10
match ip address prefix-list INTERNAL_NETWORKS
set as-path prepend 65001
!
route-map TRANSIT_OUT permit 20
match ip address prefix-list CUSTOMER_ROUTES
!
route-map TRANSIT_OUT deny 30
Implement advanced routing policies and redistribution
Configure BGP with route maps
Apply the created route maps to BGP neighbors for inbound and outbound route processing.
!
router bgp 65001
bgp router-id 203.0.113.1
bgp log-neighbor-changes
!
neighbor 203.0.113.10 remote-as 65002
neighbor 203.0.113.10 route-map CUSTOMER_POLICY in
neighbor 203.0.113.10 route-map FILTER_INTERNAL out
!
neighbor 203.0.113.20 remote-as 65003
neighbor 203.0.113.20 route-map TRANSIT_IN in
neighbor 203.0.113.20 route-map TRANSIT_OUT out
!
address-family ipv4 unicast
network 10.0.0.0/16
network 172.16.0.0/16
exit-address-family
Configure route redistribution with route maps
Control which routes get redistributed between different routing protocols using route maps.
!
route-map REDISTRIBUTE_CONNECTED permit 10
match interface eth0
set metric 50
!
route-map REDISTRIBUTE_STATIC permit 10
match ip address prefix-list INTERNAL_NETWORKS
set community 65001:400
!
router bgp 65001
redistribute connected route-map REDISTRIBUTE_CONNECTED
redistribute static route-map REDISTRIBUTE_STATIC
Implement conditional route advertisement
Use route maps with conditional logic to advertise routes only when specific conditions are met.
!
route-map CONDITIONAL_ADVERTISE permit 10
match ip address prefix-list CUSTOMER_ROUTES
match community 65001:200
set community 65001:500
!
route-map BACKUP_PATH permit 10
match ip address prefix-list DEFAULT_ROUTE
set local-preference 25
set community 65001:600
!
router bgp 65001
neighbor 203.0.113.30 remote-as 65004
neighbor 203.0.113.30 route-map CONDITIONAL_ADVERTISE out
neighbor 203.0.113.30 route-map BACKUP_PATH in
Save and apply configuration
Write the configuration to memory and exit the configuration interface.
!
write memory
exit
Enable IP forwarding
Configure the system to forward IP packets between network interfaces for proper routing functionality.
echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Verify your setup
sudo vtysh -c "show ip prefix-list"
sudo vtysh -c "show route-map"
sudo vtysh -c "show ip bgp summary"
sudo vtysh -c "show ip bgp neighbors"
sudo vtysh -c "show ip route"
Check that BGP neighbors are established and routes are being processed correctly:
sudo vtysh -c "show ip bgp neighbors 203.0.113.10 routes"
sudo vtysh -c "show ip bgp community 65001:100"
sudo vtysh -c "show ip bgp regexp 65001"
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| BGP neighbors won't establish | Incorrect AS numbers or IP addresses | sudo vtysh -c "show ip bgp summary" and verify neighbor config |
| Routes not being filtered | Route map not applied to neighbor | Add route-map POLICY_NAME in/out to neighbor configuration |
| Prefix list matches wrong networks | Incorrect use of le/ge operators | Check prefix length logic with show ip prefix-list detail |
| BGP attributes not being set | Route map deny statement reached | Add explicit permit statements or reorder route map entries |
| Routes disappearing from table | Conflicting route map policies | Review all route maps with show route-map for conflicts |
| Performance issues with large tables | Inefficient prefix list ordering | Put most specific matches first, use sequence numbers |
Next steps
- Configure BIRD BGP routing daemon for advanced routing policies and network automation
- Implement network monitoring with SNMP and BGP metrics using FRRouting and Prometheus
- Configure FRRouting OSPF and BGP multi-protocol routing for complex topologies
- Set up FRRouting BGP route reflector clusters for large-scale networks
- Implement FRRouting BGP anycast load balancing for high availability services
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Configuration variables
FRROUTING_CONFIG="/etc/frr/daemons"
VTYSH_CONFIG="/tmp/frr_config.txt"
# Error cleanup function
cleanup() {
local exit_code=$?
if [ $exit_code -ne 0 ]; then
echo -e "${RED}[ERROR] Installation failed. Cleaning up...${NC}"
systemctl stop frr 2>/dev/null || true
rm -f "$VTYSH_CONFIG" 2>/dev/null || true
fi
exit $exit_code
}
trap cleanup ERR EXIT
usage() {
echo "Usage: $0 [AS_NUMBER]"
echo " AS_NUMBER: BGP Autonomous System number (default: 65001)"
echo ""
echo "Example: $0 65001"
exit 1
}
# Parse arguments
AS_NUMBER="${1:-65001}"
if ! [[ "$AS_NUMBER" =~ ^[0-9]+$ ]]; then
echo -e "${RED}Error: AS_NUMBER must be numeric${NC}"
usage
fi
echo -e "${GREEN}FRRouting BGP Route Maps and Prefix Lists Installation${NC}"
echo "AS Number: $AS_NUMBER"
# Check if running as root or with sudo
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}This script must be run as root or with sudo${NC}"
exit 1
fi
echo -e "${YELLOW}[1/8] Detecting distribution...${NC}"
if [ ! -f /etc/os-release ]; then
echo -e "${RED}Cannot detect distribution - /etc/os-release not found${NC}"
exit 1
fi
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update && apt upgrade -y"
NETWORK_TOOLS="iproute2 net-tools"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
NETWORK_TOOLS="iproute net-tools"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
NETWORK_TOOLS="iproute net-tools"
;;
*)
echo -e "${RED}Unsupported distribution: $ID${NC}"
exit 1
;;
esac
echo "Detected: $PRETTY_NAME ($PKG_MGR)"
echo -e "${YELLOW}[2/8] Updating system packages...${NC}"
$PKG_UPDATE
echo -e "${YELLOW}[3/8] Installing FRRouting and network tools...${NC}"
$PKG_INSTALL frr frr-pythontools $NETWORK_TOOLS
echo -e "${YELLOW}[4/8] Configuring FRRouting daemons...${NC}"
if [ ! -f "$FRROUTING_CONFIG" ]; then
echo -e "${RED}FRRouting configuration file not found at $FRROUTING_CONFIG${NC}"
exit 1
fi
# Backup original config
cp "$FRROUTING_CONFIG" "${FRROUTING_CONFIG}.backup"
# Configure daemons - enable BGP, disable others
cat > "$FRROUTING_CONFIG" << '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
bfdd=no
fabricd=no
vrrpd=no
pathd=no
vtysh_enable=yes
zebra_options=" -A 127.0.0.1 -s 90000000"
bgpd_options=" -A 127.0.0.1"
ospfd_options=" -A 127.0.0.1"
ospf6d_options=" -A ::1"
ripd_options=" -A 127.0.0.1"
ripngd_options=" -A ::1"
isisd_options=" -A 127.0.0.1"
pimd_options=" -A 127.0.0.1"
ldpd_options=" -A 127.0.0.1"
nhrpd_options=" -A 127.0.0.1"
eigrpd_options=" -A 127.0.0.1"
babeld_options=" -A 127.0.0.1"
sharpd_options=" -A 127.0.0.1"
pbrd_options=" -A 127.0.0.1"
staticd_options="-A 127.0.0.1"
bfdd_options=" -A 127.0.0.1"
fabricd_options="-A 127.0.0.1"
vrrpd_options=" -A 127.0.0.1"
pathd_options=" -A 127.0.0.1"
EOF
# Set proper permissions
chmod 644 "$FRROUTING_CONFIG"
chown frr:frr "$FRROUTING_CONFIG"
echo -e "${YELLOW}[5/8] Starting and enabling FRRouting service...${NC}"
systemctl enable frr
systemctl start frr
sleep 3
# Verify service is running
if ! systemctl is-active --quiet frr; then
echo -e "${RED}FRRouting service failed to start${NC}"
systemctl status frr
exit 1
fi
echo -e "${YELLOW}[6/8] Creating FRRouting configuration with prefix lists and route maps...${NC}"
cat > "$VTYSH_CONFIG" << EOF
configure terminal
!
! Basic prefix lists for network classification
ip prefix-list INTERNAL_NETWORKS seq 10 permit 10.0.0.0/8 le 24
ip prefix-list INTERNAL_NETWORKS seq 20 permit 172.16.0.0/12 le 24
ip prefix-list INTERNAL_NETWORKS seq 30 permit 192.168.0.0/16 le 24
!
ip prefix-list CUSTOMER_ROUTES seq 10 permit 203.0.113.0/24
ip prefix-list CUSTOMER_ROUTES seq 20 permit 198.51.100.0/24
ip prefix-list CUSTOMER_ROUTES seq 30 permit 198.51.101.0/24
!
ip prefix-list DEFAULT_ROUTE seq 10 permit 0.0.0.0/0
!
ip prefix-list DENY_ALL seq 10 deny any
!
! Advanced prefix lists with length matching
ip prefix-list AGGREGATE_ROUTES seq 10 permit 10.0.0.0/8 ge 16 le 20
ip prefix-list HOST_ROUTES seq 10 permit 0.0.0.0/0 ge 32
ip prefix-list SMALL_SUBNETS seq 10 permit 0.0.0.0/0 ge 28
!
ip prefix-list TRANSIT_PREFIXES seq 10 deny 10.0.0.0/8 le 32
ip prefix-list TRANSIT_PREFIXES seq 20 deny 172.16.0.0/12 le 32
ip prefix-list TRANSIT_PREFIXES seq 30 deny 192.168.0.0/16 le 32
ip prefix-list TRANSIT_PREFIXES seq 40 permit any
!
! Route map for internal network filtering
route-map FILTER_INTERNAL permit 10
match ip address prefix-list INTERNAL_NETWORKS
set local-preference 200
set community $AS_NUMBER:100
!
route-map FILTER_INTERNAL deny 20
!
! Route map for customer traffic engineering
route-map CUSTOMER_POLICY permit 10
match ip address prefix-list CUSTOMER_ROUTES
set metric 100
set as-path prepend $AS_NUMBER $AS_NUMBER
set community $AS_NUMBER:200
!
route-map CUSTOMER_POLICY permit 20
match ip address prefix-list DEFAULT_ROUTE
set local-preference 50
!
route-map CUSTOMER_POLICY deny 30
!
! Route map for transit provider policies
route-map TRANSIT_IN permit 10
match ip address prefix-list TRANSIT_PREFIXES
set local-preference 150
set community $AS_NUMBER:300
!
route-map TRANSIT_OUT permit 10
match ip address prefix-list INTERNAL_NETWORKS
set as-path prepend $AS_NUMBER
!
route-map TRANSIT_OUT deny 20
!
write memory
exit
EOF
echo -e "${YELLOW}[7/8] Applying FRRouting configuration...${NC}"
# Apply configuration using vtysh
if ! vtysh < "$VTYSH_CONFIG"; then
echo -e "${RED}Failed to apply FRRouting configuration${NC}"
exit 1
fi
# Clean up temporary config file
rm -f "$VTYSH_CONFIG"
echo -e "${YELLOW}[8/8] Verifying installation...${NC}"
# Check if FRRouting is running
if systemctl is-active --quiet frr; then
echo -e "${GREEN}✓ FRRouting service is running${NC}"
else
echo -e "${RED}✗ FRRouting service is not running${NC}"
exit 1
fi
# Check if BGP daemon is enabled
if vtysh -c "show running-config" | grep -q "bgpd=yes"; then
echo -e "${GREEN}✓ BGP daemon is enabled${NC}"
else
echo -e "${YELLOW}! BGP daemon configuration not verified${NC}"
fi
# Verify prefix lists are configured
PREFIX_COUNT=$(vtysh -c "show ip prefix-list" | grep -c "ip prefix-list" || true)
if [ "$PREFIX_COUNT" -gt 0 ]; then
echo -e "${GREEN}✓ Prefix lists configured ($PREFIX_COUNT entries)${NC}"
else
echo -e "${YELLOW}! No prefix lists found${NC}"
fi
# Verify route maps are configured
ROUTEMAP_COUNT=$(vtysh -c "show route-map" | grep -c "route-map" || true)
if [ "$ROUTEMAP_COUNT" -gt 0 ]; then
echo -e "${GREEN}✓ Route maps configured ($ROUTEMAP_COUNT entries)${NC}"
else
echo -e "${YELLOW}! No route maps found${NC}"
fi
echo ""
echo -e "${GREEN}FRRouting installation completed successfully!${NC}"
echo ""
echo "Next steps:"
echo "1. Configure your BGP neighbors using: sudo vtysh"
echo "2. Apply route maps to BGP neighbors with: neighbor X.X.X.X route-map <map-name> in|out"
echo "3. Monitor BGP status with: vtysh -c 'show ip bgp summary'"
echo "4. View prefix lists with: vtysh -c 'show ip prefix-list'"
echo "5. View route maps with: vtysh -c 'show route-map'"
# Disable cleanup trap on successful completion
trap - ERR EXIT
Review the script before running. Execute with: bash install.sh