Commit b7720538 authored by Marcin Siodelski's avatar Marcin Siodelski

[3484] Updated Developer's Guide for the DHCPv4 server.

parent 655ba0fe
......@@ -15,34 +15,125 @@
@page dhcp4 DHCPv4 Server Component
Kea offers DHCPv4 server implementation. It is implemented as
kea-dhcp4 component. Its primary code is located in
isc::dhcp::Dhcpv4Srv class. It uses \ref libdhcp extensively,
especially isc::dhcp::Pkt4, isc::dhcp::Option and
isc::dhcp::IfaceMgr classes. Currently this code offers skeleton
functionality, i.e. it is able to receive and process incoming
requests and transmit responses. However, it does not have database
management, so it returns only one, hardcoded lease to whoever asks
for it.
DHCPv4 server component does not support direct traffic (relayed
only), as support for transmission to hosts without IPv4 address
assigned is not implemented in IfaceMgr yet.
Kea includes the "kea-dhcp4" component, which is the DHCPv4 server
implementation. This component is built around the
@ref isc::dhcp::Dhcpv4Srv class which controls all major operations
performed by the server such as: DHCP messages processing, callouts
execution for many hook points, FQDN processing and interactions with the
"kea-dhcp-ddns" component, lease allocation, system signals handling etc.
The "kea-dhcp4" component requires linking with many different libraries
to obtain access to common functions like: interfaces and sockets
management, configuration parsing, leases management and allocation,
hooks infrastructure, statistics management etc.
The following sections walk through some of the details of the "kea-dhcp4"
component implementation.
@section dhcpv4ConfigParser Configuration Parser in DHCPv4
This parser follows exactly the same logic as its DHCPv6 counterpart.
See \ref dhcpv6ConfigParser.
The common configuration parsers for the DHCP servers are located in the
src/lib/dhcpsrv/parsers/ directory. Parsers specific to the DHCPv4 component
are located in the src/bin/dhcp4/ These parsers derive
from the common configuration parsers and customize their behavior. For
example: the @c Subnet4ConfigParser is used to parse parameters
describing a single subnet. It derives from the @ref
isc::dhcp::SubnetConfigParser, which implements the common base for both
DHCPv4 and DHCPv6 subnets. The @ref isc::dhcp::Subnet4ConfigParser
implements the @c initSubnet abstract method, which creates an instance of
the DHCPv4 subnet. This method is invoked by the parent class.
Some parsers for the DHCPv4 server derive from the isc::dhcp::DhcpConfigParser
class directly. This is an abstract class, defining a basic interface for
all configuration parsers. All DHCPv4 parsers deriving from this class
directly have their entire implementation in the
@section dhcpv4ConfigInherit DHCPv4 configuration inheritance
Configuration inheritance in DHCPv4 follows exactly the same logic as its DHCPv6
counterpart. See \ref dhcpv6ConfigInherit.
One notable useful feature of DHCP configuration is its parameter inheritance.
For example, "renew-timer" value may be specified at a global scope and it then
applies to all subnets. However, some subnets may have it overwritten with subnet
specific values that takes precedence over global values that are considered
defaults. The parameters inheritance is implemented by means of the "global
context". The global context is represented by the @ref isc::dhcp::ParserContext
class and it holds pointers to storages of different kind, e.g. text parameters,
numeric parameters etc. When the server is parsing the top level configuration
parameters it passes pointers to the storages of the appropriate kind, to the
parsers being invoked to parse the global values. Parsers will store the
parsed values into these storages. Once the global parameters are stored in the
global context, the parsers for the nested configuration parameters are invoked.
These parsers check the presence of the parameters overriding the values of
the global parameters. If a value is not present, the values from the global
context is used.
A good example of inheritance is the implementation of the @ref
isc::dhcp::SubnetConfigParser. The @c getParam method is used throughout the
class to obtain values of the parameters defining a subnet. It first checks
if the specific value is present in the local values storage. If it is not
present, it uses the value from the global context.
SubnetConfigParser::getParam(const std::string& name) {
uint32_t value = 0;
try {
// look for local value
value = uint32_values_->getParam(name);
} catch (const DhcpConfigError &) {
try {
// no local, use global value
value = global_context_->uint32_values_->getParam(name);
} catch (const DhcpConfigError &) {
isc_throw(DhcpConfigError, "Mandatory parameter " << name
<< " missing (no global default and no subnet-"
<< "specific value)");
return (Triplet<uint32_t>(value));
Note that if the value is neither present in the local storage nor in the global
context an error is signalled.
Parameter inheritance is done once, during the reconfiguration phase.
Reconfigurations are rare, so extra logic here is not a problem. On the other
hand, values of those parameters may be used thousands times per second, so
access to these parameters must be as efficient as possible. In fact,
currently the code has to only call @c Subnet4::getT1(), regardless if the
"renew-timer" has been specified as a global or subnet specific value.
Debugging configuration parser may be confusing. Therefore there is a special
class called DebugParser. It does not configure anything, but just
accepts any parameter of any type. If requested to commit configuration, it will
print out received parameter name and its value. This class is not currently used,
but it is convenient to have it every time a new parameter is added to DHCP
configuration. For that purpose it should be left in the code.
@section dhcpv4OptionsParse Custom functions to parse message options
The DHCPv4 server uses the same logic to supply custom callback function to
parse message option as DHCPv6 server implementation. See \ref dhcpv6OptionsParse.
The DHCPv4 server implementation provides a generic support to define option
formats and set option values. A number of options formats have been defined
for standard options in libdhcp++. However, the formats for vendor specific
options are dynamically configured by the server's administrator and thus can't
be stored in libdhcp++. Such option formats are stored in the
@ref isc::dhcp::CfgMgr. The libdhcp++ provides functions for recursive parsing
of options which may be encapsulated by other options up to the any level of
encapsulation but these functions are unaware of the option formats defined
in the @ref isc::dhcp::CfgMgr because they belong to a different library.
Therefore, the generic functions @ref isc::dhcp::LibDHCP::unpackOptions4 and
@ref isc::dhcp::LibDHCP::unpackOptions4 are only useful to parse standard
options which definitions are provided in the libdhcp++. In order to overcome
this problem a callback mechanism has been implemented in @c Option and @c Pkt4
classes. By installing a callback function on the instance of the @c Pkt4 the
server may provide a custom implementation of the options parsing algorithm.
This callback function will take precedence over the @c LibDHCP::unpackOptions4
and @c LibDHCP::unpackOptions4 functions. With this approach, the callback is
implemented within the context of the server and it has access to all objects
which define its configuration (including dynamically created option
@section dhcpv4DDNSIntegration DHCPv4 Server Support for the Dynamic DNS Updates
......@@ -201,13 +292,9 @@ through the main loop. This method fetches the last received signal and calls
a handler function defined in the The handler function
calls a static function @c configure defined in the
In order for the signal handler to know the location of the configuration file
(specified at process startup), the location of this file needs to be stored
in a static variable so as it may be directly accessed by the signal handler.
This static variable is stored in the @c dhcp::Daemon class and all Kea processes
can use it (all processes derive from this class). The configuration file
location is initialized when the @c Daemon::init method is called. Therefore,
derived classes should call it in their implementations of the @c init method.
The signal handler reconfigures the server using the configuration file
specified at the server startup. The location of this file is held in the
@c Daemon class.
@section dhcpv4Other Other DHCPv4 topics
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment