From 0d82dfa3725a23969fd6ae02b76b135a29be6df3 Mon Sep 17 00:00:00 2001 From: khramshinr Date: Thu, 28 Mar 2024 16:01:30 +0800 Subject: [PATCH] dhcp-server: T4718: Listen-address is not commit if the ip address is on the interface with vrf --- python/vyos/template.py | 2 +- python/vyos/utils/network.py | 4 +-- .../scripts/cli/test_service_dhcp-server.py | 25 +++++++++++++++++++ src/conf_mode/service_dhcp-server.py | 2 +- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/python/vyos/template.py b/python/vyos/template.py index bde8e3554b..19a469c8fa 100644 --- a/python/vyos/template.py +++ b/python/vyos/template.py @@ -794,7 +794,7 @@ def kea_address_json(addresses): out = [] for address in addresses: - ifname = is_addr_assigned(address, return_ifname=True) + ifname = is_addr_assigned(address, return_ifname=True, include_vrf=True) if not ifname: continue diff --git a/python/vyos/utils/network.py b/python/vyos/utils/network.py index cac59475d7..829124b572 100644 --- a/python/vyos/utils/network.py +++ b/python/vyos/utils/network.py @@ -310,7 +310,7 @@ def is_ipv6_link_local(addr): return False -def is_addr_assigned(ip_address, vrf=None, return_ifname=False) -> bool | str: +def is_addr_assigned(ip_address, vrf=None, return_ifname=False, include_vrf=False) -> bool | str: """ Verify if the given IPv4/IPv6 address is assigned to any interface """ from netifaces import interfaces from vyos.utils.network import get_interface_config @@ -321,7 +321,7 @@ def is_addr_assigned(ip_address, vrf=None, return_ifname=False) -> bool | str: # case there is no need to proceed with this data set - continue loop # with next element tmp = get_interface_config(interface) - if dict_search('master', tmp) != vrf: + if dict_search('master', tmp) != vrf and not include_vrf: continue if is_intf_addr_assigned(interface, ip_address): diff --git a/smoketest/scripts/cli/test_service_dhcp-server.py b/smoketest/scripts/cli/test_service_dhcp-server.py index 24bd14af2d..abf40cd3bb 100755 --- a/smoketest/scripts/cli/test_service_dhcp-server.py +++ b/smoketest/scripts/cli/test_service_dhcp-server.py @@ -738,5 +738,30 @@ def test_dhcp_high_availability(self): self.assertTrue(process_named_running(PROCESS_NAME)) self.assertTrue(process_named_running(CTRL_PROCESS_NAME)) + def test_dhcp_on_interface_with_vrf(self): + self.cli_set(['interfaces', 'ethernet', 'eth1', 'address', '10.1.1.1/30']) + self.cli_set(['interfaces', 'ethernet', 'eth1', 'vrf', 'SMOKE-DHCP']) + self.cli_set(['protocols', 'static', 'route', '10.1.10.0/24', 'interface', 'eth1', 'vrf', 'SMOKE-DHCP']) + self.cli_set(['vrf', 'name', 'SMOKE-DHCP', 'protocols', 'static', 'route', '10.1.10.0/24', 'next-hop', '10.1.1.2']) + self.cli_set(['vrf', 'name', 'SMOKE-DHCP', 'table', '1000']) + self.cli_set(base_path + ['shared-network-name', 'SMOKE-DHCP-NETWORK', 'subnet', '10.1.10.0/24', 'subnet-id', '1']) + self.cli_set(base_path + ['shared-network-name', 'SMOKE-DHCP-NETWORK', 'subnet', '10.1.10.0/24', 'option', 'default-router', '10.1.10.1']) + self.cli_set(base_path + ['shared-network-name', 'SMOKE-DHCP-NETWORK', 'subnet', '10.1.10.0/24', 'option', 'name-server', '1.1.1.1']) + self.cli_set(base_path + ['shared-network-name', 'SMOKE-DHCP-NETWORK', 'subnet', '10.1.10.0/24', 'range', '1', 'start', '10.1.10.10']) + self.cli_set(base_path + ['shared-network-name', 'SMOKE-DHCP-NETWORK', 'subnet', '10.1.10.0/24', 'range', '1', 'stop', '10.1.10.20']) + self.cli_set(base_path + ['listen-address', '10.1.1.1']) + self.cli_commit() + + config = read_file(KEA4_CONF) + obj = loads(config) + + self.verify_config_value(obj, ['Dhcp4', 'interfaces-config'], 'interfaces', ['eth1/10.1.1.1']) + + self.cli_delete(['interfaces', 'ethernet', 'eth1', 'vrf', 'SMOKE-DHCP']) + self.cli_delete(['protocols', 'static', 'route', '10.1.10.0/24', 'interface', 'eth1', 'vrf']) + self.cli_delete(['vrf', 'name', 'SMOKE-DHCP']) + self.cli_commit() + + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/src/conf_mode/service_dhcp-server.py b/src/conf_mode/service_dhcp-server.py index ba3d69b07c..bf4454fdad 100755 --- a/src/conf_mode/service_dhcp-server.py +++ b/src/conf_mode/service_dhcp-server.py @@ -316,7 +316,7 @@ def verify(dhcp): raise ConfigError(f'Invalid CA certificate specified for DHCP high-availability') for address in (dict_search('listen_address', dhcp) or []): - if is_addr_assigned(address): + if is_addr_assigned(address, include_vrf=True): listen_ok = True # no need to probe further networks, we have one that is valid continue