Basic LeaseQuery Design

Scope

This is a high level design for basic LeaseQuery as described in RC4388 (DHCPv4) and RFC5007 (DHCPv6). Please note that this design in many places generalizes behavior that is common to both protocols. Terms are used rather loosely as equivalent between the two. Where differences are relevant they have addressed as such. It does not address Bulk LeaseQuery or Active LeaseQuery.

The first two categories do not pose a problem as the values are either on
the lease itself or can be readily calculated based on the parameters
available through the lease's subnet.

Relay-related information however, is neither stored nor derivable. The only
way forward here is to store this information per lease.

As for returning other options, providing this would be the most robust
implementation we could offer but would require either: storing additional
options on each lease or calculating them again as part of the lease query
response construction. The latter approach would offer a deal of flexibility
with the least impact to normal DHCPx processing, though we might need to
store some additional information such as the vendor id and client class list.

Design

LeaseQuery will be a subscription feature. The proposed design will make modifications to Kea core as as well the creation of a new hook library, LeaseQuery.

Kea Core Modifications

The modifications to Kea core provide the storage of the additional data required, primarily relay-related options), to lease stores.

Data Storage Content and Format

General consensus during informal discussions has been that the most likely place to store relay information (along with any other data that might be needed by LeaseQuery) would be in the lease's user-context. This would not require any modifications to any of lease back ends.

For DHCPv4 we need to store the relay-agent-info (option 82). Per the RFC 4388, the relay-agent-info should be taken from the most recent DHCPREQUEST that provided it. Recall that DHCPREQUESTs sent as renews or rebinds will not have it.

The proposed format would add an "ISC" element to user-context is as follows:

For DHCPv6, we actually need to store the all of the relay message up to but excluding the actual client DHCP6 message. In other words, we need to store each relay layer (i.e. hop) between the server and the client. How often more than one hop would actually be involved is another matter. Essentially we would loop over Pkt6::relays[] adding an entry for each. The proposed format would add an "ISC" element to user-context is as follows:

Note, that in addition to supporting LeaseQuery, storing relay information for v6 is necessary to support DHCPv6 Reconfigure.

Data Storage Mechanics

Rather than create a dependency between LeaseQuery and DHCPv6 Reconfigure, or implementing some other mechanism by which the steps to store relay information is not duplicated between them, it is proposed that we implement the ability to store the relay information as feature within Kea core, that is enabled if a the following
new Kea core parameter is enabled:

"store-extended-info" : true/false

It would globally default to false and be scoped down to at least the subnet, if not pool level. This will make it easy to control when the information is added to the lease without introducing additional lease commits or hook points. Users would be able to fine-tune the storage and enable the specific to the network-scopes that suit them.

For DHCPv4 we would add a function, AllocEngine::updateLease4ExtendedInfo(). When storage is enabled, it would gather the necessary information and update the lease's user-context with it. The function would be invoked from AllocEngine::createLease4() and AllocEngine::updateLease4Information(). This ensures the data is updated on the lease before the lease is committed to lease storage.

We would take a similarly tact for v6 by adding a function, AllocEngine::updateLease6ExtendedInfo() which would update the lease's user-context, when enabled. This would be invoked from AllocEngine::createLease6() and AllocEngine::reuseExpiredLease().

Enabling LeaseQuery (and Dhcpv6 Reconfigure)

The initial implementation will consider either feature globally enabled if their hook library component is enabled.

Both would globally default to false and be scoped down to the subnet (possibly pool) level. In addition to permitting either feature for that scope, the presence of either would also enable storing the extended data. If we find users want finer grained control we can always add these parameters.

LeaseQuery Hook Library

Handling of inbound LeaseQuery packets, would be provided by a new hook library, LeaseQuery. The process flow is fairly straight forward and breaks down as follows:

Kea server receives a LeaseQuery packet as it would any other DHCPx packet

LeaseQuery::buffer<4/6>_receive() callout will unpack the query and pass it into a LeaseQuery handler which will:

Vet the LeaseQuery query against Access Control (discussed later on). Unauthorized requests will logged and dropped.

Search for matching leases

Construct the appropriate LeaseQueryResponse - When active leases are found this includes: extracting the needed information from the lease's user-context and based on the client's requested option list. Should we decide to support additional options, we would need to calculate them at this point.

Send the LeaseQuery response

LeaseQuery::buffer<4/6>_receive() callout will set status to DROP, causing the
server to go on to the next DHCPX client packet.

Note that the hook library will not have access to many of the server's internal functions, so some degree of code replication may be necessary. Consider it the cost of isolating the functionality within a hook.

Access Control

Access control will implemented as a list of known IP addresses.

This mechanism for access control is straight forward. We will only accept LeaseQuery queries from a list of IP addresses. These would be part of the LeaseQuery hook library parameters:

Searching for Matching Leases: Use of LeaseMgr

LeaseMgr already provides the requisite queries. For DHCPv4 the lease matching process is a straight forward use of the appropriate LeaseMgr functions. There is a case for DHCPv6 though, where additional logic will be needed to narrow the parameters that LeaseMgr queries can be used. These are described in RFC 5007, Section 4.1.2.1:

QUERY_BY_ADDRESS (1) - The query-options MUST contain an OPTION_IAADDR option [2]. The link-address field, if not 0::0, specifies an address for the link on which the client is located if the address in the OPTION_IAADDR option is of insufficient scope. Only the information for the client that has a lease for the specified address or was delegated a prefix that contains the specified address is returned (if available).

If the OPTION_IAADDR address is not explicitly leased, but falls within a pool of prefixes, the server will need infer what the delegated prefix would be and look for
an active lease for that prefix.

Providing Additional Options

As mentioned earlier, LeaseQuery queries provide a list of requested options which servers should provide, when possible. There is also mention of a "sensitive options list" which servers could be configured with to not supply values deemed sensitive. Storing some or all of the options for each lease could have enormous impact on Lease IO. It is suggested here, that rather than store them, we recalculate the desired options for each the lease being returned in the LeaseQuery response. If we include vendor information and client-classes along with the relay data stored for each lease, we should be able to provide the bulk of the options that might be requested. A "sensitive options list" would be supplied as a Hook parameter, probably as a list of option codes or option names.

Whether we implement this initially, or ever is another matter. It is suggested that we wait until we have user feedback as to whether the additional options are important.

Looking Forward

While the scope of this design does not include Bulk LeaseQuery, there is at least one point worth discussing. Bulk LeaseQuery, for both DHCPv4 and DHCPv6, provides for the ability to search for leases by relay attributes such as relay-id, remote-id, link address. In other words, by values within the same information that this design proposes be stored as part of a lease's user-context. The proposed format in this design is store these values opaquely rather than as individual sub-option values. While more efficient for lease storage IO during normal DHCP operations, it may not be the best arrangement for Bulk LeaseQuery performance and may well require walking lists of leases, as opposed to querying against indexes of explicit values.

We might find it necessary to split out the information into individual columns or for even tables/maps, in order to gain performance.