// Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
/**
@page dhcpv6Hooks The Hooks API for the DHCPv6 Server
@section dhcpv6HooksIntroduction Introduction
Kea features an API (the "Hooks" API) that allows user-written code to
be integrated into Kea and called at specific points in its processing.
An overview of the API and a tutorial for writing such code can be found in
the @ref hooksdgDevelopersGuide. Information for Kea maintainers can be
found in the @ref hooksComponentDeveloperGuide.
This manual is more specialized and is aimed at developers of hook
code for the DHCPv6 server. It describes each hook point, what the callouts
attached to the hook are able to do, and the arguments passed to the
callouts. Each entry in this manual has the following information:
- Name of the hook point.
- Arguments for the callout. As well as the argument name and data type, the
information includes the direction, which can be one of:
- @b in - the server passes values to the callout but ignored any data
returned.
- @b out - the callout is expected to set this value.
- in/out - the server passes a value to the callout and uses whatever
value the callout sends back. Note that the callout may choose not to
do any modification, in which case the server will use whatever value
it sent to the callout.
- Description of the hook. This explains where in the processing the hook
is located, the possible actions a callout attached to this hook could take,
and a description of the data passed to the callouts.
- Next step status: the action taken by the server when a callout chooses to set
status to specified value. Actions not listed explicitly are not supported.
If a callout sets status to unsupported value, this specific value will be
ignored and treated as if the status was CONTINUE.
@section dhcpv6HooksHookPoints Hooks in the DHCPv6 Server
The following list is ordered by appearance of specific hook points during
packet processing. Hook points that are not specific to packet processing
(e.g. lease expiration) will be added to the end of this list.
@subsection dhcpv6HooksBuffer6Receive buffer6_receive
- @b Arguments:
- name: @b query6, type: isc::dhcp::Pkt6Ptr, direction: in/out
- @b Description: This callout is executed when an incoming DHCPv6
packet is received and the data stored in a buffer. The sole argument
"query6" contains a pointer to an @c isc::dhcp::Pkt6 object that contains
the received information stored in the data_ field. Basic information
like protocol, source/destination addresses and ports are set, but
the contents of the buffer have not yet been parsed. That means that
the @c options_ field (that will eventually contain a list of objects
representing the received options) is empty, so none of the methods
that operate on it (e.g., getOption()) will work. The primary purpose
of this early call is to offer the ability to modify incoming packets
in their raw form. Unless you need to access to the raw data, it is
usually better to install your callout on the "pkt6_receive" hook point.
- Next step status: If any callout sets the status to SKIP, the
server will assume that the callout parsed the buffer and added the
necessary option objects to the @c options_ field; the server will not
do any parsing. If the callout sets the skip flag but does not parse
the buffer, the server will most probably drop the packet due to
the absence of mandatory options. If you want to drop the packet,
see the description of the skip flag in the "pkt6_receive" hook point.
@subsection dhcpv6HooksPkt6Receive pkt6_receive
- @b Arguments:
- name: @b query6, type: isc::dhcp::Pkt6Ptr, direction: in/out
- @b Description: This callout is executed when an incoming DHCPv6
packet is received and its content is parsed. The sole argument
"query6" contains a pointer to an @c isc::dhcp::Pkt6 object that contains
all information regarding incoming packet, including its source and
destination addresses, the interface over which it was received, a list
of all options present within and relay information. All fields of
the "query6" object can be modified at this time, except data_. (data_
contains the incoming packet as raw buffer. By the time this hook is
reached, that information has already been parsed and is available though
other fields in the Pkt6 object. For this reason, modification of the
@c data_ field would have no effect.)
- Next step status: If any callout sets the status to SKIP, the server will
drop the packet and start processing the next one. The reason for the drop
will be logged if logging is set to the appropriate debug level.
@subsection dhcpv6HooksSubnet6Select subnet6_select
- @b Arguments:
- name: @b query6, type: isc::dhcp::Pkt6Ptr, direction: in/out
- name: @b subnet6, type: isc::dhcp::Subnet6Ptr, direction: in/out
- name: @b subnet6collection, type: const isc::dhcp::Subnet6Collection *, direction: in
- @b Description: This callout is executed when a subnet is being
selected for the incoming packet. All parameters, addresses and
prefixes will be assigned from that subnet. A callout can select a
different subnet if it wishes so, the list of all subnets currently
configured being provided as "subnet6collection". The list itself must
not be modified.
- Next step status: If any callout installed on "subnet6_select"
sets the status to SKIP, the server will not select any subnet. Packet processing
will continue, but will be severely limited.
@subsection dhcpv6HooksLease6Select lease6_select
- @b Arguments:
- name: @b subnet6, type: isc::dhcp::Subnet6Ptr, direction: in
- name: @b fake_allocation, type: bool, direction: in
- name: @b lease6, type: isc::dhcp::Lease6Ptr, direction: in/out
- @b Description: This callout is executed after the server engine
has selected a lease for client's request but before the lease
has been inserted into the database. Any modifications made to the
"lease6" object will affect the lease's record in the database.
The callout should make sure that any modifications are sanity
checked as the server will use that data as is, with no further
checking.\n\n The server processes lease requests for SOLICIT and
REQUEST in a very similar way. The major difference is that
for SOLICIT the lease is only selected; it is not inserted into
the database. The callouts can distinguish between the SOLICIT and
REQUEST by checking the value of the "fake_allocation" flag: a value
of true means that the lease won't be inserted into the database
(SOLICIT case), a value of false means that it will (REQUEST).
- Next step status: If any callout installed on "lease6_select"
sets the status to SKIP, the server will not assign that particular lease.
Packet processing will continue and the client may get other addresses
or prefixes if it requested more than one address and/or prefix.
@subsection dhcpv6HooksLease6Renew lease6_renew
- @b Arguments:
- name: @b query6, type: isc::dhcp::PktPtr, direction: in
- name: @b lease6, type: isc::dhcp::Lease6Ptr, direction: in/out
- name: @b ia_na, type: boost::shared_ptr, direction: in/out
- @b Description: This callout is executed when the server engine is
about to renew an existing lease. The client's request is provided as
the "query6" argument and the existing lease with the appropriate fields
already modified is given in the "lease6" argument. The final argument,
ia_na, is the IA_NA option that will be sent back to the client.
Callouts installed on the "lease6_renew" may modify the content of
the "lease6" object. Care should be taken however, as that modified
information will be written to the database without any further
checking. \n\n Although the envisaged usage assumes modification of T1,
T2, preferred and valid lifetimes only, other parameters associated
with the lease may be modified as well. The only exception is the @c addr_
field, which must not be modified as it is used by the database to
select the existing lease to be updated. Care should also be taken to
modify the "ia_na" argument to match any changes in the "lease6" argument.
If a client sends more than one IA_NA option, callouts will be called
separately for each IA_NA instance. The callout will be called only
when the update is valid, i.e. conditions such as an invalid addresses
or invalid iaid renewal attempts will not trigger this hook point.
- Next step status: If any callout installed on "lease6_renew"
sets the status to SKIP, the server will not renew the lease. Under these
circumstances, the callout should modify the "ia_na" argument to reflect
this fact; otherwise the client will think the lease was renewed and continue
to operate under this assumption.
@subsection dhcpv6HooksLease6Decline lease6_decline
- @b Arguments:
- name: @b query6, type: isc::dhcp::PktPtr, direction: in
- name: @b lease6, type: isc::dhcp::Lease6Ptr, direction: in/out
- @b Description: This callout is executed when the server engine is
about to decline an existing lease. The client's DECLINE is provided as
the "query6" argument and the existing lease with the appropriate fields
already modified is given in the "lease6" argument. The lease contains
the lease before it is being declined.
- Next step status: If any callout installed on "lease6_decline"
sets the status to SKIP, the server will not decline the lease, but will
continue processing the packet as if it did. It will send the response
that the lease was declined, but the actual database will not be
updated. If any callout installed sets the status to DROP, the packet
processing will be aborted, the lease will not be declined and the
server will not send a response.
@subsection dhcpv6HooksLease6Release lease6_release
- @b Arguments:
- name: @b query6, type: isc::dhcp::PktPtr, direction: in
- name: @b lease6, type: isc::dhcp::Lease6Ptr, direction: in/out
- @b Description: This callout is executed when the server engine is
about to release an existing lease. The client's request is provided
as the "query6" argument and the existing lease is given in the "lease6"
argument. Although the "lease6" structure may be modified, it doesn't
make sense to do so as it will be destroyed immediately the callouts
finish execution.
- Next step status: If any callout installed on "lease6_release"
sets the status to SKIP, the server will not delete the lease, which will
remain in the database until it expires. However, the server will send out
the response back to the client as if it did.
@subsection dhcpv6HooksPkt6Send pkt6_send
- @b Arguments:
- name: @b response6, type: isc::dhcp::Pkt6Ptr, direction: in/out
- @b Description: This callout is executed when server's response
is about to be send back to the client. The sole argument "response6"
contains a pointer to an @c isc::dhcp::Pkt6 object that contains the
packet, with set source and destination addresses, interface over which
it will be send, list of all options and relay information. All fields
of the "response6" object can be modified at this time. It should be
noted that unless the callout sets the skip flag (see below), anything
placed in the @c buffer_out_ field will be overwritten when the callout
returns. (buffer_out_ is scratch space used for constructing the packet.)
- Next step status: If any callout sets the status to SKIP, the server
will assume that the callout did pack the "transaction-id", "message type"
and option objects into the @c buffer_out_ field and will skip packing part.
Note that if the callout sets skip flag, but did not prepare the
output buffer, the server will send a zero sized message that will be
ignored by the client. If you want to drop the packet, please see
skip flag in the "buffer6_send" hook point.
@subsection dhcpv6HooksBuffer6Send buffer6_send
- @b Arguments:
- name: @b response6, type: isc::dhcp::Pkt6Ptr, direction: in/out
- @b Description: This callout is executed when server's response is
assembled into binary form and is about to be send back to the
client. The sole argument "response6" contains a pointer to an
@c isc::dhcp::Pkt6 object that contains the packet, with set source and
destination addresses, interface over which it will be sent, list of
all options and relay information. All options are already encoded
in @c buffer_out_ field. It doesn't make sense to modify anything but the
contents of buffer_out_ at this time (although if it is a requirement
to modify that data, it will probably be found easier to modify the
option objects in a callout attached to the "pkt6_send" hook).
- Next step status: If any callout sets the status to SKIP, the server
will drop this response packet. However, the original request packet
from a client has been processed, so server's state has most likely changed
(e.g. lease was allocated). Setting this flag merely stops the change
being communicated to the client.
@subsection dhcpv6HooksLease6Expire lease6_expire
- @b Arguments:
- name: @b lease6, type: isc::dhcp::Lease6Ptr, direction: in/out
- name: @b remove_lease, type: bool, direction: in
- @b Description: this callout is executed for each expired lease when
the server performs reclamation of the expired leases. During this
process the server executes "lease6_expire" callout, removes the DNS
records associated with this lease and finally removes the lease from
the database or updates its status to "expired-reclaimed". The "lease6"
argument contains the pointer to the lease being reclaimed. The second
argument "remove_lease" indicates if the reclaimed leases should be
removed from the lease database (if true), or their state should be
set to "expired-reclaimed" in the lease database. This argument
is only used by the callout if it takes responsibility for the lease
reclamation, i.e. it sets the "skip" flag to "true". The "remove_lease"
argument is set to "true" if the "flush-reclaimed-timer-wait-time" is
set to 0 in the server configuration file.
- Next step status: if the callout sets the status to SKIP, the server
will assume that the callout has fully reclaimed the lease, i.e.
performed the DNS update and updated the lease in the database. The
server will not perform any further actions on the lease for which the
skip flag has been set. It is important to note that if the callout
sets this flag but fails to reclaim the lease in the database, the
reclamation routine will repeatedly process this lease in subsequent
runs. Therefore, the implementors of this callout must make sure that
skip flag is only set when the lease has been actually reclaimed in the
database by the callout.
@subsection dhcpv6HooksLease6Recover lease6_recover
- @b Arguments:
- name: @b lease6, type: isc::dhcp::Lease6Ptr, direction: in
- @b Description: this callout is executed for each declined lease that
has expired (was put aside for the duration of decline-probation-period)
and is being recovered. The lease has already been stripped
from any client identifying information when it was put into declined
state. In principle the callouts can modify the lease in this hook,
but it makes little sense. There's no useful data in the lease, except
the IPv6 address (which must not be modified).
- Next step status: if the callout sets the next step action to SKIP,
the server will skip the lease recovery. In other words, it will keep
the lease as is. This is not recommended in general, as the declined
expired leases will remain in the database and their recovery will
be attempted during the next reclaim cycle.
*/