diff options
| author | Viacheslav Hletenko <v.gletenko@vyos.io> | 2026-05-22 11:56:04 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-05-22 11:56:04 +0300 |
| commit | 88b93c96faa5b1016546cbc15d1327b4692a87cc (patch) | |
| tree | 53c60f5bc9c455f9fcaa05e528fa2de562aeb750 | |
| parent | 6fa4967f49e988e4979c611ee9199bb14bef8536 (diff) | |
| parent | e97437c52d2d21b7e662d5569f668615aaee2d98 (diff) | |
| download | vyos-1x-88b93c96faa5b1016546cbc15d1327b4692a87cc.tar.gz vyos-1x-88b93c96faa5b1016546cbc15d1327b4692a87cc.zip | |
Merge pull request #5198 from indrajitr/T8862-dhcpv6-reservation-multi
dhcpv6: T8862: Allow multiple addresses and prefixes for reservations
| -rw-r--r-- | interface-definitions/include/dhcp/dhcpv6-server-common-config.xml.i | 2 | ||||
| -rw-r--r-- | python/vyos/kea.py | 4 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_service_dhcpv6-server.py | 22 | ||||
| -rwxr-xr-x | src/conf_mode/service_dhcpv6-server.py | 19 |
4 files changed, 30 insertions, 17 deletions
diff --git a/interface-definitions/include/dhcp/dhcpv6-server-common-config.xml.i b/interface-definitions/include/dhcp/dhcpv6-server-common-config.xml.i index bc949dd5a..6e40fbcd4 100644 --- a/interface-definitions/include/dhcp/dhcpv6-server-common-config.xml.i +++ b/interface-definitions/include/dhcp/dhcpv6-server-common-config.xml.i @@ -242,6 +242,7 @@ <constraint> <validator name="ipv6-address"/> </constraint> + <multi/> </properties> </leafNode> <leafNode name="ipv6-prefix"> @@ -254,6 +255,7 @@ <constraint> <validator name="ipv6-prefix"/> </constraint> + <multi/> </properties> </leafNode> </children> diff --git a/python/vyos/kea.py b/python/vyos/kea.py index 068e2cf7a..436c134c8 100644 --- a/python/vyos/kea.py +++ b/python/vyos/kea.py @@ -385,10 +385,10 @@ def kea6_parse_subnet(subnet, config): reservation['duid'] = host_config['duid'] if 'ipv6_address' in host_config: - reservation['ip-addresses'] = [host_config['ipv6_address']] + reservation['ip-addresses'] = host_config['ipv6_address'] if 'ipv6_prefix' in host_config: - reservation['prefixes'] = [host_config['ipv6_prefix']] + reservation['prefixes'] = host_config['ipv6_prefix'] if 'option' in host_config: reservation['option-data'] = kea6_parse_options(host_config['option']) diff --git a/smoketest/scripts/cli/test_service_dhcpv6-server.py b/smoketest/scripts/cli/test_service_dhcpv6-server.py index cc0c99866..04aa014b0 100755 --- a/smoketest/scripts/cli/test_service_dhcpv6-server.py +++ b/smoketest/scripts/cli/test_service_dhcpv6-server.py @@ -138,12 +138,16 @@ class TestServiceDHCPv6Server(VyOSUnitTestSHIM.TestCase): for client_suffix in range(1, 4): duid = f'00:01:00:01:12:34:56:78:aa:bb:cc:dd:ee:{client_suffix:02}' - ip = inc_ip(subnet, client_suffix) - prefix = inc_ip(subnet, client_suffix << 64) + '/64' + ip1 = inc_ip(subnet, client_suffix * 2 - 1) + ip2 = inc_ip(subnet, client_suffix * 2) + prefix1 = inc_ip(subnet, (client_suffix * 2 - 1) << 64) + '/64' + prefix2 = inc_ip(subnet, (client_suffix * 2) << 64) + '/64' self.cli_set(mapping + [f'client{client_suffix}', 'duid', duid]) - self.cli_set(mapping + [f'client{client_suffix}', 'ipv6-address', ip]) - self.cli_set(mapping + [f'client{client_suffix}', 'ipv6-prefix', prefix]) + self.cli_set(mapping + [f'client{client_suffix}', 'ipv6-address', ip1]) + self.cli_set(mapping + [f'client{client_suffix}', 'ipv6-address', ip2]) + self.cli_set(mapping + [f'client{client_suffix}', 'ipv6-prefix', prefix1]) + self.cli_set(mapping + [f'client{client_suffix}', 'ipv6-prefix', prefix2]) # cannot have both mac-address and duid set with self.assertRaises(ConfigSessionError): @@ -250,8 +254,10 @@ class TestServiceDHCPv6Server(VyOSUnitTestSHIM.TestCase): for client_suffix in range(1, 4): duid = f'00:01:00:01:12:34:56:78:aa:bb:cc:dd:ee:{client_suffix:02}' - ip = inc_ip(subnet, client_suffix) - prefix = inc_ip(subnet, client_suffix << 64) + '/64' + ip1 = inc_ip(subnet, client_suffix * 2 - 1) + ip2 = inc_ip(subnet, client_suffix * 2) + prefix1 = inc_ip(subnet, (client_suffix * 2 - 1) << 64) + '/64' + prefix2 = inc_ip(subnet, (client_suffix * 2) << 64) + '/64' self.verify_config_object( obj, @@ -259,8 +265,8 @@ class TestServiceDHCPv6Server(VyOSUnitTestSHIM.TestCase): { 'hostname': f'client{client_suffix}', 'duid': duid, - 'ip-addresses': [ip], - 'prefixes': [prefix], + 'ip-addresses': [ip1, ip2], + 'prefixes': [prefix1, prefix2], }, ) diff --git a/src/conf_mode/service_dhcpv6-server.py b/src/conf_mode/service_dhcpv6-server.py index 88d34bf61..01bbf3096 100755 --- a/src/conf_mode/service_dhcpv6-server.py +++ b/src/conf_mode/service_dhcpv6-server.py @@ -226,13 +226,18 @@ def verify(dhcpv6): for mapping, mapping_config in subnet_config['static_mapping'].items(): if 'ipv6_address' in mapping_config: # Static address must be in subnet - if ip_address(mapping_config['ipv6_address']) not in ip_network(subnet): - raise ConfigError(f'static-mapping address for mapping "{mapping}" is not in subnet "{subnet}"!') - - if ('mac' not in mapping_config and 'duid' not in mapping_config) or \ - ('mac' in mapping_config and 'duid' in mapping_config): - raise ConfigError(f'Either MAC address or Client identifier (DUID) is required for ' - f'static mapping "{mapping}" within shared-network "{network}, {subnet}"!') + for address in mapping_config['ipv6_address']: + if ip_address(address) not in ip_network(subnet): + raise ConfigError(f'static-mapping address for mapping "{mapping}" is not in subnet "{subnet}"!') + + if ('ipv6_address' not in mapping_config and 'ipv6_prefix' not in mapping_config): + raise ConfigError('Either IPv6 address or IPv6 prefix must be set for static mapping ' + f'"{mapping}" within shared-network "{network}, {subnet}"!') + + if ('mac' not in mapping_config and 'duid' not in mapping_config) or \ + ('mac' in mapping_config and 'duid' in mapping_config): + raise ConfigError('Either MAC address or Client identifier (DUID) is required for ' + f'static mapping "{mapping}" within shared-network "{network}, {subnet}"!') if 'option' in subnet_config: if 'vendor_option' in subnet_config['option']: |
