Page Menu
Home
VyOS Platform
Search
Configure Global Search
Log In
Files
F119062216
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/data/templates/dhcp-server/dhcpd.conf.tmpl b/data/templates/dhcp-server/dhcpd.conf.tmpl
index 3e0fd8d1d..d172018bf 100644
--- a/data/templates/dhcp-server/dhcpd.conf.tmpl
+++ b/data/templates/dhcp-server/dhcpd.conf.tmpl
@@ -1,192 +1,192 @@
### Autogenerated by dhcp_server.py ###
# For options please consult the following website:
# https://www.isc.org/wp-content/uploads/2017/08/dhcp43options.html
#
# log-facility local7;
{% if hostfile_update %}
on release {
set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name);
set ClientIp = binary-to-ascii(10, 8, ".",leased-address);
set ClientMac = binary-to-ascii(16, 8, ":",substring(hardware, 1, 6));
set ClientDomain = pick-first-value(config-option domain-name, "..YYZ!");
execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "release", ClientName, ClientIp, ClientMac, ClientDomain);
}
on expiry {
set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name);
set ClientIp = binary-to-ascii(10, 8, ".",leased-address);
set ClientMac = binary-to-ascii(16, 8, ":",substring(hardware, 1, 6));
set ClientDomain = pick-first-value(config-option domain-name, "..YYZ!");
execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "release", ClientName, ClientIp, ClientMac, ClientDomain);
}
{% endif %}
{% if host_decl_name %}
use-host-decl-names on;
{% endif %}
ddns-update-style {{ 'interim' if ddns_enable else 'none' }};
{% if static_route %}
option rfc3442-static-route code 121 = array of integer 8;
option windows-static-route code 249 = array of integer 8;
{% endif %}
{% if wpad %}
option wpad-url code 252 = text;
{% endif %}
{% if global_parameters %}
# The following {{ global_parameters | length }} line(s) were added as global-parameters in the CLI and have not been validated
{% for param in global_parameters %}
{{ param }}
{% endfor %}
{% endif %}
# Failover configuration
{% for network in shared_network %}
{% if not network.disabled %}
{% for subnet in network.subnet %}
{% if subnet.failover_name %}
failover peer "{{ subnet.failover_name }}" {
{% if subnet.failover_status == 'primary' %}
primary;
mclt 1800;
split 128;
{% elif subnet.failover_status == 'secondary' %}
secondary;
{% endif %}
address {{ subnet.failover_local_addr }};
port 520;
peer address {{ subnet.failover_peer_addr }};
peer port 520;
max-response-delay 30;
max-unacked-updates 10;
load balance max seconds 3;
}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
# Shared network configration(s)
{% for network in shared_network if not network.disabled %}
shared-network {{ network.name }} {
{% if network.authoritative %}
authoritative;
{% endif %}
{% if network.network_parameters %}
# The following {{ network.network_parameters | length }} line(s) were added as shared-network-parameters in the CLI and have not been validated
{% for param in network.network_parameters %}
{{ param }}
{% endfor %}
{% endif %}
{% for subnet in network.subnet %}
subnet {{ subnet.address }} netmask {{ subnet.netmask }} {
{% if subnet.dns_server %}
option domain-name-servers {{ subnet.dns_server | join(', ') }};
{% endif %}
{% if subnet.domain_search %}
option domain-search {{ subnet.domain_search | join(', ') }};
{% endif %}
{% if subnet.ntp_server %}
option ntp-servers {{ subnet.ntp_server | join(', ') }};
{% endif %}
{% if subnet.pop_server %}
option pop-server {{ subnet.pop_server | join(', ') }};
{% endif %}
{% if subnet.smtp_server %}
option smtp-server {{ subnet.smtp_server | join(', ') }};
{% endif %}
{% if subnet.time_server %}
option time-servers {{ subnet.time_server | join(', ') }};
{% endif %}
{% if subnet.wins_server %}
option netbios-name-servers {{ subnet.wins_server | join(', ') }};
{% endif %}
{% if subnet.static_route %}
option rfc3442-static-route {{ subnet.static_route }}{% if subnet.rfc3442_default_router %}, {{ subnet.rfc3442_default_router }}{% endif %};
option windows-static-route {{ subnet.static_route }};
{% endif %}
{% if subnet.ip_forwarding %}
option ip-forwarding true;
{% endif %}
{% if subnet.default_router %}
option routers {{ subnet.default_router }};
{% endif %}
{% if subnet.server_identifier %}
option dhcp-server-identifier {{ subnet.server_identifier }};
{% endif %}
{% if subnet.domain_name %}
option domain-name "{{ subnet.domain_name }}";
{% endif %}
{% if subnet.subnet_parameters %}
# The following {{ subnet.subnet_parameters | length }} line(s) were added as subnet-parameters in the CLI and have not been validated
{% for param in subnet.subnet_parameters %}
{{ param }}
{% endfor %}
{% endif %}
{% if subnet.tftp_server %}
option tftp-server-name "{{ subnet.tftp_server }}";
{% endif %}
{% if subnet.bootfile_name %}
option bootfile-name "{{ subnet.bootfile_name }}";
filename "{{ subnet.bootfile_name }}";
{% endif %}
{% if subnet.bootfile_server %}
next-server {{ subnet.bootfile_server }};
{% endif %}
{% if subnet.time_offset %}
option time-offset {{ subnet.time_offset }};
{% endif %}
{% if subnet.wpad_url %}
option wpad-url "{{ subnet.wpad_url }}";
{% endif %}
{% if subnet.client_prefix_length %}
option subnet-mask {{ subnet.client_prefix_length }};
{% endif %}
{% if subnet.lease %}
default-lease-time {{ subnet.lease }};
max-lease-time {{ subnet.lease }};
{% endif %}
{% for host in subnet.static_mapping if not host.disabled %}
- host {% if host_decl_name %} {{ host.name }} {% else %} {{ network.name }}_{{ host.name }} {% endif %} {
+ host {{ host.name if host_decl_name else network.name + '_' + host.name }} {
{% if host.ip_address %}
fixed-address {{ host.ip_address }};
{% endif %}
hardware ethernet {{ host.mac_address }};
{% if host.static_parameters %}
# The following {{ host.static_parameters | length }} line(s) were added as static-mapping-parameters in the CLI and have not been validated
{% for param in host.static_parameters %}
{{ param }}
{% endfor %}
{% endif %}
}
{% endfor %}
{% if subnet.failover_name %}
pool {
failover peer "{{ subnet.failover_name }}";
deny dynamic bootp clients;
{% for range in subnet.range %}
range {{ range.start }} {{ range.stop }};
{% endfor %}
}
{% else %}
{% for range in subnet.range %}
range {{ range.start }} {{ range.stop }};
{% endfor %}
{% endif %}
}
{% endfor %}
on commit {
set shared-networkname = "{{ network.name }}";
{% if hostfile_update %}
set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name);
set ClientIp = binary-to-ascii(10, 8, ".", leased-address);
set ClientMac = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6));
set ClientDomain = pick-first-value(config-option domain-name, "..YYZ!");
execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "commit", ClientName, ClientIp, ClientMac, ClientDomain);
{% endif %}
}
}
{% endfor %}
diff --git a/smoketest/scripts/cli/test_service_dhcp-server.py b/smoketest/scripts/cli/test_service_dhcp-server.py
index 03537472a..8d6917cf1 100755
--- a/smoketest/scripts/cli/test_service_dhcp-server.py
+++ b/smoketest/scripts/cli/test_service_dhcp-server.py
@@ -1,95 +1,148 @@
#!/usr/bin/env python3
#
# Copyright (C) 2019-2020 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import re
import os
import unittest
from vyos.configsession import ConfigSession
from vyos.configsession import ConfigSessionError
from vyos.util import cmd
from vyos.util import process_named_running
from vyos.util import read_file
from vyos.template import inc_ip
from vyos.template import address_from_cidr
from vyos.template import netmask_from_cidr
PROCESS_NAME = 'dhcpd'
DHCPD_CONF = '/run/dhcp-server/dhcpd.conf'
base_path = ['service', 'dhcp-server']
subnet = '192.0.2.0/25'
router = inc_ip(subnet, 1)
class TestServiceDHCPServer(unittest.TestCase):
def setUp(self):
self.session = ConfigSession(os.getpid())
cidr_mask = subnet.split('/')[-1]
self.session.set(['interfaces', 'dummy', 'dum8765', 'address', f'{router}/{cidr_mask}'])
def tearDown(self):
self.session.delete(['interfaces', 'dummy', 'dum8765'])
self.session.delete(base_path)
self.session.commit()
del self.session
- def test_single_pool(self):
+ def test_single_pool_range(self):
shared_net_name = 'SMOKE-1'
dns_1 = inc_ip(subnet, 2)
dns_2 = inc_ip(subnet, 3)
domain_name = 'vyos.net'
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)
pool = base_path + ['shared-network-name', shared_net_name, 'subnet', subnet]
# we use the first subnet IP address as default gateway
self.session.set(pool + ['default-router', router])
self.session.set(pool + ['dns-server', dns_1])
self.session.set(pool + ['dns-server', dns_2])
self.session.set(pool + ['domain-name', domain_name])
# check validate() - No DHCP address range or active static-mapping set
with self.assertRaises(ConfigSessionError):
self.session.commit()
self.session.set(pool + ['range', '0', 'start', range_0_start])
self.session.set(pool + ['range', '0', 'stop', range_0_stop])
self.session.set(pool + ['range', '1', 'start', range_1_start])
self.session.set(pool + ['range', '1', 'stop', range_1_stop])
# commit changes
self.session.commit()
config = read_file(DHCPD_CONF)
network = address_from_cidr(subnet)
netmask = netmask_from_cidr(subnet)
self.assertIn(f'ddns-update-style none;', config)
self.assertIn(f'subnet {network} netmask {netmask}' + r' {', config)
self.assertIn(f'option domain-name-servers {dns_1}, {dns_2};', config)
self.assertIn(f'option routers {router};', config)
self.assertIn(f'option domain-name "{domain_name}";', config)
self.assertIn(f'default-lease-time 86400;', config)
self.assertIn(f'max-lease-time 86400;', config)
self.assertIn(f'range {range_0_start} {range_0_stop};', config)
self.assertIn(f'range {range_1_start} {range_1_stop};', config)
self.assertIn(f'set shared-networkname = "{shared_net_name}";', config)
# Check for running process
self.assertTrue(process_named_running(PROCESS_NAME))
+ def test_single_pool_static_mapping(self):
+ shared_net_name = 'SMOKE-2'
+
+ dns_1 = inc_ip(subnet, 2)
+ dns_2 = inc_ip(subnet, 3)
+ domain_name = 'vyos.net'
+
+ pool = base_path + ['shared-network-name', shared_net_name, 'subnet', subnet]
+ # we use the first subnet IP address as default gateway
+ self.session.set(pool + ['default-router', router])
+ self.session.set(pool + ['dns-server', dns_1])
+ self.session.set(pool + ['dns-server', dns_2])
+ self.session.set(pool + ['domain-name', domain_name])
+
+ # check validate() - No DHCP address range or active static-mapping set
+ with self.assertRaises(ConfigSessionError):
+ self.session.commit()
+
+ client_base = 10
+ for client in ['client1', 'client2', 'client3']:
+ mac = '00:50:00:00:00:{}'.format(client_base)
+ self.session.set(pool + ['static-mapping', client, 'mac-address', mac])
+ self.session.set(pool + ['static-mapping', client, 'ip-address', inc_ip(subnet, client_base)])
+ client_base += 1
+
+ # commit changes
+ self.session.commit()
+
+ config = read_file(DHCPD_CONF)
+ network = address_from_cidr(subnet)
+ netmask = netmask_from_cidr(subnet)
+ self.assertIn(f'ddns-update-style none;', config)
+ self.assertIn(f'subnet {network} netmask {netmask}' + r' {', config)
+ self.assertIn(f'option domain-name-servers {dns_1}, {dns_2};', config)
+ self.assertIn(f'option routers {router};', config)
+ self.assertIn(f'option domain-name "{domain_name}";', config)
+ self.assertIn(f'default-lease-time 86400;', config)
+ self.assertIn(f'max-lease-time 86400;', config)
+
+ client_base = 10
+ for client in ['client1', 'client2', 'client3']:
+ mac = '00:50:00:00:00:{}'.format(client_base)
+ ip = inc_ip(subnet, client_base)
+ self.assertIn(f'host {shared_net_name}_{client}' + ' {', config)
+ self.assertIn(f'fixed-address {ip};', config)
+ self.assertIn(f'hardware ethernet {mac};', config)
+ client_base += 1
+
+ self.assertIn(f'set shared-networkname = "{shared_net_name}";', config)
+
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
if __name__ == '__main__':
unittest.main()
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Nov 6, 6:25 AM (3 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4646150
Default Alt Text
(14 KB)
Attached To
Mode
rVYOSONEX vyos-1x
Attached
Detach File
Event Timeline
Log In to Comment