summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2026-10-17 20:55:32 +0200
committerChristian Breunig <christian@breunig.cc>2026-10-17 20:56:35 +0200
commitf353f8533397249d0bcef658a4e6fcd5fffdd856 (patch)
tree802e814ba2e01f73f7643cb0a129dcc3e3b0ea32
parentbd8be7c142269bbe3849ab70e8e26bc2077e3f9b (diff)
downloadvyos-1x-f353f8533397249d0bcef658a4e6fcd5fffdd856.tar.gz
vyos-1x-f353f8533397249d0bcef658a4e6fcd5fffdd856.zip
wlb: T9472: report the initial state of every interface
On start the health daemon forces a state change so the hook learns the initial state of the WAN interfaces. The flag doing so was reset after the first interface, every other interface was only reported once its state actually changed. The flag is now reset after all interfaces have been checked. The existing hook smoketest relied on the old behaviour: it now keeps all hook events and no longer reads a file left over from an earlier run.
-rwxr-xr-xsmoketest/scripts/cli/test_load-balancing_wan.py35
-rwxr-xr-xsrc/helpers/vyos-load-balancer.py4
2 files changed, 37 insertions, 2 deletions
diff --git a/smoketest/scripts/cli/test_load-balancing_wan.py b/smoketest/scripts/cli/test_load-balancing_wan.py
index ed3970abc..5c67778e3 100755
--- a/smoketest/scripts/cli/test_load-balancing_wan.py
+++ b/smoketest/scripts/cli/test_load-balancing_wan.py
@@ -390,9 +390,13 @@ class TestLoadBalancingWan(VyOSUnitTestSHIM.TestCase):
ifname=$WLB_INTERFACE_NAME
state=$WLB_INTERFACE_STATE
-echo "$ifname - $state" > {hook_output_path}
+echo "$ifname - $state" >> {hook_output_path}
"""
+ # the hook reports every interface on start, keep all events and
+ # drop the ones of earlier runs
+ call(f'sudo rm -f {hook_output_path}')
+ self.addCleanup(call, f'sudo rm -f {hook_output_path} {hook_path}')
write_file(hook_path, hook_script)
chmod_755(hook_path)
@@ -848,6 +852,35 @@ printf 'WLB_INTERFACE_NAME=%s WLB_SCRIPT_IFACE=%s\\n' \\
self.cli_set(test + ['ttl-limit', '3'])
self.cli_commit()
self.lab_wait_status(failed)
+ def test_hook_initial_state_all_interfaces(self):
+ # the initial state was only reported to the hook for the first
+ # interface
+ tmpdir = tempfile.TemporaryDirectory()
+ self.addCleanup(tmpdir.cleanup)
+ hook = os.path.join(tmpdir.name, 'hook.sh')
+ log = os.path.join(tmpdir.name, 'hook.log')
+ # the hook runs without PATH
+ write_file(hook, f'#!/bin/sh\n/bin/echo "$WLB_INTERFACE_NAME $WLB_INTERFACE_STATE" >> {log}\n')
+ chmod_755(hook)
+ chmod_755(tmpdir.name)
+
+ isps = ['eth231', 'eth232']
+ self.lab_setup('eth230', isps)
+ for index, ifname in enumerate(isps, start=1):
+ self.lab_health(ifname, index)
+ self.cli_set(base_path + ['wan', 'rule', '10', 'interface', ifname])
+ self.cli_set(base_path + ['wan', 'rule', '10', 'inbound-interface', 'eth230'])
+ self.cli_set(base_path + ['wan', 'hook', hook])
+ self.cli_commit()
+
+ def reported():
+ if not os.path.exists(log):
+ return set()
+ with open(log) as f:
+ return set(f.read().splitlines())
+
+ found, last = self.wait_for_result(reported, {'eth231 ACTIVE', 'eth232 ACTIVE'}, timeout=20)
+ self.assertTrue(found, msg=f'hook reported {last}')
if __name__ == '__main__':
unittest.main(verbosity=2, failfast=VyOSUnitTestSHIM.TestCase.debug_on())
diff --git a/src/helpers/vyos-load-balancer.py b/src/helpers/vyos-load-balancer.py
index d289f1c7f..38ba8d87b 100755
--- a/src/helpers/vyos-load-balancer.py
+++ b/src/helpers/vyos-load-balancer.py
@@ -375,7 +375,6 @@ if __name__ == '__main__':
#Force state changed to trigger the first write
if init == True:
state['state_changed'] = True
- init = False
if state['state_changed']:
state['if_addr'] = get_ipv4_address(ifname)
@@ -386,6 +385,9 @@ if __name__ == '__main__':
restore_default_route(lb, ifname)
+ # every interface reports its initial state
+ init = False
+
if any(state['state_changed'] for ifname, state in lb['health_state'].items()):
if not nftables_update(lb):
break