OSPF Configuration with FRRouting

OSPF (Open Shortest Path First) is a link-state routing protocol widely used for dynamic routing within an organization's network. This guide covers configuring OSPF with FRRouting on Linux, managing areas, tuning cost metrics, handling adjacency, redistributing routes, and troubleshooting OSPF convergence issues.

Prerequisites

  • Ubuntu 20.04/22.04 or CentOS/Rocky Linux 8+
  • FRRouting installed (see below)
  • At least two Linux routers with IP connectivity between them
  • Root or sudo access

Install FRRouting

# Ubuntu/Debian
curl -s https://deb.frrouting.org/frr/keys.gpg | \
  sudo gpg --dearmor -o /usr/share/keyrings/frr.gpg

echo "deb [signed-by=/usr/share/keyrings/frr.gpg] \
  https://deb.frrouting.org/frr $(lsb_release -s -c) frr-stable" | \
  sudo tee /etc/apt/sources.list.d/frr.list

sudo apt update && sudo apt install -y frr frr-pythontools

# CentOS/Rocky Linux
sudo dnf install -y https://rpm.frrouting.org/repo/frr-stable-repo-1-0.el9.noarch.rpm
sudo dnf install -y frr

# Enable OSPF daemon
sudo sed -i 's/^ospfd=no/ospfd=yes/' /etc/frr/daemons
sudo sed -i 's/^staticd=no/staticd=yes/' /etc/frr/daemons
sudo systemctl enable frr && sudo systemctl restart frr

Enable OSPF and Basic Setup

# Open the FRR configuration shell
sudo vtysh

configure terminal

# Set router ID (use loopback IP for stability)
router ospf

  # Stable router-id (loopback address)
  ospf router-id 10.255.255.1

  # Advertise networks into OSPF
  # Syntax: network <prefix> area <area-id>
  network 10.0.1.0/30 area 0
  network 10.0.2.0/30 area 0
  network 10.255.255.1/32 area 0    # Loopback

  # Enable OSPF logging
  log-adjacency-changes detail

exit

write memory
end

Network topology for examples:

Router1 (10.255.255.1) --- 10.0.1.0/30 --- Router2 (10.255.255.2)
                       \                  /
                        10.0.2.0/30 --- /

Area Configuration

OSPF organizes routers into areas to limit LSA flooding and reduce routing table size:

sudo vtysh
configure terminal

router ospf

  # Backbone area (area 0) — must be configured on all ABRs
  network 10.0.1.0/30 area 0
  network 10.255.255.1/32 area 0

  # Area 1 — connects to area 0 through this router (ABR role)
  network 192.168.1.0/24 area 1
  network 192.168.2.0/24 area 1

  # Area 2 — another spoke area
  network 172.16.0.0/16 area 2

exit

# Configure virtual link if area 0 connectivity is broken
# (connect area through another area using virtual-link)
router ospf
  area 1 virtual-link 10.255.255.3   # Router ID of the far end

write memory
end

# Verify area assignments
show ip ospf
show ip ospf database

Cost Metrics and Path Selection

OSPF uses cost (inversely proportional to bandwidth) to select the best path:

sudo vtysh
configure terminal

# Set reference bandwidth to match your network (default is 100 Mbps)
# For gigabit networks:
router ospf
  auto-cost reference-bandwidth 1000

exit

# Set interface cost manually (overrides auto-cost)
interface eth0
  ip ospf cost 10       # Lower cost = preferred path

interface eth1
  ip ospf cost 100      # Higher cost = backup path

write memory
end

# Verify current costs
show ip ospf interface eth0

Multi-path (ECMP) with OSPF:

sudo vtysh
configure terminal

router ospf
  # Enable ECMP (equal-cost multi-path)
  maximum-paths 4

write memory
end

# Verify routing table shows multiple paths
show ip route ospf

Adjacency Management

OSPF forms neighbor relationships called adjacencies. Controlling them improves stability and security:

sudo vtysh
configure terminal

