From: Tomek Mrugalski Date: Mon, 24 Apr 2017 12:19:19 +0000 (+0200) Subject: [5208a] Doc written, exception messages are now better formed. X-Git-Tag: trac5212_base~10^2~5 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=d22beff70de5609d57e442679986c6236e7b5e1e;p=thirdparty%2Fkea.git [5208a] Doc written, exception messages are now better formed. --- diff --git a/doc/guide/hooks.xml b/doc/guide/hooks.xml index 038aa8b09c..e63932db42 100644 --- a/doc/guide/hooks.xml +++ b/doc/guide/hooks.xml @@ -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. + + Host Commands + Support customers + Kea 1.2.0 + 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. + @@ -547,7 +564,7 @@ link address: 3001::1, hop count: 1, identified by remote-id: -
+
flex_id: Flexible Identifiers for Host Reservations 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. - - The library allows defining an expression, using notation - initially used for client classification only. See 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. - - - The library can be loaded in similar way as other hook libraries. It - takes one mandatory parameter identifier-expression: + hook application. + + Currently this library is only available to ISC customers with a + support contract. + + The library allows defining an expression, using notation + initially used for client classification only. See 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. + + + The library can be loaded in similar way as other hook libraries. It + takes one mandatory parameter identifier-expression: "Dhcp6": { "hooks-libraries": [ @@ -592,26 +612,26 @@ link address: 3001::1, hop count: 1, identified by remote-id: ] } - - - - The flexible identifier library supports both DHCPv4 and DHCPv6. - - - - 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: + + + + The flexible identifier library supports both DHCPv4 and DHCPv6. + + + + 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: "Dhcp6": { "subnet6": [{ ..., // subnet definition starts here @@ -631,27 +651,327 @@ link address: 3001::1, hop count: 1, identified by remote-id: ] } - - - - 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. - - - - 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. - + + + + 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. + + + + 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. + +
+ +
+ host_cmds: Host Commands + + 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. + + + Currently this library is only available to ISC customers with a + support contract. + + + 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 + and ) 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. + + + + Additional host reservation commands are planned in the future. For + a description of envisaged commands, see +Control API +Requirements document. + + + All commands are using JSON syntax. They can be issued either using + control channel (see ) or via Control + Agent (see ). + + + + 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. + +"Dhcp6": { + "hooks-libraries": [ + { + "library": "/path/libdhcp_host_cmds.so" + } + ... + ] +} + + + +
+ reservation-add command + + reservation-add 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 and . There is one notable addition. A + subnet-id 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: +{ + "command": "reservation-add", + "arguments": { + "reservation": { + "subnet-id": 1, + "hw-address": "1a:1b:1c:1d:1e:1f", + "ip-address": "192.0.2.202" + } + } +} but can also take many more parameters, for example: + + +{ + "command": "reservation-add", + "arguments": { + "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" ] + } + } + } +} + +Here is an example of complex IPv6 reservation: + +{ + "command": "reservation-add", + "arguments": { + "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" + } + ] + } + } + } +} + + + + 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: + { "result": 0, "text": "Host added." } Example failure: + { "result": 1, "text": "Mandatory 'subnet-id' parameter missing." } + + + + As reservation-add 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. + +
+ +
+ reservation-get command + reservation-get 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. + + + An example command for getting a host reservation by (subnet-id, + address) pair looks as follows: + +{ + "command": "reservation-get", + "arguments": { + "subnet-id": 1, + "ip-address": "192.0.2.202" + } +} + +An example query by (subnet-id, identifier-type, identifier) looks as follows: + +{ + "command": "reservation-get", + "arguments": + "subnet-id": 4, + "identifier-type": "hw-address", + "identifier": "01:02:03:04:05:06" + } +} + + + reservation-get 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: +{ "result": 0, "text": "Host not found." } + +An example result returned when the host was found: +{ + "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." +} + +An example result returned when the query was malformed: +{ "result": 1, "text": "No 'ip-address' provided and 'identifier-type' + is either missing or not a string." } + + +
+ +
+ reservation-del command + reservation-del 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. + + + An example command for deleting a host reservation by (subnet-id, + address) pair looks as follows: + +{ + "command": "reservation-del", + "arguments": { + "subnet-id": 1, + "ip-address": "192.0.2.202" + } +} + +An example deletion by (subnet-id, identifier-type, identifier) looks as follows: + +{ + "command": "reservation-del", + "arguments": + "subnet-id": 4, + "identifier-type": "hw-address", + "identifier": "01:02:03:04:05:06" + } +} + + + reservation-del 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: + +{ + "result": 1, + "text": "Host not deleted (not found)." +} + + +{ + "result": 0, + "text": "Host deleted." +} + + +{ + "result": 1, + "text": "Unable to delete a host because there is no hosts-database + configured." +} + +
diff --git a/src/lib/dhcpsrv/host_mgr.cc b/src/lib/dhcpsrv/host_mgr.cc index d0376a85de..9275330911 100644 --- a/src/lib/dhcpsrv/host_mgr.cc +++ b/src/lib/dhcpsrv/host_mgr.cc @@ -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,