diff options
Diffstat (limited to 'src/conf_mode/dhcp_server.py')
-rwxr-xr-x | src/conf_mode/dhcp_server.py | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/src/conf_mode/dhcp_server.py b/src/conf_mode/dhcp_server.py index 84a8736e8..cdee72e09 100755 --- a/src/conf_mode/dhcp_server.py +++ b/src/conf_mode/dhcp_server.py @@ -18,6 +18,8 @@ import os from ipaddress import ip_address from ipaddress import ip_network +from netaddr import IPAddress +from netaddr import IPRange from sys import exit from vyos.config import Config @@ -25,6 +27,7 @@ from vyos.configdict import dict_merge from vyos.template import render from vyos.util import call from vyos.util import dict_search +from vyos.util import run from vyos.validate import is_subnet_connected from vyos.validate import is_addr_assigned from vyos.xml import defaults @@ -162,8 +165,7 @@ def verify(dhcp): # Check if DHCP address range is inside configured subnet declaration if 'range' in subnet_config: - range_start = [] - range_stop = [] + networks = [] for range, range_config in subnet_config['range'].items(): if not {'start', 'stop'} <= set(range_config): raise ConfigError(f'DHCP range "{range}" start and stop address must be defined!') @@ -178,18 +180,16 @@ def verify(dhcp): raise ConfigError(f'DHCP range "{range}" stop address must be greater or equal\n' \ 'to the ranges start address!') - # Range start address must be unique - if range_config['start'] in range_start: - raise ConfigError('Conflicting DHCP lease range: Pool start\n' \ - 'address "{start}" defined multipe times!'.format(range_config)) + for network in networks: + start = range_config['start'] + stop = range_config['stop'] + if start in network: + raise ConfigError(f'Range "{range}" start address "{start}" already part of another range!') + if stop in network: + raise ConfigError(f'Range "{range}" stop address "{stop}" already part of another range!') - # Range stop address must be unique - if range_config['stop'] in range_start: - raise ConfigError('Conflicting DHCP lease range: Pool stop\n' \ - 'address "{stop}" defined multipe times!'.format(range_config)) - - range_start.append(range_config['start']) - range_stop.append(range_config['stop']) + tmp = IPRange(range_config['start'], range_config['stop']) + networks.append(tmp) if 'failover' in subnet_config: for key in ['local_address', 'peer_address', 'name', 'status']: @@ -272,10 +272,25 @@ def generate(dhcp): if not dhcp or 'disable' in dhcp: return None - # Please see: https://phabricator.vyos.net/T1129 for quoting of the raw parameters - # we can pass to ISC DHCPd + # Please see: https://phabricator.vyos.net/T1129 for quoting of the raw + # parameters we can pass to ISC DHCPd + tmp_file = '/tmp/dhcpd.conf' + render(tmp_file, 'dhcp-server/dhcpd.conf.tmpl', dhcp, + formater=lambda _: _.replace(""", '"')) + # XXX: as we have the ability for a user to pass in "raw" options via VyOS + # CLI (see T3544) we now ask ISC dhcpd to test the newly rendered + # configuration + tmp = run(f'/usr/sbin/dhcpd -4 -q -t -cf {tmp_file}') + if tmp > 0: + if os.path.exists(tmp_file): + os.unlink(tmp_file) + raise ConfigError('Configuration file errors encountered - check your options!') + + # Now that we know that the newly rendered configuration is "good" we can + # render the "real" configuration render(config_file, 'dhcp-server/dhcpd.conf.tmpl', dhcp, formater=lambda _: _.replace(""", '"')) + return None def apply(dhcp): |