diff options
author | Christian Poessinger <christian@poessinger.com> | 2021-02-24 21:51:10 +0100 |
---|---|---|
committer | Christian Poessinger <christian@poessinger.com> | 2021-02-24 21:53:54 +0100 |
commit | 9bcd5adf878dfa9f5c621f8b0043ef7f94cdb4b1 (patch) | |
tree | a6a496067d6d4906805cb76232921a513ce898e8 | |
parent | c85615ad50799fd0bedbff2e9b7b1831170290f9 (diff) | |
download | vyos-1x-9bcd5adf878dfa9f5c621f8b0043ef7f94cdb4b1.tar.gz vyos-1x-9bcd5adf878dfa9f5c621f8b0043ef7f94cdb4b1.zip |
route: static: T2450: add missing "dhcp-interface" route option
As thought in the beginning the dhcp-interface route option can not be
superseeded by the interface option. When a route is installed for a DHCP
interface, that interface is usually a broadcast interface which can not be
used for plain interface-based routes.
The old Vyatta logic was migrated to Python where the current received
next-hop address from the DHCP interface is installed as next-hop address.
-rw-r--r-- | data/templates/frr/static_routes_macro.j2 | 6 | ||||
-rw-r--r-- | interface-definitions/include/static-route.xml.i | 15 | ||||
-rw-r--r-- | python/vyos/template.py | 20 |
3 files changed, 40 insertions, 1 deletions
diff --git a/data/templates/frr/static_routes_macro.j2 b/data/templates/frr/static_routes_macro.j2 index b24232ef3..f10b58047 100644 --- a/data/templates/frr/static_routes_macro.j2 +++ b/data/templates/frr/static_routes_macro.j2 @@ -2,6 +2,12 @@ {% if prefix_config.blackhole is defined %} {{ ip_ipv6 }} route {{ prefix }} blackhole {{ prefix_config.blackhole.distance if prefix_config.blackhole.distance is defined }} {{ 'tag ' + prefix_config.blackhole.tag if prefix_config.blackhole.tag is defined }} {{ 'table ' + table if table is defined and table is not none }} {% endif %} +{% if prefix_config.dhcp_interface is defined and prefix_config.dhcp_interface is not none %} +{% set next_hop = prefix_config.dhcp_interface | get_dhcp_router %} +{% if next_hop is defined and next_hop is not none %} +{{ ip_ipv6 }} route {{ prefix }} {{ next_hop }} +{% endif %} +{% endif %} {% if prefix_config.interface is defined and prefix_config.interface is not none %} {% for interface, interface_config in prefix_config.interface.items() if interface_config.disable is not defined %} {{ ip_ipv6 }} route {{ prefix }} {{ interface }} {{ interface_config.distance if interface_config.distance is defined }} {{ 'nexthop-vrf ' + interface_config.vrf if interface_config.vrf is defined }} {{ 'table ' + table if table is defined and table is not none }} diff --git a/interface-definitions/include/static-route.xml.i b/interface-definitions/include/static-route.xml.i index 386582e09..21fcbcd3f 100644 --- a/interface-definitions/include/static-route.xml.i +++ b/interface-definitions/include/static-route.xml.i @@ -31,6 +31,21 @@ </leafNode> </children> </node> + <leafNode name="dhcp-interface"> + <properties> + <help>DHCP interface supplying next-hop IP address</help> + <completionHelp> + <script>${vyos_completion_dir}/list_interfaces.py</script> + </completionHelp> + <valueHelp> + <format>txt</format> + <description>DHCP interface name</description> + </valueHelp> + <constraint> + <validator name="interface-name"/> + </constraint> + </properties> + </leafNode> <tagNode name="interface"> <properties> <help>Next-hop IPv4 router interface</help> diff --git a/python/vyos/template.py b/python/vyos/template.py index 527384d0b..22883b103 100644 --- a/python/vyos/template.py +++ b/python/vyos/template.py @@ -288,7 +288,6 @@ def compare_netmask(netmask1, netmask2): except: return False - @register_filter('isc_static_route') def isc_static_route(subnet, router): # https://ercpe.de/blog/pushing-static-routes-with-isc-dhcp-server @@ -316,3 +315,22 @@ def is_file(filename): if os.path.exists(filename): return os.path.isfile(filename) return False + +@register_filter('get_dhcp_router') +def get_dhcp_router(interface): + """ Static routes can point to a router received by a DHCP reply. This + helper is used to get the current default router from the DHCP reply. + + Returns False of no router is found, returns the IP address as string if + a router is found. + """ + interface = interface.replace('.', '_') + lease_file = f'/var/lib/dhcp/dhclient_{interface}.leases' + if not os.path.exists(lease_file): + return None + + from vyos.util import read_file + for line in read_file(lease_file).splitlines(): + if 'option routers' in line: + (_, _, address) = line.split() + return address.rstrip(';') |