diff --git a/interface-definitions/dhcp-server.xml b/interface-definitions/dhcp-server.xml
index 2002f0c65..87999f496 100644
--- a/interface-definitions/dhcp-server.xml
+++ b/interface-definitions/dhcp-server.xml
@@ -1,456 +1,462 @@
 <?xml version="1.0"?>
 <!-- DHCP server configuration -->
 <interfaceDefinition>
   <node name="service">
     <children>
       <node name="dhcp-server" owner="${vyos_conf_scripts_dir}/dhcp_server.py">
         <properties>
           <help>Dynamic Host Configuration Protocol (DHCP) for DHCP server</help>
           <priority>911</priority>
         </properties>
         <children>
           <leafNode name="disable">
             <properties>
               <help>Option to disable DHCP server</help>
               <valueless/>
             </properties>
           </leafNode>
           <leafNode name="dynamic-dns-update">
             <properties>
               <help>DHCP server to dynamically update the Domain Name System (DNS)</help>
               <valueless/>
             </properties>
           </leafNode>
           <leafNode name="global-parameters">
             <properties>
               <help>Additional global parameters for DHCP server. You must
                 use the syntax of dhcpd.conf in this text-field. Using this
                 without proper knowledge may result in a crashed DHCP server.
                 Check system log to look for errors.</help>
               <multi/>
             </properties>
           </leafNode>
           <leafNode name="hostfile-update">
             <properties>
               <help>Enable DHCP server updating /etc/hosts (per client lease)</help>
               <valueless/>
             </properties>
           </leafNode>
