Skip to main content
RunBook Academy

VyOSIII · VyOS ArchitectureArchitecture

FRRouting and the routing daemons — the dynamic brain

Intermediate⏱ ~18 minvtyshpsjournalctlvyos

What you'll learn

  • Describe the FRRouting daemon architecture and the role of each daemon
  • Explain how zebra bridges FRRouting and the kernel
  • Use vtysh to inspect routing state from the daemon's view
  • Recognise which daemon owns a routing protocol failure

Prerequisites

Verified against VyOS 1.5.x LTS (circinus) · VyOS 1.4.x (sagitta) — legacy · FRRouting 10.x (VyOS 1.5) · Linux kernel 6.6 LTS (VyOS 1.5 base) · strongSwan 5.9.x (IPsec) · WireGuard 1.0.x (kernel module + userspace tooling) · 2026-08-15

Not yet marked complete on this device.

FRRouting is the userspace routing suite that powers dynamic routing on VyOS. It runs as a collection of cooperating daemons; each daemon owns one routing protocol or service; a central daemon (zebra) bridges them to the kernel. The operator who understands this architecture can find the right daemon to look at when a routing protocol misbehaves.

This lesson is the operator’s foundation in FRRouting: the daemon architecture, the role of each daemon, and the operational interface (vtysh).

FRRouting daemon architecture

flowchart TB
  Z["zebra\nKernel interface"]
  subgraph "Dynamic routing"
    B["bgpd\nBGP"]
    O["ospfd\nOSPFv2"]
    O3["ospf6d\nOSPFv3"]
    R["ripd\nRIP"]
    IS["isisd\nIS-IS"]
    E["eigrpd\nEIGRP"]
    L["ldpd\nLDP"]
    N["nhrpd\nNHRP"]
    P["pimd\nPIM multicast"]
  end
  subgraph "Service daemons"
    BF["bfdd\nBFD"]
    ST["staticd\nStatic routes"]
    W["watchfrr\nSupervisor"]
    M["mgmtd\nManagement / YANG"]
  end

  B --> Z
  O --> Z
  O3 --> Z
  R --> Z
  IS --> Z
  E --> Z
  L --> Z
  N --> Z
  P --> Z
  ST --> Z
  BF --> B
  BF --> O
  W --> Z
  M --> Z

The architecture is modular: each routing protocol runs as its own daemon. The daemons communicate via an internal IPC (the zserv socket) routed through zebra. Zebra translates protocol messages into kernel netlink messages.

The role of each daemon:

  • zebra — the kernel interface. Every other daemon talks to the kernel through zebra.
  • bgpd — BGP. The dominant protocol on the public Internet.
  • ospfd — OSPFv2. Link-state IGP for IPv4.
  • ospf6d — OSPFv3. Link-state IGP for IPv6.
  • ripd — RIP. Distance-vector IGP. Legacy.
  • isisd — IS-IS. Link-state IGP. Used by some service providers.
  • eigrpd — EIGRP. Cisco proprietary.
  • ldpd — LDP. MPLS label distribution.
  • nhrpd — NHRP. Next Hop Resolution Protocol for DMVPN.
  • pimd — PIM. Multicast routing.
  • bfdd — BFD. Sub-second failure detection for any protocol that supports it.
  • staticd — the daemon that owns the FRRouting-configured static routes.
  • watchfrr — the supervisor that restarts failed daemons.
  • mgmtd — the management plane (YANG models).

On a typical VyOS router, only a subset of these daemons runs. The operator who does not run BGP does not start bgpd.

zebra: the kernel interface

Zebra is the most important FRRouting daemon. Without it, no dynamic routing protocol can install routes in the kernel.

sequenceDiagram
  autonumber
  participant B as bgpd
  participant Z as zebra
  participant K as Kernel

  B->>Z: route update (BGP update message)
  Z->>Z: best-path selection
  Z->>K: netlink RTM_NEWROUTE
  K->>Z: netlink acknowledgment
  Z->>B: route install confirmation

When a BGP session receives a new prefix, bgpd updates its BGP table. Zebra is notified via internal IPC. Zebra runs the best-path algorithm for BGP, decides whether the new prefix should be installed, and writes the route to the kernel via netlink. The kernel installs the route and acknowledges via netlink. Zebra confirms to bgpd.

If zebra crashes, the protocol daemons continue running but their routes are no longer installed in the kernel. The operator sees the routes in vtysh show ip route but not in ip route show.

vtysh: the unified interface

vtysh is the FRRouting text interface. It connects to every running daemon and provides a unified CLI for inspection and configuration.

# Enter vtysh
vtysh

# Show running configuration
show running-config

# Show BGP summary
show ip bgp summary

# Show OSPF neighbours
show ip ospf neighbor

# Show the kernel routing table (delegates to zebra)
show ip route

# Exit
exit

