TTR Networks

Intermediate · FRR on Debian: a BGP and OSPF router · section 2 of 10

Install FRR, addresses and forwarding

✓ Lab-tested 4 November 2026 on Debian 13.7, FRR 10.3 (Debian package), FRR 10.2.1 (upstreams), nftables 1.1.3, systemd 257

Debian 13 ships FRR 10.3 in its own repository, so installing it is one command: apt install frr. (FRR also publishes newer releases in its own Debian repository; the configuration in this lesson works on both.)

What you get straight after installing

The frr service is enabled and running, but it isn't routing anything yet. systemctl status shows what's running: watchfrr, which starts the other daemons and restarts any that crash; zebra, which owns the kernel's routing table and interfaces on FRR's behalf; mgmtd, the configuration manager; and staticd for static routes. Each routing protocol is a separate daemon, and every one of them is off in /etc/frr/daemons. You turn on only the ones you use.

Addresses and forwarding

FRR doesn't need to own the interface addresses. On Debian, systemd-networkd is a good way to set them: one small .network file per interface, read at boot. The router also gets a loopback address for its router IDs. A real Debian install already has udev, which networkd waits for; minimal container images don't, and there every link sits in pending until you install it.

The machine must also be allowed to route. Debian ships with IP forwarding off, and the lab's container starts that way too; a file in /etc/sysctl.d/ turns it on now and at every boot.

The versions in this lab (real output)
root@edge:~# cat /etc/debian_version; dpkg-query -W frr nftables systemd; uname -r
13.7
frr	10.3-3+deb13u1
nftables	1.1.3-1
systemd	257.13-1~deb13u1
7.0.14-linuxkit
  • Line 3: FRR 10.3, straight from Debian 13's own repository.
  • Line 5: systemd 257: networkd sets the addresses, and services start the router at boot.
FRR straight after installing (real output)
root@edge:~# systemctl status frr --no-pager | head -17
● frr.service - FRRouting
     Loaded: loaded (/usr/lib/systemd/system/frr.service; enabled; preset: enabled)
     Active: active (running) since Wed 2026-11-04 22:02:01 UTC; 16s ago
 Invocation: 6cb8de65d13345c89e10cdd043cf15e3
       Docs: https://frrouting.readthedocs.io/en/latest/setup.html
    Process: 135 ExecStart=/usr/lib/frr/frrinit.sh start (code=exited, status=0/SUCCESS)
   Main PID: 146 (watchfrr)
     Status: "FRR Operational"
      Tasks: 8 (limit: 9562)
     Memory: 19M (peak: 35.3M)
        CPU: 130ms
     CGroup: /docker/68dabd70d05c7d5877f2dde6ce7bac3e44adce867fa60f2035d700237fbdaeae/system.slice/frr.service
             ├─146 /usr/lib/frr/watchfrr -d -F traditional zebra mgmtd staticd
             ├─156 /usr/lib/frr/zebra -d -F traditional -A 127.0.0.1 -s 90000000
             ├─161 /usr/lib/frr/mgmtd -d -F traditional -A 127.0.0.1
             └─163 /usr/lib/frr/staticd -d -F traditional -A 127.0.0.1


root@edge:~# grep -E "^[a-z0-9]+d=" /etc/frr/daemons
bgpd=no
ospfd=no
ospf6d=no
ripd=no
ripngd=no
isisd=no
pimd=no
pim6d=no
ldpd=no
nhrpd=no
eigrpd=no
babeld=no
sharpd=no
pbrd=no
bfdd=no
fabricd=no
vrrpd=no
pathd=no
  • Line 3: Enabled and running from the moment it's installed…
  • Lines 14–17: …but only watchfrr, zebra, mgmtd and staticd. No routing protocol yet.
  • Lines 21–38: Every routing daemon is off until you turn it on.
/etc/systemd/network/10-isp1.network
# /etc/systemd/network/10-isp1.network: the link to ISP 1 (primary).
[Match]
Name=eth0

[Network]
Address=192.0.2.1/31
LinkLocalAddressing=no
IPv6AcceptRA=no
  • Lines 2–3: Matches the interface by name.
  • Lines 6–8: A fixed address on the /31 link to ISP 1, and no IPv6 on this link.
/etc/systemd/network/11-isp2.network
# /etc/systemd/network/11-isp2.network: the link to ISP 2 (backup).
[Match]
Name=eth1

[Network]
Address=192.0.2.3/31
LinkLocalAddressing=no
IPv6AcceptRA=no
/etc/systemd/network/12-core.network
# /etc/systemd/network/12-core.network: the link to the office's core router.
[Match]
Name=eth2

[Network]
Address=10.0.0.1/30
LinkLocalAddressing=no
IPv6AcceptRA=no
/etc/systemd/network/13-lo.network
# /etc/systemd/network/13-lo.network: a loopback address for the router ID.
[Match]
Name=lo

[Network]
Address=10.255.0.1/32
  • Line 6: A loopback address, used as the BGP and OSPF router ID.
/etc/sysctl.d/99-forwarding.conf
# /etc/sysctl.d/99-forwarding.conf: this machine is a router.
net.ipv4.ip_forward = 1
Addresses and forwarding (real output)
root@edge:~# ls /etc/systemd/network/ && systemctl enable --now systemd-networkd 2>&1 | grep -c "Created symlink"
10-isp1.network
11-isp2.network
12-core.network
13-lo.network
5

root@edge:~# networkctl list --no-pager | grep -E "IDX|eth|lo "; ip -br -4 addr
IDX LINK     TYPE     OPERATIONAL SETUP
  1 lo       loopback routable    configured
  4 gretap0  ether    off         unmanaged
  5 erspan0  ether    off         unmanaged
 11 eth2     ether    routable    configured
 12 eth0     ether    routable    configured
 13 eth1     ether    routable    configured
lo               UNKNOWN        127.0.0.1/8 10.255.0.1/32 
eth2@if5311      UP             10.0.0.1/30 
eth0@if5312      UP             192.0.2.1/31 
eth1@if5313      UP             192.0.2.3/31 

root@edge:~# sysctl net.ipv4.ip_forward; sysctl --system | grep ip_forward
net.ipv4.ip_forward = 0
net.ipv4.ip_forward = 1

root@edge:~# ping -c 1 -W 1 192.0.2.0 | tail -2; ping -c 1 -W 1 192.0.2.2 | tail -2; ping -c 1 -W 1 10.0.0.2 | tail -2
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.071/0.071/0.071/0.000 ms
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.047/0.047/0.047/0.000 ms
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.062/0.062/0.062/0.000 ms
  • Lines 1–6: Four files, one per interface, and networkd enabled at every boot.
  • Lines 9–15: Every link configured: networkd applied the files.
  • Lines 16–19: The addresses, including the router ID on the loopback.
  • Lines 21–23: Forwarding was off, as on a fresh install; the sysctl.d file turns it on.
  • Lines 25–31: Both ISPs and the core router answer.

Check your understanding

Right after apt install frr, why doesn't the router speak BGP yet?

  • bgpd is off in /etc/frr/daemons until you turn it on.
  • The frr service is disabled until you enable it.
  • BGP needs a licence key.
  • Debian's FRR doesn't include BGP.