Commit 94e8a6e4 authored by Francis Dupont's avatar Francis Dupont
Browse files

[master] Merge branch 'master' of ssh://git.kea.isc.org/git/kea

parents a6251e3f b3658dcb
1200 [func] tmark
1202. [func] tomek
Parsers for mac-sources, control-socket, and relay-info converted
to SimpleParser. It is no longer accepted to specify empty
mac-sources. Either specify actual values in mac-sources or
don't specify mac-sources at all.
(Trac #5032, git f1c9dee0936b48be28f890ffd428fbdeb87c12ea)
1201. [func] tmark
kea-dhcp4 and kea-dhcp6 now support the "set-config" command.
The command causes the server to replace its current configuration
with the configuration supplied as the command's argument.
(Trac #5046, git 4afbdcf89c9f83d944f774d05bd401d3f2768d10)
1200. [func] tmark
kea-dhcp4 and kea-dhcp6 now support the Command Channel "libreload"
command. The command causes the server to unload and then load all
currently loaded hook libraries.
......@@ -18,7 +31,7 @@
Created kea-ctrl-agent. This application currently doesn't
do anything. Future tickets will add REST API to allow for
managing Kea services.
(Trac #5075, git 1ec7586da5ae1474b52d5a395fb80ee37d6d568e)
(Trac #5075, git 1ec7586da5ae1474b52d5a395fb80ee37d6d568e)
1197. [doc] tomek
Configuration examples now set lfc-interval to a default
......
......@@ -44,6 +44,14 @@
"lfc-interval": 3600
},
// This defines a control socket. If defined, Kea will open a UNIX socket
// and will listen for incoming commands. See section 15 of the Kea User's
// Guide for list of supported commands.
"control-socket": {
"socket-type": "unix",
"socket-name": "/tmp/kea4-ctrl-socket"
},
// Addresses will be assigned with a lifetime of 4000 seconds.
// The client is told to start renewing after 1000 seconds. If the server
// does not respond within 2000 seconds of the lease being granted, client
......@@ -83,7 +91,14 @@
},
{
"pools": [ { "pool": "192.0.4.1 - 192.0.4.254" } ],
"subnet": "192.0.4.0/24"
"subnet": "192.0.4.0/24",
// Sometimes the relay may use an IPv4 address that does not match
// the subnet. This is discouraged, but there are valid cases when it
// makes sense. One case is when there is a shared subnet.
"relay": {
"ip-address": "192.168.1.1"
}
}
]
},
......
# This is an example configuration file for DHCPv6 server in Kea.
# It attempts to showcase some of the more advanced features.
# Topology wise, it's a basic scenario with one IPv6 subnet configured.
# It is assumed that one subnet (2001:db8:1::/64) is available directly
# over ethX interface.
#
# The following features are currently showcased here:
# 1. Configuration of MAC/hardware address sources in DHCPv6
// This is an example configuration file for DHCPv6 server in Kea.
// It attempts to showcase some of the more advanced features.
// Topology wise, it's a basic scenario with one IPv6 subnet configured.
// It is assumed that one subnet (2001:db8:1::/64) is available directly
// over ethX interface.
//
// The following features are currently showcased here:
// 1. Configuration of MAC/hardware address sources in DHCPv6
// 2. RSOO (Relay supplied options) - Some relays may insert options with the
// intention for the server to insert them into client directed messages.
// 3. Control socket. Kea can open a socket and listen for incoming
// commands.
{ "Dhcp6":
{
# Kea is told to listen on ethX network interface only.
// Kea is told to listen on ethX network interface only.
"interfaces-config": {
"interfaces": [ "ethX" ]
},
# We need to specify the the database used to store leases. As of
# September 2016, four database backends are supported: MySQL,
# PostgreSQL, Cassandra, and the in-memory database, Memfile.
# We will use memfile because it doesn't require any prior set up.
// We need to specify the the database used to store leases. As of
// September 2016, four database backends are supported: MySQL,
// PostgreSQL, Cassandra, and the in-memory database, Memfile.
// We will use memfile because it doesn't require any prior set up.
"lease-database": {
"type": "memfile",
"lfc-interval": 3600
},
# Kea 0.9.1 introduced MAC/hardware addresses support in DHCPv6. There is
# no single reliable method of getting MAC address information in DHCPv6.
# Kea supports several methods. Depending on your network set up, some
# methods may be more preferable than others, hence the configuration
# parameter. 'mac-sources' is a list of methods. Allowed parameters are:
# any, raw, duid, ipv6-link-local, client-link-addr-option, rfc6939 (which
# is an alias for client-link-addr-option), remote-id, rfc4649 (which is an
# alias for remote-id, subscriber-id, rfc4580 (which is an alias for
# subscriber-id) and docsis.
#
# Note that the order matters. Methods are attempted one by one in the order
# specified until hardware address is obtained. If you don't care which method
# is used, using 'any' is marginally faster than enumerating them all.
#
# If mac-sources are not specified, a default value of 'any' is used.
// Kea 0.9.1 introduced MAC/hardware addresses support in DHCPv6. There is
// no single reliable method of getting MAC address information in DHCPv6.
// Kea supports several methods. Depending on your network set up, some
// methods may be more preferable than others, hence the configuration
// parameter. 'mac-sources' is a list of methods. Allowed parameters are:
// any, raw, duid, ipv6-link-local, client-link-addr-option, rfc6939 (which
// is an alias for client-link-addr-option), remote-id, rfc4649 (which is an
// alias for remote-id, subscriber-id, rfc4580 (which is an alias for
// subscriber-id) and docsis.
//
// Note that the order matters. Methods are attempted one by one in the order
// specified until hardware address is obtained. If you don't care which method
// is used, using 'any' is marginally faster than enumerating them all.
//
// If mac-sources are not specified, a default value of 'any' is used.
"mac-sources": [ "client-link-addr-option", "duid", "ipv6-link-local" ],
# RFC6422 defines a mechanism called relay-supplied options option. The relay
# agent may insert certain options that the server will echo back to the
# client, if certain criteria are met. One condition is that the option must
# be RSOO-enabled (i.e. allowed to be echoed back). IANA maintains a list
# of those options here:
# http://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#options-relay-supplied
# However, it is possible to allow the server to echo back additional options.
# This entry marks options 110, 120 and 130 as RSOO-enabled.
// RFC6422 defines a mechanism called relay-supplied options option. The relay
// agent may insert certain options that the server will echo back to the
// client, if certain criteria are met. One condition is that the option must
// be RSOO-enabled (i.e. allowed to be echoed back). IANA maintains a list
// of those options here:
// http://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#options-relay-supplied
// However, it is possible to allow the server to echo back additional options.
// This entry marks options 110, 120 and 130 as RSOO-enabled.
"relay-supplied-options": [ "110", "120", "130" ],
# Addresses will be assigned with preferred and valid lifetimes
# being 3000 and 4000, respectively. Client is told to start
# renewing after 1000 seconds. If the server does not respond
# after 2000 seconds since the lease was granted, client is supposed
# to start REBIND procedure (emergency renewal that allows switching
# to a different server).
// This defines a control socket. If defined, Kea will open a UNIX socket
// and will listen for incoming commands. See section 15 of the Kea User's
// Guide for list of supported commands.
"control-socket": {
"socket-type": "unix",
"socket-name": "/tmp/kea6-ctrl-socket"
},
// Addresses will be assigned with preferred and valid lifetimes
// being 3000 and 4000, respectively. Client is told to start
// renewing after 1000 seconds. If the server does not respond
// after 2000 seconds since the lease was granted, client is supposed
// to start REBIND procedure (emergency renewal that allows switching
// to a different server).
"preferred-lifetime": 3000,
"valid-lifetime": 4000,
"renew-timer": 1000,
"rebind-timer": 2000,
# The following list defines subnets. Each subnet consists of at
# least subnet and pool entries.
// The following list defines subnets. Each subnet consists of at
// least subnet and pool entries.
"subnet6": [
{
"pools": [ { "pool": "2001:db8:1::/80" } ],
# This defines PD (prefix delegation) pools. In this case
# we have only one pool. That consists of /64 prefixes
# being delegated out of large /48 pool. Each delegated
# prefix will contain an excluded-prefix option.
// This defines PD (prefix delegation) pools. In this case
// we have only one pool. That consists of /64 prefixes
// being delegated out of large /48 pool. Each delegated
// prefix will contain an excluded-prefix option.
"pd-pools": [
{
"prefix": "2001:db8:abcd::",
......@@ -82,13 +95,21 @@
}
],
"subnet": "2001:db8:1::/64",
"interface": "ethX"
"interface": "ethX",
// Sometimes the relay may use an odd IPv6 address that's not matching
// the subnet. This is discouraged, but there are valid cases when it
// makes sense. One case is when the relay has only link-local address
// and another is when there is a shared subnet scenario.
"relay": {
"ip-address": "3000::1"
}
}
]
},
# The following configures logging. It assumes that messages with at least
# informational level (info, warn, error and fatal) should be logged to stdout.
// The following configures logging. It assumes that messages with at least
// informational level (info, warn, error and fatal) should be logged to stdout.
"Logging": {
"loggers": [
{
......
......@@ -184,6 +184,65 @@ will be sent to Kea and the responses received from Kea printed to standard outp
</para>
</section> <!-- end of command-list-commands -->
<section id="command-set-config">
<title>set-config</title>
<para>
The <emphasis>set-config</emphasis> command instructs the server to replace
its current configuration with the new configuration supplied in the
command's arguments. The supplied configuration is expected to be the full
configuration for the target server along with an optional Logger
configuration. While optional, the Logger configuration is highly
recommended as without it the server will revert to its default logging
configuration. The structure of the command is as follows:
</para>
<screen>
{
"command": "set-config",
"arguments": {
"&#60;server&#62;": {
},
"Logging": {
}
}
}
</screen>
<para>
where &#60;server&#62; is the configuration element name for a given server
such as "Dhcp4" or "Dhcp6". For example:
</para>
<screen>
{
"command": "set-config",
"arguments": {
"Dhcp6": {
:
},
"Logging": {
:
}
}
}
</screen>
<para>
If the new configuration proves to be invalid the server will retain
its current configuration. Please note that the new configuration is
retained in memory only. If the server is restarted or a configuration
reload is triggered via a signal, the server will use the configuration
stored in its configuration file.
The server's response will contain a numeric code, "result" (0 for success,
non-zero on failure), and a string, "text", describing the outcome:
<screen>
{"result": 0, "text": "Configuration successful." }
or
{"result": 1, "text": "unsupported parameter: BOGUS (&#60;string&#62;:16:26)" }
</screen>
</para>
</section> <!-- end of command-set-config -->
<section id="command-shutdown">
<title>shutdown</title>
......@@ -205,6 +264,8 @@ will be sent to Kea and the responses received from Kea printed to standard outp
</para>
</section> <!-- end of command-shutdown -->
</section> <!-- end of commands supported by both servers -->
</chapter>
......@@ -3203,6 +3203,9 @@ src/lib/dhcpsrv/cfg_host_operations.cc -->
</screen>
</para>
<para>If "relay" is specified, the "ip-address" parameter within
it is mandatory.</para>
</section>
<section id="dhcp4-srv-example-client-class-relay">
......@@ -3649,17 +3652,30 @@ src/lib/dhcpsrv/cfg_host_operations.cc -->
<para>
Communication over control channel is conducted using JSON structures.
See the Control Channel section in the Kea Developer's Guide for more details.
See the Control Channel section in the Kea Developer's Guide for more
details.
</para>
<para>The DHCPv4 server supports the following operational commands:
<itemizedlist>
<listitem>leases-reclaim</listitem>
<listitem>list-commands</listitem>
<listitem>set-config</listitem>
<listitem>shutdown</listitem>
</itemizedlist>
as described in <xref linkend="commands-common"/>. In addition,
it supports the following statistics related commands:
<itemizedlist>
<listitem>statistic-get</listitem>
<listitem>statistic-reset</listitem>
<listitem>statistic-remove</listitem>
<listitem>statistic-get-all</listitem>
<listitem>statistic-reset-all</listitem>
<listitem>statistic-remove-all</listitem>
</itemizedlist>
as described here <xref linkend="command-stats"/>.
</para>
<para>The DHCPv4 server supports <command>statistic-get</command>,
<command>statistic-reset</command>, <command>statistic-remove</command>,
<command>statistic-get-all</command>, <command>statistic-reset-all</command>
and <command>statistic-remove-all</command>, specified in
<xref linkend="command-stats"/>. It also supports
<command>list-commands</command> and <command>shutdown</command>,
specified in <xref linkend="command-list-commands" /> and
<xref linkend="command-shutdown" />, respectively.</para>
</section>
<section id="dhcp4-std">
......
......@@ -3410,6 +3410,9 @@ If not specified, the default value is:
</screen>
</para>
<para>If "relay" is specified, the "ip-address" parameter within
it is mandatory.</para>
</section>
<section id="dhcp6-client-class-relay">
......@@ -3500,7 +3503,8 @@ If not specified, the default value is:
When not specified, a special value of "any" is used, which
instructs the server to attempt to use all the methods in sequence and use
value returned by the first one that succeeds.</para>
value returned by the first one that succeeds. If specified, it
has to have at least one value.</para>
<para>Supported methods are:
<itemizedlist>
......@@ -4062,16 +4066,27 @@ If not specified, the default value is:
See the Control Channel section in the Kea Developer's Guide for more details.
</para>
<para>The DHCPv6 server supports <command>statistic-get</command>,
<command>statistic-reset</command>, <command>statistic-remove</command>,
<command>statistic-get-all</command>, <command>statistic-reset-all</command>
and <command>statistic-remove-all</command>, specified in
<xref linkend="command-stats"/>. It also supports
<command>list-commands</command> and <command>shutdown</command>,
specified in <xref linkend="command-list-commands" /> and
<xref linkend="command-shutdown" />, respectively.</para>
</section>
<para>The DHCPv6 server supports the following operational commands:
<itemizedlist>
<listitem>leases-reclaim</listitem>
<listitem>list-commands</listitem>
<listitem>set-config</listitem>
<listitem>shutdown</listitem>
</itemizedlist>
as described in <xref linkend="commands-common"/>. In addition,
it supports the following statistics related commands:
<itemizedlist>
<listitem>statistic-get</listitem>
<listitem>statistic-reset</listitem>
<listitem>statistic-remove</listitem>
<listitem>statistic-get-all</listitem>
<listitem>statistic-reset-all</listitem>
<listitem>statistic-remove-all</listitem>
</itemizedlist>
as described here <xref linkend="command-stats"/>.
</para>
</section>
<section>
<title>User context in IPv6 pools</title>
......
// Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -62,7 +62,69 @@ ControlledDhcpv4Srv::commandLibReloadHandler(const string&, ConstElementPtr) {
ConstElementPtr
ControlledDhcpv4Srv::commandConfigReloadHandler(const string&,
ConstElementPtr args) {
return (processConfig(args));
// Use set-config as it handles logging and server config
return (commandSetConfigHandler("set-config", args));
}
ConstElementPtr
ControlledDhcpv4Srv::commandSetConfigHandler(const string&,
ConstElementPtr args) {
const int status_code = 1; // 1 indicates an error
ConstElementPtr dhcp4;
string message;
// Command arguments are expected to be:
// { "Dhcp4": { ... }, "Logging": { ... } }
// The Logging component is technically optional. If it's not supplied
// logging will revert to default logging.
if (!args) {
message = "Missing mandatory 'arguments' parameter.";
} else {
dhcp4 = args->get("Dhcp4");
if (!dhcp4) {
message = "Missing mandatory 'Dhcp4' parameter.";
} else if (dhcp4->getType() != Element::map) {
message = "'Dhcp4' parameter expected to be a map.";
}
}
if (!message.empty()) {
// Something is amiss with arguments, return a failure response.
ConstElementPtr result = isc::config::createAnswer(status_code,
message);
return (result);
}
// We are starting the configuration process so we should remove any
// staging configuration that has been created during previous
// configuration attempts.
CfgMgr::instance().rollback();
// Logging is a sibling element and must be parsed explicitly.
// The call to configureLogger parses the given Logging element if
// not null, into the staging config. Note this does not alter the
// current loggers, they remain in effect until we apply the
// logging config below. If no logging is supplied logging will
// revert to default logging.
Daemon::configureLogger(args->get("Logging"),
CfgMgr::instance().getStagingCfg());
// Now we configure the server proper.
ConstElementPtr result = processConfig(dhcp4);
// If the configuration parsed successfully, apply the new logger
// configuration and the commit the new configuration. We apply
// the logging first in case there's a configuration failure.
int rcode = 0;
isc::config::parseAnswer(rcode, result);
if (rcode == 0) {
CfgMgr::instance().getStagingCfg()->applyLoggingCfg();
// Use new configuration.
CfgMgr::instance().commit();
}
return (result);
}
ConstElementPtr
......@@ -116,6 +178,9 @@ ControlledDhcpv4Srv::processCommand(const string& command,
} else if (command == "config-reload") {
return (srv->commandConfigReloadHandler(command, args));
} else if (command == "set-config") {
return (srv->commandSetConfigHandler(command, args));
} else if (command == "leases-reclaim") {
return (srv->commandLeasesReclaimHandler(command, args));
}
......@@ -235,8 +300,6 @@ ControlledDhcpv4Srv::processConfig(isc::data::ConstElementPtr config) {
}
}
return (answer);
}
......@@ -257,6 +320,9 @@ ControlledDhcpv4Srv::ControlledDhcpv4Srv(uint16_t port /*= DHCP4_SERVER_PORT*/)
CommandMgr::instance().registerCommand("libreload",
boost::bind(&ControlledDhcpv4Srv::commandLibReloadHandler, this, _1, _2));
CommandMgr::instance().registerCommand("set-config",
boost::bind(&ControlledDhcpv4Srv::commandSetConfigHandler, this, _1, _2));
CommandMgr::instance().registerCommand("leases-reclaim",
boost::bind(&ControlledDhcpv4Srv::commandLeasesReclaimHandler, this, _1, _2));
......@@ -300,6 +366,7 @@ ControlledDhcpv4Srv::~ControlledDhcpv4Srv() {
// Deregister any registered commands
CommandMgr::instance().deregisterCommand("shutdown");
CommandMgr::instance().deregisterCommand("libreload");
CommandMgr::instance().deregisterCommand("set-config");
CommandMgr::instance().deregisterCommand("leases-reclaim");
CommandMgr::instance().deregisterCommand("statistic-get");
CommandMgr::instance().deregisterCommand("statistic-reset");
......
// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2012-2017 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -143,6 +143,19 @@ private:
commandConfigReloadHandler(const std::string& command,
isc::data::ConstElementPtr args);
/// @brief handler for processing 'set-config' command
///
/// This handler processes set-config command, which processes
/// configuration specified in args parameter.
/// @param command (parameter ignored)
/// @param args configuration to be processed. Expected format:
/// map containing Dhcp4 map that contains DHCPv4 server configuration.
/// May also contain Logging map that specifies logging configuration.
///
/// @return status of the command
isc::data::ConstElementPtr
commandSetConfigHandler(const std::string& command,
isc::data::ConstElementPtr args);
/// @brief Handler for processing 'leases-reclaim' command
///
......
// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2012-2017 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -189,8 +189,7 @@ protected:
parser = new StringParser(config_id, string_values_);
} else if (config_id.compare("pools") == 0) {
parser = new Pools4ListParser(config_id, pools_);
} else if (config_id.compare("relay") == 0) {
parser = new RelayInfoParser(config_id, relay_info_, Option::V4);
// relay has been converted to SimpleParser already.
// option-data has been converted to SimpleParser already.
} else if (config_id.compare("match-client-id") == 0) {
parser = new BooleanParser(config_id, boolean_values_);
......@@ -440,8 +439,7 @@ DhcpConfigParser* createGlobalDhcp4ConfigParser(const std::string& config_id,
parser = new D2ClientConfigParser(config_id);
} else if (config_id.compare("match-client-id") == 0) {
parser = new BooleanParser(config_id, globalContext()->boolean_values_);
} else if (config_id.compare("control-socket") == 0) {
parser = new ControlSocketParser(config_id);
// control-socket has been converted to SimpleParser already.
} else if (config_id.compare("expired-leases-processing") == 0) {
parser = new ExpirationConfigParser();
} else if (config_id.compare("client-classes") == 0) {
......@@ -497,6 +495,47 @@ void setGlobalParameters4() {
}
}
/// @brief Initialize the command channel based on the staging configuration
///
/// Only close the current channel, if the new channel configuration is
/// different. This avoids disconnecting a client and hence not sending them
/// a command result, unless they specifically alter the channel configuration.
/// In that case the user simply has to accept they'll be disconnected.
///
void configureCommandChannel() {
// Get new socket configuration.
ConstElementPtr sock_cfg =
CfgMgr::instance().getStagingCfg()->getControlSocketInfo();
// Get current socket configuration.
ConstElementPtr current_sock_cfg =
CfgMgr::instance().getCurrentCfg()->getControlSocketInfo();
// Determine if the socket configuration has changed. It has if
// both old and new configuration is specified but respective