summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2026-09-04 22:26:37 +0200
committerChristian Breunig <christian@breunig.cc>2026-09-04 22:26:37 +0200
commit3f1e103d6774159fb7835c3562a1c1ab834cfd7a (patch)
treee6e79bebccba0921477705d8a9f21675c889f218 /python
parent9a7d5b27cd908473b7cd9e16fc0d1bbe7e983d2e (diff)
downloadvyos-1x-3f1e103d6774159fb7835c3562a1c1ab834cfd7a.tar.gz
vyos-1x-3f1e103d6774159fb7835c3562a1c1ab834cfd7a.zip
static: T9278: honor dhcp-interface routes in dedicated routing tables
get_dhcp_route_interfaces() only walked "protocols static route <prefix> dhcp-interface", so routes configured below "protocols static table <id> route <prefix> dhcp-interface" never made it into the interface list. Both nodes share the same include/static/static-route.xml.i definition and both are rendered from the DHCP lease via the get_dhcp_router() filter in staticd.frr.j2, so they depend on the current lease in exactly the same way. As a result the affected interfaces were missing from the DHCP gateway cache used for FRR change detection. A lease event on an interface referenced only by a table based route would compare equal to the cached state and the re-render requested by the dhclient hook was skipped, leaving the stale gateway in the rendered configuration. Iterate the route sections of every table in addition to the top level ones. Only IPv4 routes are considered, as "dhcp-interface" does not exist for route6. Named VRFs have no table node, but the collection is shared and stays correct there as well.
Diffstat (limited to 'python')
-rw-r--r--python/vyos/frrender.py17
1 files changed, 14 insertions, 3 deletions
diff --git a/python/vyos/frrender.py b/python/vyos/frrender.py
index b3f2718ac..1ea49abe4 100644
--- a/python/vyos/frrender.py
+++ b/python/vyos/frrender.py
@@ -695,18 +695,29 @@ def get_dhcp_route_interfaces(config_dict) -> set:
DHCP lease. Two CLI constructs end up reading the DHCP lease file via the
"get_dhcp_router" Jinja filter and thus depend on the current lease:
- - "protocols static route <prefix> dhcp-interface <ifname>"
+ - "protocols static route <prefix> dhcp-interface <ifname>", either directly
+ or below "protocols static table <id>"
- the default route implied by "interfaces <type> <ifname> address dhcp"
Both variants exist in the default VRF as well as inside any named VRF.
"""
interfaces = set()
+ def _add_from_routes(route_conf):
+ if not isinstance(route_conf, dict):
+ return
+ for prefix_options in route_conf.values():
+ interfaces.update(prefix_options.get('dhcp_interface', []))
+
def _add_from_static(static_conf):
if not isinstance(static_conf, dict):
return
- for prefix_options in static_conf.get('route', {}).values():
- interfaces.update(prefix_options.get('dhcp_interface', []))
+ _add_from_routes(static_conf.get('route'))
+ # Routes in a dedicated routing table use the same "dhcp-interface"
+ # node, thus they depend on the DHCP lease in the very same way
+ for table_config in static_conf.get('table', {}).values():
+ if isinstance(table_config, dict):
+ _add_from_routes(table_config.get('route'))
for ifname, if_config in static_conf.get('dhcp', {}).items():
# An interface explicitly opting out of the default route does not
# contribute a route, thus a lease change is irrelevant for it