+          <leafNode name="host-decl-name">
+            <properties>
+              <help>Instruct server to use host declaration name for forward DNS name</help>
+              <valueless/>
+            </properties>
+          </leafNode>
           <tagNode name="shared-network-name">
             <properties>
               <help>DHCP shared network name [REQUIRED]</help>
               <constraint>
                 <regex>^[-_a-zA-Z0-9.]+$</regex>
               </constraint>
               <constraintErrorMessage>Invalid DHCP pool name</constraintErrorMessage>
             </properties>
             <children>
               <leafNode name="authoritative">
                 <properties>
                   <help>Option to make DHCP server authoritative for this physical network</help>
                   <valueless/>
                 </properties>
               </leafNode>
               <leafNode name="description">
                 <properties>
                   <help>Shared-network-name description</help>
                 </properties>
               </leafNode>
               <leafNode name="disable">
                 <properties>
                   <help>Option to disable DHCP configuration for shared-network</help>
                   <valueless/>
                 </properties>
               </leafNode>
               <leafNode name="shared-network-parameters">
                 <properties>
                   <help>Additional shared-network parameters for DHCP server.
                 You must use the syntax of dhcpd.conf in this text-field.
                 Using this without proper knowledge may result in a crashed
                 DHCP server. Check system log to look for errors.</help>
                   <multi/>
                 </properties>
               </leafNode>
               <tagNode name="subnet">
                 <properties>
                   <help>DHCP subnet for shared network</help>
                   <valueHelp>
                     <format>ipv4net</format>
                     <description>IPv4 address and prefix length</description>
                   </valueHelp>
                   <constraint>
                     <validator name="ipv4-prefix"/>
                   </constraint>
                 </properties>
                 <children>
                   <leafNode name="bootfile-name">
                     <properties>
                       <help>Bootstrap file name</help>
                     </properties>
                   </leafNode>
                   <leafNode name="bootfile-server">
                     <properties>
                       <help>Server (IP address or domain name) from which the initial
                 boot file is to be loaded</help>
                     </properties>
                   </leafNode>
                   <leafNode name="client-prefix-length">
                     <properties>
                       <help>Specifies the clients subnet mask as per RFC 950. If unset, subnet declaration is used.</help>
                       <valueHelp>
                         <format>0-32</format>
                         <description>DHCP client prefix length must be 0 to 32</description>
                       </valueHelp>
                       <constraint>
                         <validator name="numeric" argument="--range 0-32"/>
                       </constraint>
                       <constraintErrorMessage>DHCP client prefix length must be 0 to 32</constraintErrorMessage>
                     </properties>
                   </leafNode>
                   <leafNode name="default-router">
                     <properties>
                       <help>IP address of default router</help>
                       <valueHelp>
                         <format>ipv4</format>
                         <description>Default router IPv4 address</description>
                       </valueHelp>
                       <constraint>
                         <validator name="ipv4-address"/>
                       </constraint>
                     </properties>
                   </leafNode>
                   <leafNode name="dns-server">
                     <properties>
                       <help>DNS server IPv4 address</help>
                       <valueHelp>
                         <format>ipv4</format>
                         <description>DNS server IPv4 address</description>
                       </valueHelp>
                       <constraint>
                         <validator name="ipv4-address"/>
                       </constraint>
                       <multi/>
                     </properties>
                   </leafNode>
                   <leafNode name="domain-name">
                     <properties>
                       <help>Client domain name</help>
                     </properties>
                   </leafNode>
                   <leafNode name="domain-search">
                     <properties>
                       <help>Client domain search</help>
                       <multi/>
                     </properties>
                   </leafNode>
                   <leafNode name="exclude">
                     <properties>
                       <help>IP address that needs to be excluded from DHCP lease range</help>
                       <valueHelp>
                         <format>ipv4</format>
                         <description>IPv4 address to exclude from lease range</description>
                       </valueHelp>
                       <constraint>
                         <validator name="ipv4-address"/>
                       </constraint>
                       <multi/>
                     </properties>
                   </leafNode>
                   <node name="failover">
                     <properties>
                       <help>DHCP failover parameters</help>
                     </properties>
                     <children>
                       <leafNode name="local-address">
                         <properties>
                           <help>IP address for failover peer to connect [REQUIRED]</help>
                           <valueHelp>
                             <format>ipv4</format>
                             <description>IPv4 address to exclude from lease range</description>
                           </valueHelp>
                           <constraint>
                             <validator name="ipv4-address"/>
                           </constraint>
                         </properties>
                       </leafNode>
                       <leafNode name="name">
                         <properties>
                           <help>DHCP failover peer name [REQUIRED]</help>
                           <constraint>
                             <regex>^[-_a-zA-Z0-9.]+$</regex>
                           </constraint>
                           <constraintErrorMessage>Invalid failover peer name</constraintErrorMessage>
                         </properties>
                       </leafNode>
                       <leafNode name="peer-address">
                         <properties>
                           <help>IP address of failover peer [REQUIRED]</help>
                           <valueHelp>
                             <format>ipv4</format>
                             <description>IPv4 address to exclude from lease range</description>
                           </valueHelp>
                           <constraint>
                             <validator name="ipv4-address"/>
                           </constraint>
                         </properties>
                       </leafNode>
                       <leafNode name="status">
                         <properties>
                           <help>DHCP failover peer status (primary|secondary) [REQUIRED]</help>
                           <completionHelp>
                             <list>primary secondary</list>
                           </completionHelp>
                           <constraint>
                             <regex>(primary|secondary)</regex>
                           </constraint>
                           <constraintErrorMessage>Invalid DHCP failover peer status</constraintErrorMessage>
                         </properties>
                       </leafNode>
                     </children>
                   </node>
                   <leafNode name="ip-forwarding">
                     <properties>
                       <help>Enable IP forwarding on client</help>
                       <valueless/>
                     </properties>
                   </leafNode>
                   <leafNode name="lease">
                     <properties>
                       <help>Lease timeout in seconds (default: 86400)</help>
                       <valueHelp>
                         <format>0-4294967295</format>
                         <description>DHCP lease time in seconds must be between 0 and 4294967295 (49 days)</description>
                       </valueHelp>
                       <constraint>
                         <validator name="numeric" argument="--range 0-4294967295"/>
                       </constraint>
                       <constraintErrorMessage>DHCP lease time must be 0 to 4294967295</constraintErrorMessage>
                     </properties>
                   </leafNode>
                   <leafNode name="ntp-server">
                     <properties>
                       <help>IP address of NTP server</help>
                       <valueHelp>
                         <format>ipv4</format>
                         <description>NTP server IPv4 address</description>
                       </valueHelp>
                       <constraint>
                         <validator name="ipv4-address"/>
                       </constraint>
                       <multi/>
                     </properties>
                   </leafNode>
                   <leafNode name="pop-server">
                     <properties>
                       <help>IP address of POP3 server</help>
                       <valueHelp>
                         <format>ipv4</format>
                         <description>POP3 server IPv4 address</description>
                       </valueHelp>
                       <constraint>
                         <validator name="ipv4-address"/>
                       </constraint>
                       <multi/>
                     </properties>
                   </leafNode>
                   <leafNode name="server-identifier">
                     <properties>
                       <help>Address for DHCP server identifier</help>
                       <valueHelp>
                         <format>ipv4</format>
                         <description>DHCP server identifier IPv4 address</description>
                       </valueHelp>
                       <constraint>
                         <validator name="ipv4-address"/>
                       </constraint>
                     </properties>
                   </leafNode>
                   <leafNode name="smtp-server">
                     <properties>
                       <help>IP address of SMTP server</help>
                       <valueHelp>
                         <format>ipv4</format>
                         <description>SMTP server IPv4 address</description>
                       </valueHelp>
                       <constraint>
                         <validator name="ipv4-address"/>
                       </constraint>
                       <multi/>
                     </properties>
                   </leafNode>
                   <tagNode name="range">
                     <properties>
                       <help>DHCP lease range</help>
                       <constraint>
                         <regex>^[-_a-zA-Z0-9.]+$</regex>
                       </constraint>
                       <constraintErrorMessage>Invalid DHCP lease range name</constraintErrorMessage>
                     </properties>
                     <children>
                       <leafNode name="start">
                         <properties>
                           <help>First IP address for DHCP lease range</help>
                           <valueHelp>
                             <format>ipv4</format>
                             <description>IPv4 start address of pool</description>
                           </valueHelp>
                           <constraint>
                             <validator name="ipv4-address"/>
                           </constraint>
                         </properties>
                       </leafNode>
                       <leafNode name="stop">
                         <properties>
                           <help>Last IP address for DHCP lease range</help>
                           <valueHelp>
                             <format>ipv4</format>
                             <description>IPv4 end address of pool</description>
                           </valueHelp>
                           <constraint>
                             <validator name="ipv4-address"/>
                           </constraint>
                         </properties>
                       </leafNode>
                     </children>
                   </tagNode>
                   <tagNode name="static-mapping">
                     <properties>
                       <help>Static mapping for specified address type</help>
                       <constraint>
                         <regex>^[-_a-zA-Z0-9.]+$</regex>
                       </constraint>
                       <constraintErrorMessage>Invalid static-mapping name</constraintErrorMessage>
                     </properties>
                     <children>
                       <leafNode name="disable">
                         <properties>
                           <help>Option to disable static-mapping</help>
                           <valueless/>
                         </properties>
                       </leafNode>
                       <leafNode name="ip-address">
                         <properties>
                           <help>Static mapping for specified IP address [REQUIRED]</help>
                           <valueHelp>
                             <format>ipv4</format>
                             <description>IPv4 address used in static mapping</description>
                           </valueHelp>
                           <constraint>
                             <validator name="ipv4-address"/>
                           </constraint>
                         </properties>
                       </leafNode>
                       <leafNode name="mac-address">
                         <properties>
                           <help>Static mapping for specified MAC address [REQUIRED]</help>
                           <valueHelp>
                             <format>h:h:h:h:h:h</format>
                             <description>MAC address used in static mapping [REQUIRED]</description>
                           </valueHelp>
                         </properties>
                       </leafNode>
                       <leafNode name="static-mapping-parameters">
                         <properties>
                           <help>Additional static-mapping parameters for DHCP server.
                 You must use the syntax of dhcpd.conf in this text-field.
                 Using this without proper knowledge may result in a crashed
                 DHCP server. Check system log to look for errors.</help>
                           <multi/>
                         </properties>
                       </leafNode>
                     </children>
                   </tagNode>
                   <node name="static-route">
                     <properties>
                       <help>Classless static route</help>
                     </properties>
                     <children>
                       <leafNode name="destination-subnet">
                         <properties>
                           <help>Destination subnet [REQUIRED]</help>
                           <valueHelp>
                             <format>ipv4net</format>
                             <description>IPv4 address and prefix length</description>
                           </valueHelp>
                           <constraint>
                             <validator name="ipv4-prefix"/>
                           </constraint>
                         </properties>
                       </leafNode>
                       <leafNode name="router">
                         <properties>
                           <help>IP address of router to be used to reach the destination subnet [REQUIRED]</help>
                           <valueHelp>
                             <format>ipv4</format>
                             <description>IPv4 address of router</description>
                           </valueHelp>
                           <constraint>
                             <validator name="ip-address"/>
                           </constraint>
                         </properties>
                       </leafNode>
                     </children>
                   </node>
                   <leafNode name="subnet-parameters">
                     <properties>
                       <help>Additional subnet parameters for DHCP server. You must
                 use the syntax of dhcpd.conf in this text-field. Using this
                 without proper knowledge may result in a crashed DHCP server.
                 Check system log to look for errors.</help>
                       <multi/>
                     </properties>
                   </leafNode>
                   <leafNode name="tftp-server-name">
                     <properties>
                       <help>TFTP server name</help>
                     </properties>
                   </leafNode>
                   <leafNode name="time-offset">
                     <properties>
                       <help>Offset of the client's subnet in seconds from Coordinated Universal Time (UTC)</help>
                       <constraint>
                         <regex>^-?[0-9]+$</regex>
                       </constraint>
                       <constraintErrorMessage>Invalid time offset valuee</constraintErrorMessage>
                     </properties>
                   </leafNode>
                   <leafNode name="time-server">
                     <properties>
                       <help>IP address of time server</help>
                       <valueHelp>
                         <format>ipv4</format>
                         <description>Time server IPv4 address</description>
                       </valueHelp>
                       <constraint>
                         <validator name="ipv4-address"/>
                       </constraint>
                       <multi/>
                     </properties>
                   </leafNode>
                   <leafNode name="wins-server">
                     <properties>
                       <help>IP address for Windows Internet Name Service (WINS) server</help>
                       <valueHelp>
                         <format>ipv4</format>
                         <description>WINS server IPv4 address</description>
                       </valueHelp>
                       <constraint>
                         <validator name="ipv4-address"/>
                       </constraint>
                       <multi/>
                     </properties>
                   </leafNode>
                   <leafNode name="wpad-url">
                     <properties>
                       <help>Web Proxy Autodiscovery (WPAD) URL</help>
                     </properties>
                   </leafNode>
                 </children>
               </tagNode>
             </children>
           </tagNode>
         </children>
       </node>
     </children>
   </node>
 </interfaceDefinition>
