summaryrefslogtreecommitdiff
path: root/src/conf_mode/dhcp_server.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/conf_mode/dhcp_server.py')
-rwxr-xr-xsrc/conf_mode/dhcp_server.py45
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("&quot;", '"'))
+ # 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("&quot;", '"'))
+
return None
def apply(dhcp):