Commit d22beff7 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰

[5208a] Doc written, exception messages are now better formed.

parent 8b561ef8
......@@ -219,11 +219,28 @@
client. Those scenarios are addressed by the Flexible Identifiers
hook application. It allows defining an expression, similar to
the one used in client classification,
e.g. substring(relay6[0].option[37],0,6). Each incoming packet is
evaluated against that expression and its value is then searched
in the reservations database.
e.g. substring(relay6[0].option[37],0,6). Each incoming packet is
evaluated against that expression and its value is then searched
in the reservations database.
</entry>
</row>
<row>
<entry>Host Commands</entry>
<entry>Support customers</entry>
<entry>Kea 1.2.0</entry>
<entry>Kea provides a way to store host reservations in a
database. In many larger deployments it is useful to be able to
manage that information while the server is running. This library
provides management commands for adding, querying and deleting
host reservations in a safe way without restarting the server.
In particular, it validates the parameters, so an attempt to
insert incorrect data, e.g. add a host with conflicting identifier
in the same subnet will be rejected. Those commands are
exposed via command channel (JSON over unix sockets) and Control
Agent (JSON over RESTful interface). Additional commands and
capabilities related to host reservations will be added in the
future.</entry>
</row>
</tbody>
</tgroup>
</table>
......@@ -547,7 +564,7 @@ link address: 3001::1, hop count: 1, identified by remote-id:
</section>
</section>
<section>
<section id="flex-id">
<title>flex_id: Flexible Identifiers for Host Reservations</title>
<para>
This section describes a hook application dedicated to generate
......@@ -560,25 +577,28 @@ link address: 3001::1, hop count: 1, identified by remote-id:
options that mentioned above, uses part of specific options or perhaps
even a combination of several options and fields to uniquely identify
a client. Those scenarios are addressed by the Flexible Identifiers
hook application.</para>
<para>The library allows defining an expression, using notation
initially used for client classification only. See <xref
linkend="classification-using-expressions" /> for detailed description
of the syntax available. One notable difference is that for client
classification the expression currently has to evaluate to either true
or false, while the flexible identifier expression is expected to
evaluate to a string that will be used as identifier. It is a valid case
for the expression to evaluate to empty string (e.g. in cases where a
client does not sent specific options). This expression is then
evaluated for each incoming packet. This evaluation generates an
identifier that is used to identify the client. In particular, there may
be host reservations that are tied to specific values of the flexible
identifier.</para>
<para>
The library can be loaded in similar way as other hook libraries. It
takes one mandatory parameter identifier-expression:
hook application.</para>
<para>Currently this library is only available to ISC customers with a
support contract.</para>
<para>The library allows defining an expression, using notation
initially used for client classification only. See <xref
linkend="classification-using-expressions" /> for detailed description
of the syntax available. One notable difference is that for client
classification the expression currently has to evaluate to either true
or false, while the flexible identifier expression is expected to
evaluate to a string that will be used as identifier. It is a valid case
for the expression to evaluate to empty string (e.g. in cases where a
client does not sent specific options). This expression is then
evaluated for each incoming packet. This evaluation generates an
identifier that is used to identify the client. In particular, there may
be host reservations that are tied to specific values of the flexible
identifier.</para>
<para>
The library can be loaded in similar way as other hook libraries. It
takes one mandatory parameter identifier-expression:
<screen>
"Dhcp6": { <userinput>
"hooks-libraries": [
......@@ -592,26 +612,26 @@ link address: 3001::1, hop count: 1, identified by remote-id:
] </userinput>
}
</screen>
</para>
<para>
The flexible identifier library supports both DHCPv4 and DHCPv6.
</para>
<para>
EXAMPLE: Let's consider a case of an IPv6 network that has an
independent interface for each of the connected customers. Customers
are able to plug in whatever device they want, so any type of
identifier (e.g. a client-id) is unreliable. Therefore the operator
may decide to use an option inserted by a relay agent to differentiate
between clients. In this particular deployment, the operator verified
that the interface-id is unique for each customer facing
interface. Therefore it is suitable for usage as reservation. However,
only the first 6 bytes of the interface-id are interesting, because
remaining bytes are either randomly changed or not unique between
devices. Therefore the customer decided to use first 6 bytes of the
interface-id option inserted by the relay agent. This could be
achieved by using the following configuration:
</para>
<para>
The flexible identifier library supports both DHCPv4 and DHCPv6.
</para>
<para>
EXAMPLE: Let's consider a case of an IPv6 network that has an
independent interface for each of the connected customers. Customers
are able to plug in whatever device they want, so any type of
identifier (e.g. a client-id) is unreliable. Therefore the operator
may decide to use an option inserted by a relay agent to differentiate
between clients. In this particular deployment, the operator verified
that the interface-id is unique for each customer facing
interface. Therefore it is suitable for usage as reservation. However,
only the first 6 bytes of the interface-id are interesting, because
remaining bytes are either randomly changed or not unique between
devices. Therefore the customer decided to use first 6 bytes of the
interface-id option inserted by the relay agent. This could be
achieved by using the following configuration:
<screen>
"Dhcp6": {
"subnet6": [{ ..., // subnet definition starts here
......@@ -631,27 +651,327 @@ link address: 3001::1, hop count: 1, identified by remote-id:
]
}
</screen>
</para>
<para>
NOTE: Care should be taken when adjusting the expression. If the
expression changes, then all the flex-id values may change, possibly
rendering all reservations based on flex-id unusable until they're
manually updated. Therefore it is strongly recommended to start with
the expression and a handful reservations, adjust the expression as
needed and only after it was confirmed the expression does exactly
what is expected out of it go forward with host reservations on any
broader scale.
</para>
<para>
flex-id values in host reservations can be specified in two
ways. First, they can be expressed as hex string, e.g. bar string
can be represented as 626174. Alternatively, it can be expressed
as quoted value (using double and single quotes), e.g. "'bar'".
The former is more convenient for printable characters, while hex
string values are more convenient for non-printable characters.
</para>
</para>
<para>
NOTE: Care should be taken when adjusting the expression. If the
expression changes, then all the flex-id values may change, possibly
rendering all reservations based on flex-id unusable until they're
manually updated. Therefore it is strongly recommended to start with
the expression and a handful reservations, adjust the expression as
needed and only after it was confirmed the expression does exactly
what is expected out of it go forward with host reservations on any
broader scale.
</para>
<para>
flex-id values in host reservations can be specified in two
ways. First, they can be expressed as hex string, e.g. bar string
can be represented as 626174. Alternatively, it can be expressed
as quoted value (using double and single quotes), e.g. "'bar'".
The former is more convenient for printable characters, while hex
string values are more convenient for non-printable characters.
</para>
</section>
<section id="host-cmds">
<title>host_cmds: Host Commands</title>
<para>
This section describes a hook application that offers a number of new
commands used to query and manipulate host reservations. Kea provides
a way to store host reservations in a database. In many larger
deployments it is useful to be able to manage that information while
the server is running. This library provides management commands for
adding, querying and deleting host reservations in a safe way without
restarting the server. In particular, it validates the parameters, so
an attempt to insert incorrect data e.g. add a host with conflicting
identifier in the same subnet will be rejected. Those commands are
exposed via command channel (JSON over unix sockets) and Control Agent
(JSON over RESTful interface). Additional commands and capabilities
related to host reservations will be added in the future.
</para>
<para>Currently this library is only available to ISC customers with a
support contract.</para>
<para>
Currently three commands are supported: reservation-add (which adds
new host reservation), reservation-get (which returns existing
reservation if specified criteria are matched) and reservation-del
(which attempts to delete a reservation matching specified
criteria). To use commands that change the reservation information
(currently these are reservation-add and reservation-del, but this
rule applies to other commands that may be implemented in the future),
hosts database must be specified (see hosts-database description in
<xref linkend="hosts-database-configuration4"/> and <xref
linkend="hosts-database-configuration6"/>) and it must not operate in
read-only mode. If the hosts-database is not specified or is running
in read-only mode, the host_cmds library will load, but any attempts
to use reservation-add or reservation-del will fail.
</para>
<para>
Additional host reservation commands are planned in the future. For
a description of envisaged commands, see
<ulink url="http://kea.isc.org/wiki/ControlAPIRequirements">Control API
Requirements </ulink> document.</para>
<para>
All commands are using JSON syntax. They can be issued either using
control channel (see <xref linkend="ctrl-channel"/>) or via Control
Agent (see <xref linkend="kea-ctrl-agent"/>).
</para>
<para>
The library can be loaded in similar way as other hook libraries. It
does not take any parameters. It supports both DHCPv4 and DHCPv6
servers.
<screen>
"Dhcp6": { <userinput>
"hooks-libraries": [
{
"library": "/path/libdhcp_host_cmds.so"
}
...
] </userinput>
}
</screen>
</para>
<section>
<title>reservation-add command</title>
<para>
<command>reservation-add</command> allows insertion of a new host. It
takes a set of arguments that vary depending on the nature of the host
reservation. Any parameters allowed in the configuration file that
pertain to host reservation are permitted here. For details regarding
IPv4 reservations, see <xref linkend="host-reservation-v4"/> and <xref
linkend="host-reservation-v6"/>. There is one notable addition. A
<command>subnet-id</command> must be specified. This parameter is
mandatory, because reservations specified in the configuration file
are always defined within a subnet, so the subnet they belong to is
clear. This is not the case with reservation-add, therefore the
subnet-id must be specified explicitly. An example command can be as
simple as:
<screen>{
"command": "reservation-add",
"arguments": {
<userinput>"reservation": {
"subnet-id": 1,
"hw-address": "1a:1b:1c:1d:1e:1f",
"ip-address": "192.0.2.202"
}</userinput>
}
}</screen> but can also take many more parameters, for example:
<screen>
{
"command": "reservation-add",
"arguments": {
<userinput>"reservation": {
{
"client-id": "01:0a:0b:0c:0d:0e:0f",
"ip-address": "192.0.2.205",
"next-server": "192.0.2.1",
"server-hostname": "hal9000",
"boot-file-name": "/dev/null",
"option-data": [
{
"name": "domain-name-servers",
"data": "10.1.1.202,10.1.1.203"
}
],
"client-classes": [ "special_snowflake", "office" ]
}
}</userinput>
}
}</screen>
Here is an example of complex IPv6 reservation:
<screen>
{
"command": "reservation-add",
"arguments": {
<userinput>"reservation": {
{
"duid": "01:02:03:04:05:06:07:08:09:0A",
"ip-addresses": [ "2001:db8:1:cafe::1" ],
"prefixes": [ "2001:db8:2:abcd::/64" ],
"hostname": "foo.example.com",
"option-data": [
{
"name": "vendor-opts",
"data": "4491"
},
{
"name": "tftp-servers",
"space": "vendor-4491",
"data": "3000:1::234"
}
]
}
}</userinput>
}
}</screen>
</para>
<para>
The command returns a status that indicates either a success (result
0) or a failure (result 1). Failed command always includes text
parameter that explains the cause of failure. Example results:
<screen>{ "result": 0, "text": "Host added." }</screen> Example failure:
<screen>{ "result": 1, "text": "Mandatory 'subnet-id' parameter missing." }</screen>
</para>
<para>
As <command>reservation-add</command> is expected to store the host,
hosts-database parameter must be specified in your configuration and
the database must not run in read-only mode. In the future versions
it will be possible to modify the reservations read from a
configuration file. Please contact ISC if you are interested in this
functionality.
</para>
</section>
<section>
<title>reservation-get command</title>
<para><command>reservation-get</command> can be used to query the host
database and retrieve existing reservations. There are two types of
parameters this command supports: (subnet-id, address) or (subnet-id,
identifier-type, identifier). The first type of query is used when the
address (either IPv4 or IPv6) is known, but the details of the
reservation aren't. One common use case of this type of query is to
find out whether a given address is reserved or not. The second query
uses identifiers. For maximum flexibility, Kea stores the host
identifying information as a pair of values: type and the actual
identifier. Currently supported identifiers are "hw-address", "duid",
"circuit-id", "client-id" and "flex-id", but additional types may be
added in the future. If any new identifier types are defined in the
future, reservation-get command will support them
automatically.</para>
<para>
An example command for getting a host reservation by (subnet-id,
address) pair looks as follows:
<screen>
{
"command": "reservation-get",
"arguments": {
"subnet-id": 1,
"ip-address": "192.0.2.202"
}
}</screen>
An example query by (subnet-id, identifier-type, identifier) looks as follows:
<screen>
{
"command": "reservation-get",
"arguments":
"subnet-id": 4,
"identifier-type": "hw-address",
"identifier": "01:02:03:04:05:06"
}
}</screen>
</para>
<para><command>reservation-get</command> typically returns result 0
when the query was conducted properly. In particular, 0 is returned
when the host was not found. If the query was successful a number
of host parameters will be returned. An example of a query that
did not find the host looks as follows:
<screen>{ "result": 0, "text": "Host not found." }</screen>
An example result returned when the host was found:
<screen>{
"arguments": {
"boot-file-name": "bootfile.efi",
"client-classes": [
],
"hostname": "somehost.example.org",
"hw-address": "01:02:03:04:05:06",
"ip-address": "192.0.2.100",
"next-server": "192.0.0.2",
"option-data": [
],
"server-hostname": "server-hostname.example.org"
},
"result": 0,
"text": "Host found."
}</screen>
An example result returned when the query was malformed:<screen>
{ "result": 1, "text": "No 'ip-address' provided and 'identifier-type'
is either missing or not a string." }</screen>
</para>
</section>
<section>
<title>reservation-del command</title>
<para><command>reservation-del</command> can be used to delete a
reservation from the host database. There are two types of parameters
this command supports: (subnet-id, address) or (subnet-id,
identifier-type, identifier). The first type of query is used when the
address (either IPv4 or IPv6) is known, but the details of the
reservation aren't. One common use case of this type of query is to
remove a reservation (e.g. you want a specific address to no longer be
reserved). The second query uses identifiers. For maximum flexibility,
Kea stores the host identifying information as a pair of values: type
and the actual identifier. Currently supported identifiers are
"hw-address", "duid", "circuit-id", "client-id" and "flex-id", but
additional types may be added in the future. If any new identifier
types are defined in the future, reservation-get command will support
them automatically.</para>
<para>
An example command for deleting a host reservation by (subnet-id,
address) pair looks as follows:
<screen>
{
"command": "reservation-del",
"arguments": {
"subnet-id": 1,
"ip-address": "192.0.2.202"
}
}</screen>
An example deletion by (subnet-id, identifier-type, identifier) looks as follows:
<screen>
{
"command": "reservation-del",
"arguments":
"subnet-id": 4,
"identifier-type": "hw-address",
"identifier": "01:02:03:04:05:06"
}
}</screen>
</para>
<para>
<command>reservation-del</command> returns result 0 when the host
deletion was successul or 1 if it was not. A descriptive text is
provided in case of error. Example results look as follows:
<screen>
{
"result": 1,
"text": "Host not deleted (not found)."
}</screen>
<screen>
{
"result": 0,
"text": "Host deleted."
}</screen>
<screen>
{
"result": 1,
"text": "Unable to delete a host because there is no hosts-database
configured."
}</screen>
</para>
</section>
</section>
</section>
......
......@@ -216,8 +216,8 @@ HostMgr::get6(const SubnetID& subnet_id,
void
HostMgr::add(const HostPtr& host) {
if (!alternate_source_) {
isc_throw(NoHostDataSourceManager, "unable to add new host because there is "
"no alternate host data source present");
isc_throw(NoHostDataSourceManager, "Unable to add new host because there is "
"no hosts-database configured.");
}
alternate_source_->add(host);
}
......@@ -225,8 +225,8 @@ HostMgr::add(const HostPtr& host) {
bool
HostMgr::del(const SubnetID& subnet_id, const asiolink::IOAddress& addr) {
if (!alternate_source_) {
isc_throw(NoHostDataSourceManager, "unable to delete a host because there is "
"no alternate host data source present");
isc_throw(NoHostDataSourceManager, "Unable to delete a host because there is "
"no hosts-database configured.");
}
return (alternate_source_->del(subnet_id, addr));
......@@ -236,8 +236,8 @@ bool
HostMgr::del4(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len) {
if (!alternate_source_) {
isc_throw(NoHostDataSourceManager, "unable to delete a host because there is "
"no alternate host data source present");
isc_throw(NoHostDataSourceManager, "Unable to delete a host because there is "
"no hosts-database configured.");
}
return (alternate_source_->del4(subnet_id, identifier_type,
......
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