From 7aa188ccc51acf4e86aa3b41cde26a0a8d938510 Mon Sep 17 00:00:00 2001 From: khramshinr Date: Thu, 28 Mar 2024 17:14:59 +0800 Subject: dhcp-server: T4718: Listen-address is not commit if the ip address is on the interface with vrf --- python/vyos/utils/network.py | 4 ++-- smoketest/scripts/cli/test_service_dhcp-server.py | 22 ++++++++++++++++++++++ src/conf_mode/service_dhcp-server.py | 3 +-- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/python/vyos/utils/network.py b/python/vyos/utils/network.py index b58e02d91..63c9e263d 100644 --- a/python/vyos/utils/network.py +++ b/python/vyos/utils/network.py @@ -307,7 +307,7 @@ def is_ipv6_link_local(addr): return False -def is_addr_assigned(ip_address, vrf=None) -> bool: +def is_addr_assigned(ip_address, vrf=None, include_vrf=False) -> bool: """ Verify if the given IPv4/IPv6 address is assigned to any interface """ from netifaces import interfaces from vyos.utils.network import get_interface_config @@ -318,7 +318,7 @@ def is_addr_assigned(ip_address, vrf=None) -> bool: # 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 24ae2f4e2..3d1f47ece 100755 --- a/smoketest/scripts/cli/test_service_dhcp-server.py +++ b/smoketest/scripts/cli/test_service_dhcp-server.py @@ -501,5 +501,27 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase): # Check for running process self.assertTrue(process_named_running(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', 'default-router', '10.1.10.1']) + self.cli_set(base_path + ['shared-network-name', 'SMOKE-DHCP-NETWORK', 'subnet', '10.1.10.0/24', '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(DHCPD_CONF) + self.assertIn('subnet 10.1.1.0 netmask 255.255.255.252', config) + + 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 90056887a..e910ecdf7 100755 --- a/src/conf_mode/service_dhcp-server.py +++ b/src/conf_mode/service_dhcp-server.py @@ -280,14 +280,13 @@ def verify(dhcp): raise ConfigError(f'DHCP failover requires "{tmp}" to be specified!') 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 else: raise ConfigError(f'listen-address "{address}" not configured on any interface') - if not listen_ok: raise ConfigError('None of the configured subnets have an appropriate primary IP address on any\n' 'broadcast interface configured, nor was there an explicit listen-address\n' -- cgit v1.2.3