summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorViacheslav Hletenko <v.gletenko@vyos.io>2026-05-22 11:56:04 +0300
committerGitHub <noreply@github.com>2026-05-22 11:56:04 +0300
commit88b93c96faa5b1016546cbc15d1327b4692a87cc (patch)
tree53c60f5bc9c455f9fcaa05e528fa2de562aeb750
parent6fa4967f49e988e4979c611ee9199bb14bef8536 (diff)
parente97437c52d2d21b7e662d5569f668615aaee2d98 (diff)
downloadvyos-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.i2
-rw-r--r--python/vyos/kea.py4
-rwxr-xr-xsmoketest/scripts/cli/test_service_dhcpv6-server.py22
-rwxr-xr-xsrc/conf_mode/service_dhcpv6-server.py19
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']: