summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2026-10-10 22:10:32 +0200
committerChristian Breunig <christian@breunig.cc>2026-10-10 22:10:32 +0200
commit1748e1eff7db459bfcaa69b28862dd2740fe1745 (patch)
tree5d0484258b28e9191285842e13a2efaae951d44e
parent313ced7111e5f313ac6496db9cd92fac83f7b5b3 (diff)
downloadvyos-1x-1748e1eff7db459bfcaa69b28862dd2740fe1745.tar.gz
vyos-1x-1748e1eff7db459bfcaa69b28862dd2740fe1745.zip
frrender: T9454: render FRR after a DHCP lease only once the commit completed
A lease event during a commit rendered FRR from the active configuration, which the commit has not replaced yet. When the lease arrived after the commit's own FRR render but before the commit finished, the stale render was applied and nothing corrected it: moving a DHCP interface into a VRF left the VRF without its default route. The lease hook now starts the render detached and the render waits for the running commit to complete. Detaching is required, as a commit stopping the DHCP client waits for the release hook. Waiting is opt-in, as the commit itself uses the same helper when it cannot reach the configuration daemon.
-rwxr-xr-xsrc/etc/dhcp/dhclient-exit-hooks.d/98-vyos-static-routes-dhclient-hook6
-rwxr-xr-xsrc/helpers/vyos-frr-render.py15
2 files changed, 19 insertions, 2 deletions
diff --git a/src/etc/dhcp/dhclient-exit-hooks.d/98-vyos-static-routes-dhclient-hook b/src/etc/dhcp/dhclient-exit-hooks.d/98-vyos-static-routes-dhclient-hook
index 2c895ffd6..7c432d46c 100755
--- a/src/etc/dhcp/dhclient-exit-hooks.d/98-vyos-static-routes-dhclient-hook
+++ b/src/etc/dhcp/dhclient-exit-hooks.d/98-vyos-static-routes-dhclient-hook
@@ -34,5 +34,7 @@ elif [ "$reason" != "BOUND" ] && [ "$reason" != "EXPIRE" ] && [ "$reason" != "RE
return 0
fi
-# Reconcile the rendered FRR configuration with the current lease
-sudo /usr/libexec/vyos/vyos-frr-render.py
+# Reconcile the rendered FRR configuration with the current lease. The render
+# waits for a running commit, which may itself wait for this dhclient to stop -
+# do not block on it.
+sudo systemd-run --no-block --collect --quiet /usr/libexec/vyos/vyos-frr-render.py --after-commit
diff --git a/src/helpers/vyos-frr-render.py b/src/helpers/vyos-frr-render.py
index 739b56410..bffdda4a2 100755
--- a/src/helpers/vyos-frr-render.py
+++ b/src/helpers/vyos-frr-render.py
@@ -23,12 +23,16 @@ to running the conf-mode scripts directly."""
import sys
+from argparse import ArgumentParser
+from time import sleep
+
from vyos.config import Config
from vyos.frrender import FRRender
from vyos.frrender import frr_applied_config_file
from vyos.frrender import frr_config_file
from vyos.frrender import frr_render_lock
from vyos.frrender import get_frrender_dict
+from vyos.utils.commit import commit_in_progress2
from vyos.utils.file import read_file
from vyos import ConfigError
@@ -50,6 +54,17 @@ def render() -> None:
if __name__ == '__main__':
+ parser = ArgumentParser()
+ # The active configuration only changes once a commit is complete. Reading
+ # it earlier renders the pre-commit state, which the commit then never
+ # corrects as its own FRR render has already run. Not for callers which
+ # are part of a commit - they would wait for themselves.
+ parser.add_argument('--after-commit', action='store_true',
+ help='Wait for a running commit to complete first')
+ args = parser.parse_args()
+
+ while args.after_commit and commit_in_progress2():
+ sleep(0.25)
try:
with frr_render_lock():
render()