# Configure OSPF timers on an interface (faster convergence)
interface eth0
  # Hello interval: 5s, Dead interval: 20s (default: 10/40)
  ip ospf hello-interval 5
  ip ospf dead-interval 20

  # Set interface network type
  # point-to-point: no DR/BDR election (use on P2P links)
  ip ospf network point-to-point

  # broadcast: DR/BDR election (default for Ethernet)
  # ip ospf network broadcast

  # Set DR priority (higher = more likely to become DR)
  # Set to 0 to never become DR
  ip ospf priority 1

exit

# MD5 authentication for OSPF neighbors (prevents rogue routers)
interface eth0
  ip ospf authentication message-digest
  ip ospf message-digest-key 1 md5 MySecretKey

write memory
end

# Verify neighbor state
show ip ospf neighbor
show ip ospf neighbor detail

Expected adjacency states:

StateMeaning
DownNo hellos received
InitHello received, but not bidirectional
2-WayBidirectional communication
ExStartPreparing to exchange LSAs
ExchangeExchanging database descriptors
LoadingRequesting missing LSAs
FullAdjacency complete, routing operational

Route Redistribution

Inject routes from other protocols into OSPF:

sudo vtysh
configure terminal

router ospf

  # Redistribute connected interfaces (non-OSPF networks)
  redistribute connected

  # Redistribute static routes
  redistribute static metric 20 metric-type 2

  # Redistribute BGP routes into OSPF
  redistribute bgp metric-type 1

  # Redistribute with a route map (filter which routes enter OSPF)
  redistribute connected route-map CONN-TO-OSPF

exit

# Route map to filter redistributed routes
ip prefix-list ALLOWED-NETWORKS seq 10 permit 192.168.0.0/16 le 24

route-map CONN-TO-OSPF permit 10
  match ip address prefix-list ALLOWED-NETWORKS
  set metric 50

write memory
end

# Check redistributed routes in OSPF database
show ip ospf database external

Stub and NSSA Areas

Stub areas reduce LSA flooding by blocking external routes:

sudo vtysh
configure terminal

router ospf

  # Configure area 1 as a stub (no external LSAs; gets default route instead)
  area 1 stub

  # Configure area 2 as NSSA (can import external routes locally)
  area 2 nssa

  # Totally stubby area (no external OR inter-area LSAs)
  area 1 stub no-summary

exit

write memory
end

# On the ABR, verify stub configuration
show ip ospf
# Look for: "Area 1 is a stub area"

Troubleshooting

Neighbors stuck in Init or 2-Way:

# Check that hello timers match on both sides
show ip ospf interface eth0
# "Hello due in X sec, Dead interval X sec" — must match peer

# Verify MTU matches (mismatched MTU blocks adjacency)
ip link show eth0 | grep mtu
# If MTU differs, configure on the interface:
sudo vtysh -c "conf t" -c "interface eth0" -c "ip ospf mtu-ignore"

No routes in routing table:

# Verify OSPF is running
show ip ospf

# Check LSA database
show ip ospf database
show ip ospf database router

# Verify network statement covers the interface
show ip ospf interface

# Check for route filtering
show ip route ospf

Adjacency flapping:

# Check FRR logs
sudo journalctl -u frr -n 100 | grep -i "ospf\|adj"

# Monitor neighbor changes in real time
sudo vtysh
debug ospf adj
debug ospf hello
# Watch output for "neighbor state change"
no debug ospf all   # Disable when done

Route redistribution not appearing:

# Verify routes exist in the routing table before redistribution
show ip route connected
show ip route static

# Check OSPF external LSAs
show ip ospf database external

Conclusion

FRRouting's OSPF implementation provides a full-featured, production-ready dynamic routing protocol for Linux servers and network appliances. By configuring areas correctly, tuning cost metrics, and enabling MD5 authentication, you can build resilient and scalable IGP networks. OSPF's fast convergence and hierarchical area design make it the standard choice for enterprise and datacenter internal routing alongside BGP for inter-AS connectivity.