Version 12 (modified by tomek, 3 years ago) (diff)


Control API Requirements

Kea provides a control channel that allows external entity send administrative commands to the server. This document explains rationale that led to certain decisions and enumerates desired capabilities.

WARNING: This document is a work in progress. Expect significant changes. Once this document is more mature, it will be discussed on kea-dev list.

At the time of writing this document (post Kea 1.0, before Kea 1.1 release) several commands listed here are already supported. They're listed here in an effort to provide a complete overview of the desired capability of the Control API.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 (

They can also be used to roughly estimate priority for a given feature: MUST is P1 priority (i.e. it's the most important feature), SHOULD being P2 (less important than MUST) and MAY being P3 (this is really an optional thing. Assuming infinite time we would implement all MAYs, but the reality makes it somewhat unlikely).

Administrative actions

  • A.1. Kea MUST support shutdown command (already supported since 0.9.2).

Supporting large command parameters and and responses is required for a number of scenarios: getting all leases from a subnet, getting statistics for multiple subnets when # of subnets is large etc. (This was never tested, it may work for commands bigger than 1500, but we do have a static buffer somewhere. Once the command parameters are larger than this buffer, we'll truncate the command first and then will reject it as malformed. We need to improve the code).

  • A.2. Control channel MUST support accepting commands and sending responses bigger than 1500 bytes.

Kea 1.0 already supports reload-config. It remembers the path to the config file used during start and can reload it if needed. This is sufficient in simple cases of a local config file that was edited. However, there are other scenarios that it does not address. In particular, there is no way to specify that the file location has changed. There are customers who built IPAM systems around ISC DHCP and they generate temporary config files, then restart isc dhcpd. Once dhcpd is restarted, that temporary file is removed. It seems logical to presume that similar model will be used with Kea.

  • A.3. Kea MUST support reload-config (Kea reloads its current configuration file from disk, already supported in 1.0).

This functionality is already supported in Kea 1.0, albeit not in its fully featured form. Current code simply allows to reload the same file, without providing an ability to change its location. Changing location is especially important for cases when Kea is integrated into IPAM or similar system: The system around Kea may generate a temporary config file, let Kea reload it and then the file is deleted.

  • A.4. Kea MUST support get-config (Kea sends back its current configuration in the response).

With the advance of Control API the ability to modify its configuration during run-time a new problem will emerge: how to ensure persistence of the configuration changes. It was suggested that perhaps Kea could try to overwrite its configuration file. This approach has several issues. First, we would have to ensure that whatever rewrite Kea does would not overwrite any existing information, including comments. Current Kea parser simply ignores comments. Kea code would have to remember it and then insert them back into the written file. This is more complex than it sounds as there are many commenting styles. People write their comments immediately before the clause, they may put sections in their config, add some comments for specific entries etc. Understanding which comment applies to which JSON entry is a difficult task. Have we chose to retain comments and write whole configuration, there would be cases of oddly misplaced comments.

Second argument against the approach of Kea rewriting its own configuration file is limiting use cases. There are deployments where the config file is stored on read-only filesystem (e.g. OpenWRT or systems where only /tmp and /var is writeable). It would also make difficult for IPAM-like systems built around Kea. We know of several systems developed around ISC DHCP. One of them keeps the configuration internally in XML. When configuration changes, this XML is processed to generate isc dhcpd's config written to a temporary file, the server is restarted and the temporary file removed. Rewriting this long deleted file would be meaningless.

Last, but not least the argument is about desired persistence of the changes. Users could experiment with their configuration and not necessarily keep the changes if they don't like the outcome. Therefore the "rewrite your own config" approach would require adding "bool persist" parameters to all configuration modification calls and then keep them internall in configuration manager. Furthermore, the configuration could possibly be internally inconsistent, e.g. sane with non-persistent elements, but insane without them. This would be an evergrowing complexity without good solutions in sight.

Therefore the proposal is to provide get-config method that would return current running configuration. It is up to the caller to do something with the response, e.g. store it externally, review it or write it to configuration file, possibly overwrite existing config if the user so desires. Also, it gives the best flexibility in the sense of discarding changes that are deemed not desired. The user would simply not call get-config, restart Kea and it would revert to its previous configuration.

  • A.5. Kea MUST support set-config (sysadmin specifies new configuration as parameter).

Currently we assume that Kea loads its configuration file from local file system. This will certainly remain the default behavior, but with simple modification we could add optional, additional source of configuration. The JSON configuration would be sent over command channel. One specific envisaged use case for this is the ability to boot many DHCP servers in data centers or large networks. There would be a VM image with just bare bones configuration covering logging destination and pointers to the database. Then once the VM is booted the actual configuration is deployed using set-config command.

Another envisaged use case for this call is the ability to push configuration. This could be useful in several scenarios. In large networks new configuration could be pushed to multiple servers at the same time. Another scenario would be to overwrite existing configuration without needing to restart the server.

Configuration management

Identifier types

There are several calls proposed below that refer to identifier-type and identifier, especially in leases and host reservations contexts. In a very simplified approach, the DHCPv4 client can be identified by its hardware/MAC address and DHCPv6 client can be identified by its client-id (which is a DUID). However, modern networks are often more complicated and so are the ways clients are identified. DHCPv4 clients may send client-id options, ISPs may not know the MAC addresses, but know the ports over which the clients will be connecting etc. The number of such identifiers that are used to identify a client are growing over time. Therefore Kea is currently being refactored to allow easy addition of extra identifiers in the future.

Kea 1.0 allowed the following identifier types: hardware/MAC addresses for DHCPv4 and DUID for DHCPv6. Kea 1.1 is expected to allow the following identifier types: hardware/MAC addresses, client-id (client-id option in DHCPv4), DUID (client-id option formatted according to RFC4361 in DHCPv4, client-id option in DHCPv6), remote-id (remote-id suboption inserted in option 82 by a DHCPv4 relay agent or remote-id option (37) inserted by a DHCPv6 relay agent) or circuit-id (circuit-id suboption inserted in option 82 by a DHCPv4 relay agent).

Additional identifier types are likely to be implemented in the future.

Leases management

After DHCP server assigns an address (or address or prefix in case of DHCPv6) it records the fact of the address being assigned to given client as a lease. This is the most important run-time piece of information for every DHCP server. The lease information tends to be updated frequently as most communications with any client causes lease state to change. Therefore this is the most dynamic data in the DHCP world.

The API must allow management of the leases. It should allow full CRUD methodology (Create, Retrieve, Update, Delete). Those changes MUST be applicable during run-time and MUST NOT require Kea to be restarted.

  • L.1. Kea MUST support add-lease4 command.
  • L.2. Kea MUST support add-lease6 command.

Kea is able to store leases in memfile (which is in-memory database that writes changes to a CSV file), MySQL, PostgreSQL. There's work in progress to also store leases in Cassandra nosql database. While it is possible to insert leases into the databases in some backends (MySQL and Postgres), this direct insertion approach has several flaws. In particular, it does not offer any sanity checks. The very basic checks (that the address is unique) are enforced by the database schema, but the more subtle are not. Three specific examples of such checks would be adding a lease for host A when the address is reserved for host B, adding a lease with invalid subnet ID and adding a lease for subnet X with an address Y where address Y does not belong to the subnet X. Another reason why using an API is better, because it behaves in the same way for every backend, so any solutions built around Kea could be migrated to a different backend if such a need arises.

  • L.3. Kea MUST support get-lease4 command that takes IPv4 address as a parameter.
  • L.4. Kea MUST support get-lease4 command that takes (identifier-type, identifier, subnet-id) as parameters.
  • L.5. Kea MUST support get-lease6 command that takes IPv6 address as a parameter.
  • L.6. Kea MUST support get-lease6 command that takes (identifier-type, identifier, subnet-id) as parameters.

identifier-type is hwaddr (hardware/MAC address of the client), client-id (content of the client-identifier option in DHCPv4), DUID (content of the client-identifier option in DHCPv6), remote-id (content of the remote-id sub-option inserted in option 82 by a relay agent), circuit-id (content of the circuit-id sub-option inserted in option 82 by a relay agent). More identifier types may be defined in the future.

Those two calls will be used to retrieve IPv4 or IPv6 lease information. For each call one of available two sets of parameters may be specified: either IP address or a tuple of (identifier-type, identifier, subnet-id). The first call type is pretty obvious. We know an IP address and want to check whether there's a lease for it. The second call type is somewhat more complex. Kea 1.0 supports MAC addresses in IPv4 leases and DUIDs in IPv6 leases. Kea 1.1 will support several identifier types, in particular we're working on adding support for client-id, remote-id and circuit-id options. It is envisaged that more identifier types may be added in the future. Therefore we chose the identifier-type + identifier approach, rather than provide specific calls for get-lease-by-hwaddr, get-lease-by-client-id etc. as the number of such calls would grow over time.

Q: Do we want to have a single query (e.g. get-lease4) with multiple parameter sets or do we want separate queries (get-lease4-by-ip-addr, get-lease4-by-identifier).

Q: Do we want to support multi-tenancy (i.e. having multiple hot spots, each with the same private IP address space)? If that is so, then (IP address only) parameter set must be extended with (IP address, subnet-id). The benefit would be to allow new deployment scenarios, but the downside would be to make usage more complicated (i.e. caller may simply don't know the subnet-id).

  • L.7. Kea MUST support update-lease4 command.
  • L.8. Kea MUST support update-lease6 command.

Those two calls allow updating all parameters of v4 or v6 lease. It is assumed that all parameters can change, except the IP address. Code processing this call MUST ensure that the data is consistent, e.g. verify that subnet-id are sane, that IP address range matches the subnet it belongs to, that hostname has valid format etc. For the call to succeed the lease for specified IP address must exist.

  • L.9. Kea MUST support delete-lease4 command.
  • L.10. Kea MUST support delete-lease6 command.

Those two call attempt to remove IPv4 and IPv6 leases. There will be only one mandatory parameter specified: IP address of the lease to be removed. There will be one optional parameter called mode. It will accept one of two values: remove (which simply remove the lease from the database), release (treat it as if Release packet was received. In particular, this would trigger additional steps, like cleaning up DNS entries if necessary). The default would be 'remove'.

Note: There are currently no plans to implement calls that retrieve multiple leases, e.g. all leases in a subnet. The reason why such an API was not designed is the stress on the API code. With subnets having potentially millions of leases, a call requesting all of them formatted as JSON structures would be a significant burden (potentially exploitable as a denial of service attack) to the server. We may revisit this if people come up with actual use cases for this.

Reservations management

Kea allows host reservations. HR is a mechanism that allows reserving a specific IPv4 address, IPv6 address, IPv6 prefix, specific hostname or set of options is reserved to a given client. Depending on the deployment there may be no host reservations at all (all leases assigned dynamically), there may be some reservations (mixed model, where most clients are assigned dynamically, but there is a subset of clients that have reserved parameters) up to fully static model (dynamic allocation is effectively disabled, all clients are known and have static reservations).

Currently (Kea 1.0) Kea allows storing host reservations in the configuration file and there's work in progress to allow storing HR in MySQL and PostgreSQL. Ultimately, the plan is to store this information in backends (for most backends except memfile). When the number of reservations is small and they are not updated frequently, it makes sense to store them in configuration file. However, with the number of HR getting large or being updated more frequently, it is increasingly compelling to store them in the database. The following calls provide ability to manipulate the HR information.

Note: for backends that provide ability to store HR (currently MySQL only, but this capability for PostgreSQL is planned for 1.1. There are also discussions about developing such capability for Cassandra in the upcoming releases, but no firm decisions have been made yet).

  • R.1. Kea MUST support add-reservation command that adds a reservation.
  • R.2. The add-reservation command MUST allow reserving an IPv4 address.
  • R.3. The add-reservation command MUST allow reserving at least one IPv6 address.
  • R.4. The add-reservation command MUST allow reserving at least one IPv6 prefix.
  • R.5. The add-reservation command MUST allow specifying a hostname.
  • R.6. The add-reservation command MUST allow specifying IPv4 options that will be sent for the host.
  • R.7. The add-reservation command MUST allow specifying IPv6 options that will be sent for that host.
  • R.8. The add-reservation command MUST allow reservations by hardware (MAC) address.
  • R.9. The add-reservation command MUST allow reservations by DUID.
  • R.10. The add-reservation command SHOULD allow reservations by client-id.
  • R.11. The add-reservation command MAY allow reservations by circuit-id.
  • R.12. The add-reservation command MAY allow reservations by remote-id.

This call will add a new reservation for a host. It will be possible to specify IPv4 address, IPv6 addresses (typically one, but eventually it will be possible to specify more), IPv6 prefixes (typically one, but eventually it will be possible to specify more), hostname, per host specific options, subnet-id (separate for IPv4 and IPv6 subnets) and an identifier. The identifier will be specified as (identifier-type, identifier) pair. The details are TBD, but it seems very likely that the initial implementation will allow specifying the following identifier types: hwaddr (hardware/MAC address), client-id (client-identifier option in DHCPv4), DUID (client-id option in DHCPv6), remote-id (remote-id sub-option in option 82), circuit-id (circuit-id sub-option in option 82). Additional identifier types are likely to be defined in the future.

  • R.13. Kea MUST support get-reservation by IPv4 address.
  • R.14. Kea MUST support get-reservation by IPv6 address.
  • R.15. Kea MUST support get-reservation by (identifier-type, identifier, subnet-id).
  • R.16. Kea MUST support update-reservation call that modifies existing reservation.
  • R.17. Kea MUST support delete-reservation by IPv4 address.
  • R.18. Kea MUST support delete-reservation by IPv6 address.

Subnets management

  1. MUST support get-subnet4-count
  2. MUST support get-subnet6-count
  3. MUST support get-subnet4 (by subnet-id), (by index)
  4. MUST support get-subnet6 (by subnet-id), (by index)
  5. MUST support update-subnet4
  6. MUST support update-subnet6
  7. MUST support add-subnet4
  8. MUST support add-subnet6
  9. MUST support delete-subnet4
  10. MUST support delete-subnet6

TODO: Hmmm, how do we want to refer to specific pools. We currently don't have any indexes.

  1. MUST support get-pools4-count (returns a number of subnets in a given v4 subnet)
  2. MUST support get-pools6-count (returns a number of subnets in a given v4 subnet)
  3. MUST support add-pool4
  4. MUST support add-pool6
  5. MUST support get-pool4
  6. MUST support get-pool6
  7. MUST support delete-pool4
  8. MUST support delete-pool6

Options management

Need API calls to manage assigned global and per subnet options.

Classification management

Do we need API calls to manage client classification?

Interfaces management

We will most likely need an API to manage interfaces (which interfaces to listen on and which addresses to bind).

Run-time operations

  1. Kea MUST support (TODO: list all statistics related commands here).

Open questions

Q: What to do with the leases when removing pools/subnets? Available options:

  1. Keep them in the DB (useful when removal is temporary)
  2. Keep them, but don't allow the server to renew (that would keep the subnet/leases, but they would expire naturally)
  3. delete them instantly
  4. initiate reconfigure process and delete the leases/subnet afterwards