vtysh show ip route shows the routing engine’s view. This includes routes from FRRouting’s protocols and routes zebra has received from the kernel (including static and connected).

CommandShows
show ip routeFRRouting’s view (RIB plus kernel via zebra)
show ip bgpBGP table
show ip ospf databaseOSPF link-state database
show ip ospf neighborOSPF neighbours and state
show ip ripRIP routes
show bfd peerBFD peer state
show zebrazebra status and configuration
show running-configFull FRRouting configuration

Configuration and operational state

FRRouting has two distinct views of its state:

  • Configuration — what the daemons are supposed to do. Set via configure mode in vtysh or via the VyOS CLI.
  • Operational state — what the daemons are actually doing. Set by the protocols themselves as they exchange messages with peers.

Configuration and state diverge when the configuration is wrong or the protocols cannot establish sessions. The operator who sees bgpd in Established for a peer but missing routes should check both the configuration (the neighbour is configured correctly) and the operational state (the session is actually exchanging routes).

watchfrr: the supervisor

watchfrr is a small supervisor process that restarts failed daemons. It runs as a system service; configuration is in /etc/frr/watchfrr.conf or in the VyOS configuration.

set system frr watchfrr enable
set system frr watchfrr restart-script /usr/lib/frr/frr-reload.py

The default behaviour: if a daemon crashes, watchfrr restarts it after a brief delay. The restart takes a few seconds; during that time, the daemon is unavailable.

The operator who needs a faster restart or different behaviour configures watchfrr accordingly.

Failure modes

Zebra crashes and routes disappear

Zebra crashes. The kernel loses all FRRouting-managed routes. The operator sees ip route show show only connected and static routes.

Diagnostic:

  • systemctl status frr shows zebra status.
  • journalctl -u frr shows the crash log.

Fix:

  • Restart zebra: systemctl restart frr or the VyOS equivalent.
  • Investigate the crash cause from the log.

bgpd cannot establish a session

BGP session is stuck in Active. The router is not receiving BGP updates.

Diagnostic:

  • vtysh show ip bgp summary shows the peer in Active.
  • vtysh show ip bgp neighbor <ip> shows the timers and counters.

Fix: standard BGP troubleshooting — check TCP/179, ACLs, source address, AS numbers, MD5.

OSPF neighbour stuck in EXSTART/EXCHANGE

OSPF adjacency does not reach Full.

Diagnostic:

  • vtysh show ip ospf neighbor shows the state.
  • vtysh show ip ospf interface shows the interface parameters.

Fix: standard OSPF troubleshooting — MTU, area, authentication, network type.

Validation

The validation sequence for “FRRouting is wrong”:

  1. All daemons are running: vtysh show daemons lists running daemons.
  2. The configuration is loaded: vtysh show running-config shows the expected configuration.
  3. The zebra daemon is talking to the kernel: vtysh show zebra shows the zebra status.
  4. The protocols have sessions: vtysh show ip bgp summary (for BGP), vtysh show ip ospf neighbor (for OSPF), etc.
  5. The kernel has the routes: ip route show and vtysh show ip route agree.

If the protocols’ sessions are up but the kernel lacks the routes, zebra has a problem. If zebra is fine but the protocols’ sessions are down, the protocols have a problem.

Cross-course references

  • The Linux course’s XIX-Linux-NetFoundations covers the kernel / userspace boundary from the host perspective.
  • The OPNsense course covers the equivalent routing-daemon architecture on FreeBSD (FRRouting is also available on BSD, but the integration differs).
  • The lessons on BGP, OSPF, and other protocols later in the course cover each protocol in depth.

Quiz

Knowledge check · 4 questions

  1. Q1. You commit a BGP neighbour. After commit, `vtysh show ip bgp summary` shows the session as Established. `ip route show` does not list the prefixes from this peer. What is the most likely cause?

    R1 has a BGP neighbour configured and committed. After commit, `vtysh show ip bgp summary` shows the session as Established. `vtysh show ip route` lists the prefixes from the peer. `ip route show` does not.

  2. Q2. Which daemon is the bridge between FRRouting and the Linux kernel?

  3. Q3. When a FRRouting daemon crashes, watchfrr restarts it automatically.

  4. Q4. OSPF neighbour is stuck in EXSTART. The interface MTUs match. The areas match. What is the most likely cause?

    R1 has an OSPF neighbour over a point-to-point link. The MTU on both sides is 1500. The OSPF area on both sides is 0. The interface type is point-to-point on both sides. Authentication is configured and matches. The neighbour state stays in EXSTART.

Passing score: 75%. Answers are checked in this browser.

Production discipline

FRRouting is the dynamic brain of a VyOS router. The daemons must be running for the dynamic routes to be installed. The configuration must be correct for the sessions to establish. The kernel must accept the netlink messages for the routes to appear.

Plan the FRRouting configuration once. Document the daemon set. Plan the zebra / watchfrr recovery. Then routing either works or fails predictably.