summaryrefslogtreecommitdiff
path: root/smoketest/scripts/cli
diff options
context:
space:
mode:
authorcblackburn-igl <chris.blackburn@infinitivegroup.co.uk>2025-10-28 15:38:43 +0000
committerGitHub <noreply@github.com>2025-10-28 15:38:43 +0000
commit1737b16dd87778358266222e2ef061eb15d63019 (patch)
tree0e127460ae080ad35a06b4e719d261ab3f7a1805 /smoketest/scripts/cli
parentecc4c85b799047f51e4a32ae5b0590017a6ce374 (diff)
downloadvyos-1x-1737b16dd87778358266222e2ef061eb15d63019.tar.gz
vyos-1x-1737b16dd87778358266222e2ef061eb15d63019.zip
dhcp-server: T3936: Added support for DHCP Option 82 (#4665)
* dhcp-server: T3936: Added support for DHCP Option 82 This commit adds support in both the CLI and the underlying code for DHCP Option 82 to be used to filter/route DHCP address assignments. The primary use case for this is to support enterprise switches which can "tag" DHCP requests with physical real world informaiton such as which switch first saw the request and which port it originated from (known in this context as remote-id and circuit-id). Once client-classes have been defined they can be assigned to subnets or ranges so that only certain addresses get assigned to specific requests. There is also a corresponding documentation update which pairs with this code change. (cherry picked from commit 326b5e713cb363a2b9f69e2204c4ee2ccd9939bb) * Update src/conf_mode/service_dhcp-server.py Co-authored-by: Nataliia S. <81954790+natali-rs1985@users.noreply.github.com> * Update src/conf_mode/service_dhcp-server.py Co-authored-by: Nataliia S. <81954790+natali-rs1985@users.noreply.github.com> * Update interface-definitions/include/dhcp/dhcp-server-common-config.xml.i Co-authored-by: Nataliia S. <81954790+natali-rs1985@users.noreply.github.com> --------- Co-authored-by: Daniil Baturin <daniil@baturin.org> Co-authored-by: Nataliia S. <81954790+natali-rs1985@users.noreply.github.com>
Diffstat (limited to 'smoketest/scripts/cli')
-rwxr-xr-xsmoketest/scripts/cli/test_service_dhcp-server.py128
1 files changed, 107 insertions, 21 deletions
diff --git a/smoketest/scripts/cli/test_service_dhcp-server.py b/smoketest/scripts/cli/test_service_dhcp-server.py
index 9f66bdb78..285b56dfe 100755
--- a/smoketest/scripts/cli/test_service_dhcp-server.py
+++ b/smoketest/scripts/cli/test_service_dhcp-server.py
@@ -114,27 +114,7 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
range_1_start = inc_ip(subnet, 40)
range_1_stop = inc_ip(subnet, 50)
- self.cli_set(base_path + ['listen-interface', interface])
-
- self.cli_set(base_path + ['shared-network-name', shared_net_name, 'ping-check'])
-
- pool = base_path + ['shared-network-name', shared_net_name, 'subnet', subnet]
- self.cli_set(pool + ['subnet-id', '1'])
- self.cli_set(pool + ['ignore-client-id'])
- self.cli_set(pool + ['ping-check'])
- # we use the first subnet IP address as default gateway
- self.cli_set(pool + ['option', 'default-router', router])
- self.cli_set(pool + ['option', 'name-server', dns_1])
- self.cli_set(pool + ['option', 'name-server', dns_2])
- self.cli_set(pool + ['option', 'domain-name', domain_name])
-
- # check validate() - No DHCP address range or active static-mapping set
- with self.assertRaises(ConfigSessionError):
- self.cli_commit()
- self.cli_set(pool + ['range', '0', 'start', range_0_start])
- self.cli_set(pool + ['range', '0', 'stop', range_0_stop])
- self.cli_set(pool + ['range', '1', 'start', range_1_start])
- self.cli_set(pool + ['range', '1', 'stop', range_1_stop])
+ self.setup_single_pool_range(range_0_start, range_0_stop, range_1_start, range_1_stop, shared_net_name)
# commit changes
self.cli_commit()
@@ -211,6 +191,112 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase):
# Check for running process
self.verify_service_running()
+ def setup_single_pool_range(self, range_0_start, range_0_stop, range_1_start, range_1_stop, shared_net_name):
+ self.cli_set(base_path + ['listen-interface', interface])
+ self.cli_set(base_path + ['shared-network-name', shared_net_name, 'ping-check'])
+
+ pool = base_path + ['shared-network-name', shared_net_name, 'subnet', subnet]
+
+ self.cli_set(pool + ['subnet-id', '1'])
+ self.cli_set(pool + ['ignore-client-id'])
+ self.cli_set(pool + ['ping-check'])
+ # we use the first subnet IP address as default gateway
+ self.cli_set(pool + ['option', 'default-router', router])
+ self.cli_set(pool + ['option', 'name-server', dns_1])
+ self.cli_set(pool + ['option', 'name-server', dns_2])
+ self.cli_set(pool + ['option', 'domain-name', domain_name])
+
+ # check validate() - No DHCP address range or active static-mapping set
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.cli_set(pool + ['range', '0', 'start', range_0_start])
+ self.cli_set(pool + ['range', '0', 'stop', range_0_stop])
+ self.cli_set(pool + ['range', '1', 'start', range_1_start])
+ self.cli_set(pool + ['range', '1', 'stop', range_1_stop])
+
+ def test_dhcp_client_class(self):
+ shared_net_name = 'SMOKE-1'
+
+ range_0_start = inc_ip(subnet, 10)
+ range_0_stop = inc_ip(subnet, 20)
+ range_1_start = inc_ip(subnet, 40)
+ range_1_stop = inc_ip(subnet, 50)
+
+ self.setup_single_pool_range(range_0_start, range_0_stop, range_1_start, range_1_stop, shared_net_name)
+
+ self.cli_set(base_path + ['shared-network-name', shared_net_name, 'subnet', subnet, 'client-class', 'test'])
+
+ # check validate() - Client class referenced that doesn't exist yet
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.cli_delete(base_path + ['shared-network-name', shared_net_name, 'subnet', subnet, 'client-class', 'test'])
+
+ self.cli_set(base_path + ['shared-network-name', shared_net_name, 'subnet', subnet, 'range', '0', 'client-class', 'test'])
+
+ # check validate() - Client class referenced that doesn't exist yet
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.cli_set(base_path + ['shared-network-name', shared_net_name, 'subnet', subnet, 'client-class', 'test'])
+
+ client_class = base_path + ['client-class', 'test']
+
+ # Test that invalid hex is rejected
+ self.cli_set(client_class + ['relay-agent-information', 'circuit-id', '0xHELLOWORLD'])
+
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.cli_delete(client_class + ['relay-agent-information', 'circuit-id'])
+ self.cli_set(client_class + ['relay-agent-information', 'remote-id', '0xHELLOWORLD'])
+
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.cli_delete(client_class + ['relay-agent-information', 'remote-id'])
+
+ # Test string literals
+ self.cli_set(client_class + ['relay-agent-information', 'circuit-id', 'foo'])
+ self.cli_set(client_class + ['relay-agent-information', 'remote-id', 'bar'])
+
+ self.cli_commit()
+
+ self.check_client_class_in_config()
+
+ self.cli_delete(client_class + ['relay-agent-information', 'circuit-id'])
+ self.cli_delete(client_class + ['relay-agent-information', 'remote-id'])
+
+ # Test hex strings
+ self.cli_set(client_class + ['relay-agent-information', 'circuit-id', '0x666f6f'])
+ self.cli_set(client_class + ['relay-agent-information', 'remote-id', '0x626172'])
+
+ self.cli_commit()
+
+ self.check_client_class_in_config()
+
+ def check_client_class_in_config(self):
+ config = read_file(KEA4_CONF)
+ obj = loads(config)
+ self.verify_config_value(
+ obj, ['Dhcp4', 'client-classes', 0], 'name', 'test'
+ )
+ self.verify_config_value(
+ obj, ['Dhcp4', 'client-classes', 0], 'test',
+ 'relay4[1].hex == 0x666f6f and relay4[2].hex == 0x626172'
+ )
+ self.verify_config_value(
+ obj, ['Dhcp4', 'shared-networks', 0, 'subnet4', 0], 'client-class',
+ 'test'
+ )
+ self.verify_config_value(
+ obj, ['Dhcp4', 'shared-networks', 0, 'subnet4', 0, 'pools', 0],
+ 'client-class', 'test'
+ )
+ # Check for running process
+ self.verify_service_running()
+
def test_dhcp_single_pool_options(self):
shared_net_name = 'SMOKE-0815'