diff --git a/src/conf_mode/dhcp_server.py b/src/conf_mode/dhcp_server.py
index 22ada72a8..bbe0bf28a 100755
--- a/src/conf_mode/dhcp_server.py
+++ b/src/conf_mode/dhcp_server.py
@@ -1,816 +1,825 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2018 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 sys
 import os
 import ipaddress
 import jinja2
 import socket
 import struct
 
 import vyos.validate
 
 from vyos.config import Config
 from vyos import ConfigError
 
 config_file = r'/etc/dhcp/dhcpd.conf'
 lease_file = r'/config/dhcpd.leases'
 daemon_config_file = r'/etc/default/isc-dhcp-server'
 
 # Please be careful if you edit the template.
 config_tmpl = """
 ### 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 {% if ddns_enable -%} interim {%- else -%} none {%- endif %};
 {% 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 static_route -%}
 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 }} {
     {{ "authoritative;" if network.authoritative }}
     {%- 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 }};
         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 {{ network.name }}_{{ host.name }} {
             fixed-address {{ host.ip_address }};
             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 %}
         }
         {%- 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 -%}
     }
 }
 {%- endif %}
 {% endfor %}
 """
 
 daemon_tmpl = """
 ### Autogenerated by dhcp_server.py ###
 
 # sourced by /etc/init.d/isc-dhcp-server
 
 DHCPD_CONF=/etc/dhcp/dhcpd.conf
 DHCPD_PID=/var/run/dhcpd.pid
 OPTIONS="-4 -lf {{ lease_file }}"
 INTERFACES=""
 """
 
 default_config_data = {
     'lease_file': lease_file,
     'disabled': False,
     'ddns_enable': False,
     'global_parameters': [],
     'hostfile_update': False,
+    'host_decl_name': False,
     'static_route': False,
     'wpad': False,
     'shared_network': [],
 }
 
 def get_config():
     dhcp = default_config_data
     conf = Config()
     if not conf.exists('service dhcp-server'):
         return None
     else:
         conf.set_level('service dhcp-server')
 
     # check for global disable of DHCP service
     if conf.exists('disable'):
         dhcp['disabled'] = True
 
     # check for global dynamic DNS upste
     if conf.exists('dynamic-dns-update'):
         dhcp['ddns_enable'] = True
 
     # HACKS AND TRICKS
     #
     # check for global 'raw' ISC DHCP parameters configured by users
     # actually this is a bad idea in general to pass raw parameters from any user
     if conf.exists('global-parameters'):
         dhcp['global_parameters'] = conf.return_values('global-parameters')
 
     # check for global DHCP server updating /etc/host per lease
     if conf.exists('hostfile-update'):
         dhcp['hostfile_update'] = True
 
