Skip to content

Commit 65b020b

Browse files
Changes requested by dmbaturin to improve testing. This also exposed a bug so
that was corrected.
1 parent 650d7c0 commit 65b020b

File tree

4 files changed

+78
-16
lines changed

4 files changed

+78
-16
lines changed

interface-definitions/include/dhcp/dhcp-server-common-config.xml.i

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,29 @@
1414
<help>Match DHCP option 82 (relay agent information)</help>
1515
</properties>
1616
<children>
17-
<leafNode name="circuit-id">
18-
<properties>
19-
<help>Filters on the contents of the circuit-id sub option</help>
17+
<leafNode name="circuit-id">
18+
<properties>
19+
<help>Filters on the contents of the circuit-id sub option</help>
20+
<valueHelp>
21+
<format>hex</format>
22+
<description>Values that start with 0x are interpreted as raw hex. This must only be hexadecimal characters e.g. 0x1234567890ABCDEF</description>
23+
</valueHelp>
2024
<valueHelp>
2125
<format>txt</format>
22-
<description>Assumes ASCII text unless input starts with 0x in which case it is interpreted as raw hex</description>
26+
<description>Any other text string is interpreted as ASCII text</description>
2327
</valueHelp>
2428
</properties>
2529
</leafNode>
2630
<leafNode name="remote-id">
2731
<properties>
2832
<help>Filters on the contents of the remote-id sub option.</help>
33+
<valueHelp>
34+
<format>hex</format>
35+
<description>Values that start with 0x are interpreted as raw hex. This must only be hexadecimal characters e.g. 0x1234567890ABCDEF</description>
36+
</valueHelp>
2937
<valueHelp>
3038
<format>txt</format>
31-
<description>Assumes ASCII text unless input starts with 0x in which case it is interpreted as raw hex</description>
39+
<description>Any other text string is interpreted as ASCII text</description>
3240
</valueHelp>
3341
</properties>
3442
</leafNode>

python/vyos/kea.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -679,10 +679,15 @@ def kea_build_client_class_test(config):
679679

680680
if "option82" in config:
681681
if "circuit_id" in config["option82"]:
682-
conditions.append("relay4[1].hex == 0x" + config["option82"]["circuit_id"].encode().hex().lower())
682+
if config["option82"]["circuit_id"].startswith("0x"):
683+
conditions.append("relay4[1].hex == " + config["option82"]["circuit_id"])
684+
else:
685+
conditions.append("relay4[1].hex == 0x" + config["option82"]["circuit_id"].encode().hex().lower())
683686
if "remote_id" in config["option82"]:
684-
conditions.append("relay4[2].hex == 0x" + config["option82"]["remote_id"].encode().hex().lower())
685-
687+
if config["option82"]["remote_id"].startswith("0x"):
688+
conditions.append("relay4[1].hex == " + config["option82"]["remote_id"])
689+
else:
690+
conditions.append("relay4[1].hex == 0x" + config["option82"]["remote_id"].encode().hex().lower())
686691

687692
test = " and ".join(conditions)
688693

smoketest/scripts/cli/test_service_dhcp-server.py

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -240,30 +240,58 @@ def test_dhcp_client_class(self):
240240
self.cli_set(base_path + ['shared-network-name', shared_net_name, 'subnet', subnet, 'client-class', 'test'])
241241

242242
client_class = base_path + ['client-class', 'test']
243+
244+
# Test that invalid hex is rejected
245+
self.cli_set(client_class + ['option82', 'circuit-id', '0xHELLOWORLD'])
246+
247+
with self.assertRaises(ConfigSessionError):
248+
self.cli_commit()
249+
250+
self.cli_delete(client_class + ['option82', 'circuit-id'])
251+
self.cli_set(client_class + ['option82', 'remote-id', '0xHELLOWORLD'])
252+
253+
with self.assertRaises(ConfigSessionError):
254+
self.cli_commit()
255+
256+
self.cli_delete(client_class + ['option82', 'remote-id'])
257+
258+
# Test string literals
243259
self.cli_set(client_class + ['option82', 'circuit-id', 'foo'])
244260
self.cli_set(client_class + ['option82', 'remote-id', 'bar'])
245261

246262
self.cli_commit()
247263

264+
self.check_client_class_in_config()
265+
266+
self.cli_delete(client_class + ['option82', 'circuit-id'])
267+
self.cli_delete(client_class + ['option82', 'remote-id'])
268+
269+
# Test hex strings
270+
self.cli_set(client_class + ['option82', 'circuit-id', '0x666f6f'])
271+
self.cli_set(client_class + ['option82', 'remote-id', '0x626172'])
272+
273+
self.cli_commit()
274+
275+
self.check_client_class_in_config()
276+
277+
def check_client_class_in_config(self):
248278
config = read_file(KEA4_CONF)
249279
obj = loads(config)
250-
251280
self.verify_config_value(
252281
obj, ['Dhcp4', 'client-classes', 0], 'name', 'test'
253282
)
254-
255283
self.verify_config_value(
256-
obj, ['Dhcp4', 'client-classes', 0], 'test', 'relay4[1].hex == 0x666f6f and relay4[2].hex == 0x626172'
284+
obj, ['Dhcp4', 'client-classes', 0], 'test',
285+
'relay4[1].hex == 0x666f6f and relay4[2].hex == 0x626172'
257286
)
258-
259287
self.verify_config_value(
260-
obj, ['Dhcp4', 'shared-networks', 0, 'subnet4', 0], 'client-class', 'test'
288+
obj, ['Dhcp4', 'shared-networks', 0, 'subnet4', 0], 'client-class',
289+
'test'
261290
)
262-
263291
self.verify_config_value(
264-
obj, ['Dhcp4', 'shared-networks', 0, 'subnet4', 0, 'pools', 0], 'client-class', 'test'
292+
obj, ['Dhcp4', 'shared-networks', 0, 'subnet4', 0, 'pools', 0],
293+
'client-class', 'test'
265294
)
266-
267295
# Check for running process
268296
self.verify_service_running()
269297

src/conf_mode/service_dhcp-server.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
# along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

1717
import os
18+
import re
1819

1920
from sys import exit
2021
from sys import argv
@@ -521,6 +522,26 @@ def verify(dhcp):
521522
if 'reverse_domain' in ddns:
522523
verify_ddns_domain_servers('Reverse', ddns['reverse_domain'])
523524

525+
if 'client_class' in dhcp:
526+
# Check client class values are valid
527+
for class_name, class_config in dhcp['client_class'].items():
528+
if 'option82' in class_config:
529+
option82_config = class_config['option82']
530+
# Compile a regex that will scan for valid inputs. Input can be
531+
# either hex in the form 0x0123456789ABCDEF or a string that
532+
# does *not* start with 0x. i.e. 0xHELLOWORLD is bad
533+
pattern = re.compile(r'^(?:0x[0-9A-Fa-f]+|(?!0x).+)$')
534+
535+
if 'circuit_id' in option82_config:
536+
circuit_id = option82_config['circuit_id']
537+
if not pattern.match(circuit_id):
538+
raise ConfigError(f'Invalid circuit-id "{circuit_id}" must be either text literal or hex string starting with 0x')
539+
540+
if 'remote_id' in option82_config:
541+
remote_id = option82_config['remote_id']
542+
if not pattern.match(remote_id):
543+
raise ConfigError(f'Invalid remote-id "{remote_id}" must be either text literal or hex string starting with 0x')
544+
524545
return None
525546

526547

0 commit comments

Comments
 (0)