TTR Networks

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

Saving, reloading and rebooting

✓ 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

Live changes and saved changes

Changes made in vtysh take effect at once, but only in the running daemons. In the lab, lowering ISP 2's prefix limit to 500 worked immediately, and was gone after systemctl restart frr: the file still said 1000.

write memory saves the running configuration to /etc/frr/frr.conf. But it writes the file from scratch: the comments, layout and order of the file you wrote are gone, replaced by FRR's own rendering (it even added frr version 10.3 and no ipv6 forwarding). So choose one way of working:

  • Edit the file, then apply it: keep frr.conf in version control with its comments, apply it with systemctl restart frr (sessions drop for a few seconds, so do it in a quiet moment), and never write memory.
  • Configure in vtysh, then write memory: quick, but the file becomes FRR's, and comments don't survive. Back it up before and after.

Mixing the two is how a carefully commented file disappears.

No reload on Debian 13

Applying a changed file without a restart needs frr-reload.py, which compares the file with the running configuration and applies only the differences. systemctl reload frr runs it. On Debian 13 it fails: the script lives in the frr-pythontools package, which FRR's package recommends but Debian 13 doesn't ship, so there's nothing to install. FRR's running daemons are unaffected; only the reload fails. If you need hitless reloads, install FRR from FRR's own Debian repository (deb.frrouting.org), which includes frr-pythontools; otherwise, restart.

After a reboot

Everything here is an ordinary systemd service, so a reboot is the real test. Twenty-five seconds after the machine started, networkd had configured the interfaces, nftables had loaded the firewall, forwarding was on from sysctl.d, and FRR had both BGP sessions Established and OSPF Full. Check those four things after any reboot of a router.

Live changes, restarts and write memory (real output)
root@edge:~# vtysh -c "conf t" -c "router bgp 64500" -c "address-family ipv4 unicast" -c "neighbor 192.0.2.2 maximum-prefix 500"; vtysh -c "show running-config" | grep "192.0.2.2 maximum"
  neighbor 192.0.2.2 maximum-prefix 500

root@edge:~# systemctl restart frr && sleep 3 && vtysh -c "show running-config" | grep "192.0.2.2 maximum"
  neighbor 192.0.2.2 maximum-prefix 1000

root@edge:~# head -3 /etc/frr/frr.conf; vtysh -c "conf t" -c "router bgp 64500" -c "address-family ipv4 unicast" -c "neighbor 192.0.2.2 maximum-prefix 500" && vtysh -c "write memory"
! /etc/frr/frr.conf on edge: two upstreams by BGP, the office core by OSPF.
frr defaults traditional
hostname edge
Note: this version of vtysh never writes vtysh.conf
Building Configuration...
Integrated configuration saved to /etc/frr/frr.conf
[OK]

root@edge:~# head -5 /etc/frr/frr.conf; grep -c "^!.*[a-z]" /etc/frr/frr.conf
frr version 10.3
frr defaults traditional
hostname edge
log syslog informational
no ipv6 forwarding
0
  • Lines 1–2: A change in vtysh takes effect at once…
  • Lines 4–5: …and is gone after a restart: the file still says 1000.
  • Lines 7–14: The file starts with a comment; write memory saves the running configuration.
  • Lines 16–22: The file now starts with FRR's own header, and no comment lines are left.
systemctl reload frr on Debian 13 (real output)
root@edge:~# systemctl reload frr; echo "exit code $?"; journalctl -u frr --no-pager -o cat -n 2
Job for frr.service failed.
See "systemctl status frr.service" and "journalctl -xeu frr.service" for details.
exit code 1
frr.service: Control process exited, code=exited, status=1/FAILURE
Reload failed for frr.service - FRRouting.

root@edge:~# apt-cache policy frr-pythontools
frr-pythontools:
  Installed: (none)
  Candidate: (none)
  Version table:
  • Lines 1–6: The reload fails…
  • Lines 8–12: …because the frr-pythontools package it needs isn't in Debian 13.
After a reboot (real output)
root@edge:~# ps -o etime=,comm= -p 1; systemctl is-active systemd-networkd nftables frr; sysctl net.ipv4.ip_forward
      00:25 systemd
active
active
active
net.ipv4.ip_forward = 1

root@edge:~# vtysh -c "show bgp summary" | grep -E "^192"; vtysh -c "show ip ospf neighbor" | grep Full; nft list tables
192.0.2.0       4      64501         6         4        3    0    0 00:00:21            2        1 isp1 (primary)
192.0.2.2       4      64502         7         4        3    0    0 00:00:21            2        1 isp2 (backup)
10.255.0.2        1 Full/-          15.528s           34.471s 10.0.0.2        eth2:10.0.0.1                        0     0     0
table inet filter
  • Lines 1–2: The machine started 25 seconds ago.
  • Lines 3–6: networkd, the firewall and FRR are running; forwarding is on.
  • Lines 9–12: Both BGP sessions and OSPF are back, and the firewall is loaded.

Check your understanding

You keep a commented frr.conf in git. How should you apply a change on Debian 13?

  • Edit the file and restart FRR in a quiet moment; never write memory.
  • Make the change in vtysh, then write memory.
  • Edit the file and run systemctl reload frr.
  • Edit the file; FRR rereads it automatically.