+    # If enabled every host declaration within that scope, the name provided
+    # for the host declaration will be supplied to the client as its hostname.
+    if conf.exists('host-decl-name'):
+        dhcp['host_decl_name'] = True
+
     # check for multiple, shared networks served with DHCP addresses
     if conf.exists('shared-network-name'):
         for network in conf.list_nodes('shared-network-name'):
             conf.set_level('service dhcp-server shared-network-name {0}'.format(network))
             config = {
                 'name': network,
                 'authoritative': False,
                 'description': '',
                 'disabled': False,
                 'network_parameters': [],
                 'subnet': []
             }
             # check if DHCP server should be authoritative on this network
             if conf.exists('authoritative'):
                 config['authoritative'] = True
 
             # A description for this given network
             if conf.exists('description'):
                 config['description'] = conf.return_value('description')
 
             # If disabled, the shared-network configuration becomes inactive in
             # the running DHCP server instance
             if conf.exists('disable'):
                 config['disabled'] = True
 
             # HACKS AND TRICKS
             #
             # check for 'raw' ISC DHCP parameters configured by users
             # actually this is a bad idea in general to pass raw parameters
             # from any user
             #
             # deprecate this and issue a warning like we do for DNS forwarding?
             if conf.exists('shared-network-parameters'):
                 config['network_parameters'] = conf.return_values('shared-network-parameters')
 
             # check for multiple subnet configurations in a shared network
             # config segment
             if conf.exists('subnet'):
                 for net in conf.list_nodes('subnet'):
                     conf.set_level('service dhcp-server shared-network-name {0} subnet {1}'.format(network, net))
                     subnet = {
                         'network': net,
                         'address': str(ipaddress.ip_network(net).network_address),
                         'netmask': str(ipaddress.ip_network(net).netmask),
                         'bootfile_name': '',
                         'bootfile_server': '',
                         'client_prefix_length': '',
                         'default_router': '',
                         'dns_server': [],
                         'domain_name': '',
                         'domain_search': [],
                         'exclude': [],
                         'failover_local_addr': '',
                         'failover_name': '',
                         'failover_peer_addr': '',
                         'failover_status': '',
                         'ip_forwarding': False,
                         'lease': '86400',
                         'ntp_server': [],
                         'pop_server': [],
                         'server_identifier': '',
                         'smtp_server': [],
                         'range': [],
                         'static_mapping': [],
                         'static_subnet': '',
                         'static_router': '',
                         'static_route': '',
                         'subnet_parameters': [],
                         'tftp_server': '',
                         'time_offset': '',
                         'time_server': [],
                         'wins_server': [],
                         'wpad_url': ''
                     }
 
                     # Used to identify a bootstrap file
                     if conf.exists('bootfile-name'):
                         subnet['bootfile_name'] = conf.return_value('bootfile-name')
 
                     # Specify host address of the server from which the initial boot file
                     # (specified above) is to be loaded. Should be a numeric IP address or
                     # domain name.
                     if conf.exists('bootfile-server'):
                         subnet['bootfile_server'] = conf.return_value('bootfile-server')
 
                     # The subnet mask option specifies the client's subnet mask as per RFC 950. If no subnet
                     # mask option is provided anywhere in scope, as a last resort dhcpd will use the subnet
                     # mask from the subnet declaration for the network on which an address is being assigned.
                     if conf.exists('client-prefix-length'):
                         # snippet borrowed from https://stackoverflow.com/questions/33750233/convert-cidr-to-subnet-mask-in-python
                         host_bits = 32 - int(conf.return_value('client-prefix-length'))
                         subnet['client_prefix_length'] = socket.inet_ntoa(struct.pack('!I', (1 << 32) - (1 << host_bits)))
 
                     # Default router IP address on the client's subnet
                     if conf.exists('default-router'):
                         subnet['default_router'] = conf.return_value('default-router')
 
                     # Specifies a list of Domain Name System (STD 13, RFC 1035) name servers available to
                     # the client. Servers should be listed in order of preference.
                     if conf.exists('dns-server'):
                         subnet['dns_server'] = conf.return_values('dns-server')
 
                     # Option specifies the domain name that client should use when resolving hostnames
                     # via the Domain Name System.
                     if conf.exists('domain-name'):
                         subnet['domain_name'] = conf.return_value('domain-name')
 
                     # The domain-search option specifies a 'search list' of Domain Names to be used
                     # by the client to locate not-fully-qualified domain names.
                     if conf.exists('domain-search'):
                         for domain in conf.return_values('domain-search'):
                             subnet['domain_search'].append('"' + domain + '"')
 
                     # IP address (local) for failover peer to connect
                     if conf.exists('failover local-address'):
                         subnet['failover_local_addr'] = conf.return_value('failover local-address')
 
                     # DHCP failover peer name
                     if conf.exists('failover name'):
                         subnet['failover_name'] = conf.return_value('failover name')
 
                     # IP address (remote) of failover peer
                     if conf.exists('failover peer-address'):
                         subnet['failover_peer_addr'] = conf.return_value('failover peer-address')
 
                     # DHCP failover peer status (primary|secondary)
                     if conf.exists('failover status'):
                         subnet['failover_status'] = conf.return_value('failover status')
 
                     # Option specifies whether the client should configure its IP layer for packet
                     # forwarding
                     if conf.exists('ip-forwarding'):
                         subnet['ip_forwarding'] = True
 
                     # Time should be the length in seconds that will be assigned to a lease if the
                     # client requesting the lease does not ask for a specific expiration time
                     if conf.exists('lease'):
                         subnet['lease'] = conf.return_value('lease')
 
                     # Specifies a list of IP addresses indicating NTP (RFC 5905) servers available
                     # to the client.
                     if conf.exists('ntp-server'):
                         subnet['ntp_server'] = conf.return_values('ntp-server')
 
                     # POP3 server option specifies a list of POP3 servers available to the client.
                     # Servers should be listed in order of preference.
                     if conf.exists('pop-server'):
                         subnet['pop_server'] = conf.return_values('pop-server')
 
                     # DHCP servers include this option in the DHCPOFFER in order to allow the client
                     # to distinguish between lease offers. DHCP clients use the contents of the
                     # 'server identifier' field as the destination address for any DHCP messages
                     # unicast to the DHCP server
                     if conf.exists('server-identifier'):
                         subnet['server_identifier'] = conf.return_value('server-identifier')
 
                     # SMTP server option specifies a list of SMTP servers available to the client.
                     # Servers should be listed in order of preference.
                     if conf.exists('smtp-server'):
                         subnet['smtp_server'] = conf.return_values('smtp-server')
 
                     # For any subnet on which addresses will be assigned dynamically, there must be at
                     # least one range statement. The range statement gives the lowest and highest IP
                     # addresses in a range. All IP addresses in the range should be in the subnet in
                     # which the range statement is declared.
                     if conf.exists('range'):
                         for range in conf.list_nodes('range'):
                             range = {
                                 'start': conf.return_value('range {0} start'.format(range)),
                                 'stop':  conf.return_value('range {0} stop'.format(range))
                             }
                             subnet['range'].append(range)
 
                     # IP address that needs to be excluded from DHCP lease range
                     if conf.exists('exclude'):
                         # We have no need to store the exclude addresses. Exclude addresses
                         # are recalculated into several ranges
                         exclude = []
                         subnet['exclude'] = conf.return_values('exclude')
                         for addr in subnet['exclude']:
                             exclude.append(ipaddress.ip_address(addr))
 
                         # sort excluded IP addresses ascending
                         exclude = sorted(exclude)
 
                         # calculate multipe ranges based on the excluded IP addresses
                         output = []
                         for range in subnet['range']:
                             range_start = range['start']
                             range_stop = range['stop']
 
                             for i in exclude:
                                 # Excluded IP address must be in out specified range
                                 if (i >= ipaddress.ip_address(range_start)) and (i <= ipaddress.ip_address(range_stop)):
                                     # Build up new IP address range ending one IP address before
                                     # our exclude address
                                     range = {
                                         'start': str(range_start),
                                         'stop': str(i - 1)
                                     }
                                     # Our next IP address range will start one address after
                                     # our exclude address
                                     range_start = i + 1
                                     output.append(range)
 
                                     # Take care of last IP address range spanning from the last exclude
                                     # address (+1) to the end of the initial configured range
                                     if i is exclude[-1]:
                                         last = {
                                             'start': str(i + 1),
                                             'stop': str(range_stop)
                                         }
                                         output.append(last)
                                 else:
                                     # IP address not inside search range, take range is it is
                                     output.append(range)
 
                         # We successfully build up a new list containing several IP address
                         # ranges, replace IP address range in our dictionary
                         subnet['range'] = output
 
                     # Static DHCP leases
                     if conf.exists('static-mapping'):
                         for mapping in conf.list_nodes('static-mapping'):
                             conf.set_level('service dhcp-server shared-network-name {0} subnet {1} static-mapping {2}'.format(network, net, mapping))
                             mapping = {
                                 'name': mapping,
                                 'disabled': False,
                                 'ip_address': '',
                                 'mac_address': '',
                                 'static_parameters': []
                             }
 
                             # This static lease is disabled
                             if conf.exists('disable'):
                                 mapping['disabled'] = True
 
                             # IP address used for this DHCP client
                             if conf.exists('ip-address'):
                                 mapping['ip_address'] = conf.return_value('ip-address')
 
                             # MAC address of requesting DHCP client
                             if conf.exists('mac-address'):
                                 mapping['mac_address'] = conf.return_value('mac-address')
 
                             # HACKS AND TRICKS
                             #
                             # check for 'raw' ISC DHCP parameters configured by users
                             # actually this is a bad idea in general to pass raw parameters
                             # from any user
                             #
                             # deprecate this and issue a warning like we do for DNS forwarding?
                             if conf.exists('static-mapping-parameters'):
                                 mapping['static_parameters'] = conf.return_values('static-mapping-parameters')
 
                             # append static-mapping configuration to subnet list
                             subnet['static_mapping'].append(mapping)
 
                     # Reset config level to matching hirachy
                     conf.set_level('service dhcp-server shared-network-name {0} subnet {1}'.format(network, net))
 
                     # This option specifies a list of static routes that the client should install in its routing
                     # cache. If multiple routes to the same destination are specified, they are listed in descending
                     # order of priority.
                     if conf.exists('static-route destination-subnet'):
                         subnet['static_subnet'] = conf.return_value('static-route destination-subnet')
                         # Required for global config section
                         dhcp['static_route'] = True
 
                     if conf.exists('static-route router'):
                         subnet['static_router'] = conf.return_value('static-route router')
 
                     if subnet['static_router'] and subnet['static_subnet']:
                         # https://ercpe.de/blog/pushing-static-routes-with-isc-dhcp-server
                         # Option format is:
                         # <netmask>, <network-byte1>, <network-byte2>, <network-byte3>, <router-byte1>, <router-byte2>, <router-byte3>
                         # where bytes with the value 0 are omitted.
                         net = ipaddress.ip_network(subnet['static_subnet'])
                         # add netmask
                         string = str(net.prefixlen) + ','
                         # add network bytes
                         bytes = str(net.network_address).split('.')
                         for b in bytes:
                             if b != '0':
                                 string += b + ','
 
                         # add router bytes
                         bytes = subnet['static_router'].split('.')
                         for b in bytes:
                             if b != '0':
                                 string += b
                                 if b is not bytes[-1]:
                                     string += ','
 
                         subnet['static_route'] = string
 
                     # HACKS AND TRICKS
                     #
                     # check for 'raw' ISC DHCP parameters configured by users
                     # actually this is a bad idea in general to pass raw parameters
                     # from any user
                     #
                     # deprecate this and issue a warning like we do for DNS forwarding?
                     if conf.exists('subnet-parameters'):
                         subnet['subnet_parameters'] = conf.return_values('subnet-parameters')
 
                     # This option is used to identify a TFTP server and, if supported by the client, should have
                     # the same effect as the server-name declaration. BOOTP clients are unlikely to support this
                     # option. Some DHCP clients will support it, and others actually require it.
                     if conf.exists('tftp-server-name'):
                         subnet['tftp_server'] = conf.return_value('tftp-server-name')
 
                     # The time-offset option specifies the offset of the client’s subnet in seconds from
                     # Coordinated Universal Time (UTC).
                     if conf.exists('time-offset'):
                         subnet['time_offset'] = conf.return_value('time-offset')
 
                     # The time-server option specifies a list of RFC 868 time servers available to the client.
                     # Servers should be listed in order of preference.
                     if conf.exists('time-server'):
                         subnet['time_server'] = conf.return_values('time-server')
 
                     # The NetBIOS name server (NBNS) option specifies a list of RFC 1001/1002 NBNS name servers
                     # listed in order of preference. NetBIOS Name Service is currently more commonly referred to
                     # as WINS. WINS servers can be specified using the netbios-name-servers option.
                     if conf.exists('wins-server'):
                         subnet['wins_server'] = conf.return_values('wins-server')
 
                     # URL for Web Proxy Autodiscovery Protocol
                     if conf.exists('wpad-url'):
                         subnet['wpad_url'] = conf.return_value('wpad-url')
                         # Required for global config section
                         dhcp['wpad'] = True
 
                     # append subnet configuration to shared network subnet list
                     config['subnet'].append(subnet)
 
             # append shared network configuration to config dictionary
             dhcp['shared_network'].append(config)
 
     return dhcp
 
 def verify(dhcp):
     if (dhcp is None) or (dhcp['disabled'] is True):
         return None
 
     # If DHCP is enabled we need one share-network
     if len(dhcp['shared_network']) == 0:
         raise ConfigError('No DHCP shared networks configured.\n' \
                           'At least one DHCP shared network must be configured.')
 
     # Inspect shared-network/subnet
     failover_names = []
     listen_ok = False
     subnets = []
 
     # A shared-network requires a subnet definition
     for network in dhcp['shared_network']:
         if len(network['subnet']) == 0:
             raise ConfigError('No DHCP lease subnets configured for {0}. At least one\n' \
                               'lease subnet must be configured for each shared network.'.format(network['name']))
 
         for subnet in network['subnet']:
             # Subnet static route declaration requires destination and router
             if subnet['static_subnet'] or subnet['static_router']:
                 if not (subnet['static_subnet'] and subnet['static_router']):
                     raise ConfigError('Please specify missing DHCP static-route parameter(s):\n' \
                                       'destination-subnet | router')
 
             # Failover requires all 4 parameters set
             if subnet['failover_local_addr'] or subnet['failover_peer_addr'] or subnet['failover_name'] or subnet['failover_status']:
                 if not (subnet['failover_local_addr'] and subnet['failover_peer_addr'] and subnet['failover_name'] and subnet['failover_status']):
                     raise ConfigError('Please specify missing DHCP failover parameter(s):\n' \
                                       'local-address | peer-address | name | status')
 
                 # Failover names must be uniquie
                 if subnet['failover_name'] in failover_names:
                     raise ConfigError('Failover names must be unique:\n' \
                                       '{0} has already been configured!'.format(subnet['failover_name']))
                 else:
                     failover_names.append(subnet['failover_name'])
 
                 # Failover requires start/stop ranges for pool
                 if (len(subnet['range']) == 0):
                     raise ConfigError('At least one start-stop range must be configured for {0}\n' \
                                       'to set up DHCP failover!'.format(subnet['network']))
 
             # Check if DHCP address range is inside configured subnet declaration
             range_start = []
             range_stop = []
             for range in subnet['range']:
                 start = range['start']
                 stop = range['stop']
                 # DHCP stop IP required after start IP
                 if start and not stop:
                     raise ConfigError('DHCP range stop address for start {0} is not defined!'.format(start))
 
                 # Start address must be inside network
                 if not ipaddress.ip_address(start) in ipaddress.ip_network(subnet['network']):
                     raise ConfigError('DHCP range start address {0} is not in subnet {1}\n' \
                                       'specified for shared network {2}!'.format(start, subnet['network'], network['name']))
 
                 # Stop address must be inside network
                 if not ipaddress.ip_address(stop) in ipaddress.ip_network(subnet['network']):
                     raise ConfigError('DHCP range stop address {0} is not in subnet {1}\n' \
                                       'specified for shared network {2}!'.format(stop, subnet['network'], network['name']))
 
                 # Stop address must be greater or equal to start address
                 if not ipaddress.ip_address(stop) >= ipaddress.ip_address(start):
                     raise ConfigError('DHCP range stop address {0} must be greater or equal\n' \
                                       'to the range start address {1}!'.format(stop, start))
 
                 # Range start address must be unique
                 if start in range_start:
                     raise ConfigError('Conflicting DHCP lease range:\n' \
                                       'Pool start address {0} defined multipe times!'.format(start))
                 else:
                     range_start.append(start)
 
                 # Range stop address must be unique
                 if stop in range_stop:
                     raise ConfigError('Conflicting DHCP lease range:\n' \
                                       'Pool stop address {0} defined multipe times!'.format(stop))
                 else:
                     range_stop.append(stop)
 
             # Exclude addresses must be in bound
             for exclude in subnet['exclude']:
                 if not ipaddress.ip_address(exclude) in ipaddress.ip_network(subnet['network']):
                     raise ConfigError('Exclude IP address {0} is outside of the DHCP lease network {1}\n' \
                                       'under shared network {2}!'.format(exclude, subnet['network'], network['name']))
 
             # At least one DHCP address range or static-mapping required
             active_mapping = False
             if (len(subnet['range']) == 0):
                 for mapping in subnet['static_mapping']:
                     # we need at least one active mapping
                     if (not active_mapping) and (not mapping['disabled']):
                         active_mapping = True
             else:
                 active_mapping = True
 
             if not active_mapping:
                 raise ConfigError('No DHCP address range or active static-mapping set\n' \
                                   'for subnet {0}!'.format(subnet['network']))
 
             # Static IP address mappings require both an IP address and MAC address
             for mapping in subnet['static_mapping']:
                 # Static IP address must be configured
                 if not mapping['ip_address']:
                     raise ConfigError('DHCP static lease IP address not specified for static mapping\n' \
                                       '{0} under shared network name {1}!'.format(mapping['name'], network['name']))
 
                 # Static IP address must be in bound
                 if not ipaddress.ip_address(mapping['ip_address']) in ipaddress.ip_network(subnet['network']):
                     raise ConfigError('DHCP static lease IP address {0} for static mapping {1}\n' \
                                       'in shared network {2} is outside DHCP lease subnet {3}!' \
                                       .format(mapping['ip_address'], mapping['name'], network['name'], subnet['network']))
 
                 # Static mapping requires MAC address
                 if not mapping['mac_address']:
                      raise ConfigError('DHCP static lease MAC address not specified for static mapping\n' \
                                        '{0} under shared network name {1}!'.format(mapping['name'], network['name']))
 
             # There must be one subnet connected to a listen interface.
             # This only counts if the network itself is not disabled!
             if not network['disabled']:
                 if vyos.validate.is_subnet_connected(subnet['network'], primary=True):
                     listen_ok = True
 
             # Subnets must be non overlapping
             if subnet['network'] in subnets:
                 raise ConfigError('DHCP subnets must be unique! Subnet {0} defined multiple times!'.format(subnet))
             else:
                 subnets.append(subnet['network'])
 
             # Check for overlapping subnets
             net = ipaddress.ip_network(subnet['network'])
             for n in subnets:
                 net2 = ipaddress.ip_network(n)
                 if (net != net2):
                     if net.overlaps(net2):
                         raise ConfigError('DHCP conflicting subnet ranges: {0} overlaps {1}'.format(net, net2))
 
     if not listen_ok:
         raise ConfigError('None of the DHCP lease subnets are inside any configured subnet on\n' \
                           'broadcast interfaces. At least one lease subnet must be set such that\n' \
                           'DHCP server listens on a one broadcast interface!')
 
     return None
 
 def generate(dhcp):
     if dhcp is None:
         return None
 
     if dhcp['disabled'] is True:
         print('Warning: DHCP server will be deactivated because it is disabled')
         return None
 
     tmpl = jinja2.Template(config_tmpl)
     config_text = tmpl.render(dhcp)
 
     # Please see: https://phabricator.vyos.net/T1129 for quoting of the raw parameters
     # we can pass to ISC DHCPd
     config_text = config_text.replace("&quot;",'"')
 
     with open(config_file, 'w') as f:
         f.write(config_text)
 
     tmpl = jinja2.Template(daemon_tmpl)
     config_text = tmpl.render(dhcp)
     with open(daemon_config_file, 'w') as f:
         f.write(config_text)
 
     return None
 
 def apply(dhcp):
     if (dhcp is None) or dhcp['disabled']:
         # DHCP server is removed in the commit
         os.system('sudo systemctl stop isc-dhcp-server.service')
         if os.path.exists(config_file):
             os.unlink(config_file)
         if os.path.exists(daemon_config_file):
             os.unlink(daemon_config_file)
     else:
         # If our file holding DHCP leases does yet not exist - create it
         if not os.path.exists(lease_file):
             os.mknod(lease_file)
 
         os.system('sudo systemctl restart isc-dhcp-server.service')
 
     return None
 
 if __name__ == '__main__':
     try:
         c = get_config()
         verify(c)
         generate(c)
         apply(c)
     except ConfigError as e:
         print(e)
         sys.exit(1)