summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/helpers/vyos-load-balancer.py41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/helpers/vyos-load-balancer.py b/src/helpers/vyos-load-balancer.py
index 5df83b31e..249433f0b 100755
--- a/src/helpers/vyos-load-balancer.py
+++ b/src/helpers/vyos-load-balancer.py
@@ -24,6 +24,7 @@ import time
from vyos.config import Config
from vyos.template import render
from vyos.utils.commit import commit_in_progress
+from vyos.utils.dict import dict_search_args
from vyos.utils.network import get_interface_address
from vyos.utils.process import rc_cmd
from vyos.utils.process import run
@@ -125,6 +126,43 @@ def dynamic_nexthop_update(lb, ifname):
return False
+def restore_default_route(lb: dict, ifname: str) -> None:
+ """
+ Restores a missing default route for a WAN interface in its policy routing table.
+
+ When a link flap or DHCP/PPP renegotiation removes the per-interface default route,
+ this function checks the interface’s assigned table for an existing default entry.
+ If none is found, it determines the proper next-hop (from DHCP, PPP, or static config)
+ and reinstalls the route using:
+ ip route replace table <table_num> default dev <ifname> via <nexthop>
+
+ @param lb Load-balancer state/config dictionary.
+ @param ifname Interface name whose default route should be verified and restored.
+ @returns None — exits quietly if the table number or next-hop cannot be found.
+ """
+ table_num = dict_search_args(lb, 'health_state', ifname, 'table_number')
+ if not table_num:
+ return
+
+ rc, out = rc_cmd(f'ip -j route show default table {table_num}')
+ if rc == 0:
+ rt_table = json.loads(out)
+ if len(rt_table) > 0:
+ return
+ else:
+ if 'dhcp_nexthop' in lb['health_state'][ifname]:
+ if ifname[:5] == 'pppoe':
+ nexthop_addr = parse_ppp_nexthop(ifname)
+ else:
+ nexthop_addr = parse_dhcp_nexthop(ifname)
+ else:
+ nexthop_addr = dict_search_args(lb, 'interface_health', ifname, 'nexthop')
+
+ if nexthop_addr:
+ run(f'ip route replace table {table_num} default dev {ifname} via {nexthop_addr}')
+ else:
+ return
+
def nftables_update(lb):
# Atomically reload nftables table from template
if not os.path.exists(nftables_wlb_conf):
@@ -295,6 +333,9 @@ if __name__ == '__main__':
if dynamic_nexthop_update(lb, ifname):
ip_change = True
+ restore_default_route(lb, ifname)
+
+
if any(state['state_changed'] for ifname, state in lb['health_state'].items()):
if not nftables_update(lb):
break