Kea: Kea Stat Commands Hooks Library

| Kea 3.2.0-git

Kea Stat Commands Hooks Library

# Introduction

Welcome to Kea Stat Commands Hooks Library. This documentation is addressed to developers who are interested in the internal operation of the Stat Commands library. This file provides information needed to understand and perhaps extend this library.

This documentation is stand-alone: you should have read and understood the Kea Developer's Guide and in particular its section about hooks.

# Stat Commands Overview

Stat Commands (or stat_cmds) is a Hook library that can be loaded by either kea-dhcp4 and kea-dhcp6 servers to extend them with additional statistics mechanisms.

The initial purpose of this library is provide supplemental commands for obtaining accurate lease statistics in deployments that share lease storage between multiple Kea DHCP servers. It is likely that additional statistics related commands will be added to this library in future releases as use cases for them arise.

The library is structured around command handlers. When the library is loaded it registers handlers for new commands. When a command is issued, the code receives a JSON command with parameters. The command is routed the appropriate handler, its parameters are parsed and command executed accordingly. Lastly, a response is constructed and shipped back to the client.

This lease statistics commands interact with both the isc::dhcp::StatsMgr and the isc::dhcp::LeaseMgr instance. At the time of writing this text (May, 2018), Kea supports four types of lease managers: memfile, MySQL or PostgreSQL. The lease statistics commands provided by this library provide a unified interface supported by all four of these backends.

As with other hooks, this one keeps its code in a separate namespace which corresponds to the file name of the library: isc::stat_cmds.

For background on the design and design choices please refer to: Shared Lease Stats Design

# Stat Commands Code Overview

Library operation starts with Kea calling the load() function (file stat_cmds_callouts.cc). This function registers the command callout functions for each of the libraries commands. For a list, see isc::stat_cmds::StatCmds class documentation. This class uses the Pimpl design pattern, and thus the actual implementation is hidden in isc::stat_cmds::LeaseStatCmdsImpl.

Unlike similar libraries, the Pimpl class is differentiated from the the StatCmds class by the prefix "Lease" and it is instantiated in the outer handler (e.g. isc::stat_cmds::StatCmds::statLease4GetHandler) rather than the StatCmds constructor. This was done in the event that commands, unrelated to lease statistics, are added to this library and that would be better served by Pimpl derivations specific to them.

## Lease Stat Commands Code Overview

There are two shared lease statistic commands, "stat-lease4-get" and "stat-lease6-get". Both of these support the same input parameters and have their own command handlers:

- isc::stat_cmds::LeaseStatCmdsImpl::statLease4GetHandler (stat-lease4-get)
- isc::stat_cmds::LeaseStatCmdsImpl::statLease6GetHandler (stat-lease6-get)

Briefly, the commands are intended to fetch the lease statistics per subnet for the range of subnets described by the input parameters. JSON text structure of the commands is as follows:

DHCPv4 command:

{
"command": "stat-lease4-get",
"arguments": {
"subnet-id": x
"subnet-range": {
"first-subnet-id": x,
"last-subnet-id": y
}
}
}
where subnet-id and subnet-range are optional and mutually exclusive

DHCPv6 command:

{
"command": "stat-lease6-get",
"arguments": {
"subnet-id": x
"subnet-range": {
"first-subnet-id": x,
"last-subnet-id": y
}
}
}
where subnet-id and subnet-range are optional and mutually exclusive

Command handling for both commands is symmetrical consists of the following steps:

1. The input parameters (if any) are parsed. Invalid values or combinations if detected result in generating a CONTROL_RESULT_ERROR response to the client. (See isc::stat_cmds::LeaseStatCmdsImpl::getParameters and isc::stat_cmds::LeaseStatCmdsImpl::Parameters)
2. The parameters are used to identify the range of configured subnets to include in the response. This is done by querying subnet configuration housed by isc::dhcp::CfgMgr. If the range contains no known subnets then a CONTROL_RESULT_EMPTY response is sent back to the client.
3. The initial result-set response is constructed. Essentially this is an isc::data::Element tree, which converted to JSON would appear as follows:

"result-set": {
"timestamp": "2018-03-22 09:43:30.815371",
"columns": ["<label-1>, <label-2>, ... ],
"rows": []
}

1. The actual lease statistics are then retrieved from isc::dhcp::LeaseMgr instance by invoking of the three functions based on the input parameters:

DHCPv4 functions:

- isc::dhcp::LeaseMgr::startLeaseStatsQuery4
- isc::dhcp::LeaseMgr::startSubnetLeaseStatsQuery4
- isc::dhcp::LeaseMgr::startSubnetRangeLeaseStatsQuery4

DHCPv6 functions:

- isc::dhcp::LeaseMgr::startLeaseStatsQuery6
- isc::dhcp::LeaseMgr::startSubnetLeaseStatsQuery6
- isc::dhcp::LeaseMgr::startSubnetRangeLeaseStatsQuery6

1. Iterate over the range of qualifying subnets adding a row of statistics for each subnet to the result-set. Each row combines the subnet total(s) from isc::dhcp::StatsMgr with the type and state counts from the lease query results. For subnets with no query data (i.e. no leases), their rows have non-zero values for totals only.
2. Finally, a CONTROL_RESULT_SUCCESS response is generated containing the populated result-set.

A DHCPv4 response might look like this:

{
"result-set\": {
"columns\": [
"subnet-id", "total-addresses",
"cumulative-assigned-addresses",
"assigned-addresses", "declined-addresses"
],
"rows\": [
[ 30, 256, 300, 100, 2 ],
[ 40, 16, 5, 0, 0 ],
[ 50, 256, 100, 35, 0 ]
],
timestamp\": \"2018-05-04 15:03:37.000000\" }
}

and DHCPv6 response might look like this:

{
"result-set": {
"columns": [
"subnet-id", "total-nas", "cumulative-assigned-nas",
"assigned-nas", "declined-addresses", "total-pds",
"cumulative-assigned-pds", "assigned-pds"
],
"rows": [
[ 30, 16, 20, 6, 0, 65536, 1000, 400 ],
[ 40, 16777216, 1100000, 989837, 0, 0, 0, 0 ]
],
"timestamp": "2018-05-04 15:03:37.000000" }
}

# Multi-Threading Compatibility

The Stat Commands Hook library is compatible with multi-threading. All commands are executed inside a critical section, i.e. with threads stopped. It makes sense to not have lease state changes when retrieving lease counts.