Chapter 53: FRRouting (FRR) - Open Source Routing Suite
Learning Objectives
By the end of this chapter, you will be able to: - Understand FRRouting architecture and capabilities - Deploy FRR containers in ContainerLab environments - Configure multiple routing protocols using FRR - Implement advanced routing features with open source tools - Integrate FRR with commercial network equipment
Introduction to FRRouting (FRR)
What is FRRouting?
FRRouting (FRR) is a free and open source Internet routing protocol suite for Linux and Unix platforms. It implements BGP, OSPF, RIP, IS-IS, PIM, LDP, BFD, and Babel routing protocols. FRR is a fork of Quagga and is actively developed by a community of network engineers and developers.
Key FRR Features
- Multi-Protocol Support: BGP, OSPF, IS-IS, RIP, PIM, LDP, BFD
- High Performance: Optimized for modern hardware
- Standards Compliant: Implements RFC standards
- Extensible: Plugin architecture for new features
- Production Ready: Used by major cloud providers and ISPs
- Container Native: Excellent ContainerLab integration
FRR Architecture
Core Components
- zebra: Kernel routing manager and interface to other daemons
- bgpd: BGP daemon
- ospfd: OSPF daemon
- ospf6d: OSPFv3 daemon
- ripd: RIP daemon
- ripngd: RIPng daemon
- isisd: IS-IS daemon
- pimd: PIM daemon
- ldpd: LDP daemon
- bfdd: BFD daemon
FRR Lab Environment
Basic FRR Lab Setup
# FRR comprehensive lab
name: frr-routing-lab
prefix: frr
topology:
nodes:
# FRR routers
frr-r1:
kind: linux
image: frrouting/frr:latest
mgmt-ipv4: 172.20.20.10
exec:
- ip addr add 10.1.12.1/30 dev eth1
- ip addr add 10.1.13.1/30 dev eth2
- ip addr add 192.168.1.1/24 dev eth3
- ip link set eth1 up
- ip link set eth2 up
- ip link set eth3 up
binds:
- ./configs/frr-r1:/etc/frr
frr-r2:
kind: linux
image: frrouting/frr:latest
mgmt-ipv4: 172.20.20.11
exec:
- ip addr add 10.1.12.2/30 dev eth1
- ip addr add 10.1.24.1/30 dev eth2
- ip addr add 192.168.2.1/24 dev eth3
- ip link set eth1 up
- ip link set eth2 up
- ip link set eth3 up
binds:
- ./configs/frr-r2:/etc/frr
frr-r3:
kind: linux
image: frrouting/frr:latest
mgmt-ipv4: 172.20.20.12
exec:
- ip addr add 10.1.13.2/30 dev eth1
- ip addr add 10.1.34.1/30 dev eth2
- ip addr add 192.168.3.1/24 dev eth3
- ip link set eth1 up
- ip link set eth2 up
- ip link set eth3 up
binds:
- ./configs/frr-r3:/etc/frr
frr-r4:
kind: linux
image: frrouting/frr:latest
mgmt-ipv4: 172.20.20.13
exec:
- ip addr add 10.1.24.2/30 dev eth1
- ip addr add 10.1.34.2/30 dev eth2
- ip addr add 192.168.4.1/24 dev eth3
- ip link set eth1 up
- ip link set eth2 up
- ip link set eth3 up
binds:
- ./configs/frr-r4:/etc/frr
# BGP route reflector
frr-rr:
kind: linux
image: frrouting/frr:latest
mgmt-ipv4: 172.20.20.14
exec:
- ip addr add 10.1.15.1/30 dev eth1
- ip addr add 10.1.25.1/30 dev eth2
- ip addr add 10.1.35.1/30 dev eth3
- ip addr add 10.1.45.1/30 dev eth4
- ip link set eth1 up
- ip link set eth2 up
- ip link set eth3 up
- ip link set eth4 up
binds:
- ./configs/frr-rr:/etc/frr
# Test clients
client1:
kind: linux
image: alpine:latest
exec:
- ip addr add 192.168.1.10/24 dev eth1
- ip route add default via 192.168.1.1
client2:
kind: linux
image: alpine:latest
exec:
- ip addr add 192.168.2.10/24 dev eth1
- ip route add default via 192.168.2.1
client3:
kind: linux
image: alpine:latest
exec:
- ip addr add 192.168.3.10/24 dev eth1
- ip route add default via 192.168.3.1
client4:
kind: linux
image: alpine:latest
exec:
- ip addr add 192.168.4.10/24 dev eth1
- ip route add default via 192.168.4.1
links:
# Core network mesh
- endpoints: ["frr-r1:eth1", "frr-r2:eth1"]
- endpoints: ["frr-r1:eth2", "frr-r3:eth1"]
- endpoints: ["frr-r2:eth2", "frr-r4:eth1"]
- endpoints: ["frr-r3:eth2", "frr-r4:eth2"]
# Route reflector connections
- endpoints: ["frr-rr:eth1", "frr-r1:eth4"]
- endpoints: ["frr-rr:eth2", "frr-r2:eth4"]
- endpoints: ["frr-rr:eth3", "frr-r3:eth4"]
- endpoints: ["frr-rr:eth4", "frr-r4:eth4"]
# Client connections
- endpoints: ["frr-r1:eth3", "client1:eth1"]
- endpoints: ["frr-r2:eth3", "client2:eth1"]
- endpoints: ["frr-r3:eth3", "client3:eth1"]
- endpoints: ["frr-r4:eth3", "client4:eth1"]FRR Configuration Files
Basic FRR Configuration Structure
# Create configuration directories
mkdir -p configs/frr-r1 configs/frr-r2 configs/frr-r3 configs/frr-r4 configs/frr-rr
# FRR daemon configuration
cat > configs/frr-r1/daemons << 'EOF'
# FRR daemon configuration
bgpd=yes
ospfd=yes
ospf6d=no
ripd=no
ripngd=no
isisd=no
pimd=no
ldpd=no
nhrpd=no
eigrpd=no
babeld=no
sharpd=no
pbrd=no
bfdd=yes
fabricd=no
vrrpd=no
# Integrated config file
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"
bfdd_options=" -A 127.0.0.1"
EOFOSPF Configuration
# FRR-R1 OSPF Configuration
cat > configs/frr-r1/frr.conf << 'EOF'
frr version 8.4
frr defaults traditional
hostname frr-r1
log syslog informational
service integrated-vtysh-config
!
interface eth1
description To-FRR-R2
ip address 10.1.12.1/30
ip ospf area 0
ip ospf hello-interval 5
ip ospf dead-interval 20
!
interface eth2
description To-FRR-R3
ip address 10.1.13.1/30
ip ospf area 0
!
interface eth3
description LAN-Network
ip address 192.168.1.1/24
ip ospf area 1
!
interface lo
ip address 1.1.1.1/32
ip ospf area 0
!
router ospf
ospf router-id 1.1.1.1
log-adjacency-changes detail
area 1 range 192.168.1.0/24
passive-interface eth3
!
line vty
!
EOFBGP Configuration
# FRR-R1 BGP Configuration
cat > configs/frr-r1/frr.conf << 'EOF'
frr version 8.4
frr defaults traditional
hostname frr-r1
log syslog informational
service integrated-vtysh-config
!
interface eth1
description To-FRR-R2
ip address 10.1.12.1/30
!
interface eth2
description To-FRR-R3
ip address 10.1.13.1/30
!
interface eth3
description LAN-Network
ip address 192.168.1.1/24
!
interface eth4
description To-Route-Reflector
ip address 10.1.15.2/30
!
interface lo
ip address 1.1.1.1/32
!
router bgp 65001
bgp router-id 1.1.1.1
bgp log-neighbor-changes
no bgp default ipv4-unicast
neighbor 10.1.15.1 remote-as 65001
neighbor 10.1.15.1 description Route-Reflector
neighbor 10.1.15.1 update-source lo
!
address-family ipv4 unicast
network 192.168.1.0/24
neighbor 10.1.15.1 activate
neighbor 10.1.15.1 route-reflector-client
exit-address-family
!
line vty
!
EOFFRR Protocol Configuration
OSPF with FRR
Multi-Area OSPF Setup
# Deploy FRR lab
containerlab deploy -t frr-routing-lab.yml
# Connect to FRR-R1 and configure OSPF
docker exec -it clab-frr-frr-r1 vtysh
# Enter configuration mode
configure terminal
# Configure OSPF
router ospf
ospf router-id 1.1.1.1
log-adjacency-changes detail
area 1 range 192.168.0.0/22
area 1 stub
passive-interface eth3
network 10.1.12.0/30 area 0
network 10.1.13.0/30 area 0
network 192.168.1.0/24 area 1
network 1.1.1.1/32 area 0
# Verify OSPF configuration
show ip ospf neighbor
show ip ospf database
show ip route ospfOSPF Authentication
# Configure OSPF authentication
interface eth1
ip ospf message-digest-key 1 md5 SecureOSPFKey123
router ospf
area 0 authentication message-digest
# Verify authentication
show ip ospf interface eth1BGP with FRR
eBGP Configuration
# Configure eBGP on FRR-R1
configure terminal
router bgp 65001
bgp router-id 1.1.1.1
bgp log-neighbor-changes
no bgp default ipv4-unicast
# eBGP neighbor
neighbor 10.1.12.2 remote-as 65002
neighbor 10.1.12.2 description FRR-R2-eBGP
address-family ipv4 unicast
network 192.168.1.0/24
neighbor 10.1.12.2 activate
neighbor 10.1.12.2 soft-reconfiguration inbound
exit-address-family
# Verify BGP
show bgp summary
show bgp neighbors
show ip route bgpRoute Reflector Configuration
# Configure route reflector on FRR-RR
configure terminal
router bgp 65001
bgp router-id 5.5.5.5
bgp cluster-id 1.1.1.1
# Route reflector clients
neighbor 1.1.1.1 remote-as 65001
neighbor 1.1.1.1 update-source lo
neighbor 2.2.2.2 remote-as 65001
neighbor 2.2.2.2 update-source lo
neighbor 3.3.3.3 remote-as 65001
neighbor 3.3.3.3 update-source lo
neighbor 4.4.4.4 remote-as 65001
neighbor 4.4.4.4 update-source lo
address-family ipv4 unicast
neighbor 1.1.1.1 activate
neighbor 1.1.1.1 route-reflector-client
neighbor 2.2.2.2 activate
neighbor 2.2.2.2 route-reflector-client
neighbor 3.3.3.3 activate
neighbor 3.3.3.3 route-reflector-client
neighbor 4.4.4.4 activate
neighbor 4.4.4.4 route-reflector-client
exit-address-familyIS-IS with FRR
Basic IS-IS Configuration
# Enable IS-IS daemon
# Edit /etc/frr/daemons: isisd=yes
# Configure IS-IS
configure terminal
router isis 1
net 49.0001.0000.0000.0001.00
is-type level-2-only
log-adjacency-changes
interface eth1
ip router isis 1
isis circuit-type level-2-only
isis hello-interval 3
isis hello-multiplier 3
interface lo
ip router isis 1
isis circuit-type level-2-only
isis passive
# Verify IS-IS
show isis neighbor
show isis database
show ip route isisAdvanced FRR Features
BFD (Bidirectional Forwarding Detection)
# Configure BFD for fast convergence
configure terminal
# Enable BFD globally
bfd
peer 10.1.12.2
detect-multiplier 3
receive-interval 300
transmit-interval 300
exit
# Enable BFD for OSPF
router ospf
bfd all-interfaces
# Enable BFD for BGP
router bgp 65001
neighbor 10.1.12.2 bfd
# Verify BFD
show bfd peers
show bfd peer 10.1.12.2Route Maps and Filtering
# Configure route maps
configure terminal
# Create access lists
ip prefix-list CUSTOMER-ROUTES seq 10 permit 192.168.0.0/16 le 24
ip prefix-list PROVIDER-ROUTES seq 10 permit 0.0.0.0/0 le 32
# Create route map
route-map CUSTOMER-IN permit 10
match ip address prefix-list CUSTOMER-ROUTES
set local-preference 200
route-map CUSTOMER-IN permit 20
set local-preference 100
# Apply to BGP neighbor
router bgp 65001
neighbor 10.1.12.2 route-map CUSTOMER-IN in
# Verify route map
show route-map
show bgp neighbors 10.1.12.2 received-routesMulticast with PIM
# Enable PIM daemon
# Edit /etc/frr/daemons: pimd=yes
# Configure PIM
configure terminal
# Enable multicast forwarding
ip multicast-routing
# Configure PIM on interfaces
interface eth1
ip pim sparse-mode
ip igmp
interface eth2
ip pim sparse-mode
ip igmp
# Configure RP (Rendezvous Point)
ip pim rp 1.1.1.1 224.0.0.0/4
# Verify PIM
show ip pim neighbor
show ip pim rp-info
show ip mrouteFRR Integration with Commercial Equipment
FRR with Cisco Integration
# Mixed FRR and Cisco lab
name: frr-cisco-integration
topology:
nodes:
frr-router:
kind: linux
image: frrouting/frr:latest
exec:
- ip addr add 10.1.12.1/30 dev eth1
- ip link set eth1 up
binds:
- ./configs/frr-mixed:/etc/frr
cisco-router:
kind: cisco_iosxe
image: cisco/iosxe:latest
startup-config: |
hostname Cisco-Router
!
interface GigabitEthernet0/0/0
ip address 10.1.12.2 255.255.255.252
no shutdown
!
router bgp 65002
bgp router-id 2.2.2.2
neighbor 10.1.12.1 remote-as 65001
network 203.0.113.0 mask 255.255.255.0
!
links:
- endpoints: ["frr-router:eth1", "cisco-router:eth1"]Protocol Interoperability Testing
# Test OSPF interoperability
docker exec -it clab-frr-cisco-integration-frr-router vtysh -c "show ip ospf neighbor"
docker exec -it clab-frr-cisco-integration-cisco-router cli -c "show ip ospf neighbor"
# Test BGP interoperability
docker exec -it clab-frr-cisco-integration-frr-router vtysh -c "show bgp summary"
docker exec -it clab-frr-cisco-integration-cisco-router cli -c "show bgp summary"FRR Monitoring and Troubleshooting
FRR Diagnostic Commands
# System information
show version
show memory
show thread cpu
# Interface information
show interface
show interface eth1
show ip interface
# Routing information
show ip route
show ip route summary
show ip route 192.168.1.0/24
# Protocol-specific commands
show ip ospf
show ip ospf neighbor detail
show ip ospf database
show bgp summary
show bgp neighbors
show isis neighbor
show bfd peersFRR Logging and Debugging
# Configure logging
configure terminal
log file /var/log/frr/frr.log informational
log syslog informational
# Enable debugging (use carefully)
debug ospf packet all
debug bgp updates
debug isis adj-packets
# View logs
show loggingPerformance Monitoring
# Monitor FRR performance
show thread cpu
show memory
show zebra
# Interface statistics
show interface eth1
show ip route summary
# Protocol statistics
show ip ospf statistics
show bgp statisticsFRR Automation and Scripting
FRR Configuration Automation
#!/usr/bin/env python3
# frr_config_manager.py
import subprocess
import json
import time
class FRRManager:
def __init__(self, container_name):
self.container_name = container_name
def execute_vtysh_command(self, command):
"""Execute vtysh command in FRR container"""
cmd = f"docker exec {self.container_name} vtysh -c '{command}'"
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
return result.stdout, result.stderr
def configure_ospf(self, router_id, networks):
"""Configure OSPF on FRR router"""
commands = [
"configure terminal",
f"router ospf",
f"ospf router-id {router_id}",
"log-adjacency-changes detail"
]
for network in networks:
commands.append(f"network {network['network']} area {network['area']}")
commands.append("exit")
for cmd in commands:
stdout, stderr = self.execute_vtysh_command(cmd)
if stderr:
print(f"Error executing '{cmd}': {stderr}")
def configure_bgp(self, asn, router_id, neighbors):
"""Configure BGP on FRR router"""
commands = [
"configure terminal",
f"router bgp {asn}",
f"bgp router-id {router_id}",
"bgp log-neighbor-changes",
"no bgp default ipv4-unicast"
]
for neighbor in neighbors:
commands.extend([
f"neighbor {neighbor['ip']} remote-as {neighbor['asn']}",
f"neighbor {neighbor['ip']} description {neighbor.get('description', '')}",
"address-family ipv4 unicast",
f"neighbor {neighbor['ip']} activate",
"exit-address-family"
])
commands.append("exit")
for cmd in commands:
stdout, stderr = self.execute_vtysh_command(cmd)
if stderr:
print(f"Error executing '{cmd}': {stderr}")
def get_routing_table(self):
"""Get routing table from FRR"""
stdout, stderr = self.execute_vtysh_command("show ip route json")
if not stderr:
try:
return json.loads(stdout)
except json.JSONDecodeError:
return None
return None
def get_bgp_summary(self):
"""Get BGP summary from FRR"""
stdout, stderr = self.execute_vtysh_command("show bgp summary json")
if not stderr:
try:
return json.loads(stdout)
except json.JSONDecodeError:
return None
return None
# Usage example
if __name__ == '__main__':
frr = FRRManager('clab-frr-frr-r1')
# Configure OSPF
networks = [
{'network': '10.1.12.0/30', 'area': '0'},
{'network': '192.168.1.0/24', 'area': '1'}
]
frr.configure_ospf('1.1.1.1', networks)
# Configure BGP
neighbors = [
{'ip': '10.1.12.2', 'asn': '65002', 'description': 'FRR-R2'}
]
frr.configure_bgp('65001', '1.1.1.1', neighbors)
# Get routing information
routes = frr.get_routing_table()
if routes:
print("Routing table:", json.dumps(routes, indent=2))FRR Best Practices
Configuration Management
- Version Control: Store FRR configurations in Git
- Templating: Use Jinja2 templates for consistent configs
- Validation: Test configurations before deployment
- Backup: Regular configuration backups
- Documentation: Document network design and changes
Performance Optimization
# Optimize FRR performance
configure terminal
# Increase BGP keepalive frequency
router bgp 65001
timers bgp 30 90
# Optimize OSPF timers
router ospf
timers throttle spf 200 400 10000
timers throttle lsa 200 400 10000
# Enable BFD for fast convergence
bfd
peer 10.1.12.2
detect-multiplier 3
receive-interval 100
transmit-interval 100Security Hardening
# FRR security configuration
configure terminal
# BGP security
router bgp 65001
neighbor 10.1.12.2 password SecureBGPKey123
neighbor 10.1.12.2 ttl-security hops 1
# OSPF security
interface eth1
ip ospf message-digest-key 1 md5 SecureOSPFKey456
router ospf
area 0 authentication message-digest
# Access control
access-list 10 permit 10.1.12.0 0.0.0.3
line vty
access-class 10 inSummary
FRRouting provides a powerful, open-source alternative to commercial routing platforms. Its comprehensive protocol support, container-native design, and active development community make it an excellent choice for learning, testing, and production deployments. Understanding FRR capabilities enables cost-effective network implementations while maintaining enterprise-grade functionality.
Key concepts covered: - FRR architecture and daemon structure - Multi-protocol routing configuration (OSPF, BGP, IS-IS) - Advanced features (BFD, route maps, multicast) - Integration with commercial equipment - Automation and monitoring techniques - Performance optimization and security
In the next chapter, we’ll explore VyOS, another powerful open-source network operating system with comprehensive routing and security features.
Review Questions
- What are the main advantages of FRR over commercial routing platforms?
- How do you configure multi-area OSPF in FRR?
- What is the role of the zebra daemon in FRR architecture?
- How do you implement BGP route reflection with FRR?
- What are best practices for FRR security hardening?
Hands-on Exercises
Exercise 1: Basic FRR Deployment
- Deploy the FRR routing lab
- Configure OSPF on all routers
- Verify neighbor relationships and routing tables
- Test end-to-end connectivity
Exercise 2: BGP Configuration
- Configure eBGP between different autonomous systems
- Implement route reflector for iBGP scaling
- Apply route maps for traffic engineering
- Monitor BGP convergence and path selection
Exercise 3: Advanced Features
- Configure BFD for fast convergence
- Implement IS-IS as alternative IGP
- Set up PIM for multicast routing
- Test protocol interoperability with commercial equipment
Exercise 4: FRR Automation
- Create Python scripts for FRR configuration management
- Implement automated monitoring and alerting
- Develop configuration templates and validation
- Build CI/CD pipeline for FRR deployments