dhcp6_hooks.dox 22.9 KB
Newer Older
1
// Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC")
2
//
3 4 5
// 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/.
6 7

/**
8 9 10
 @page dhcpv6Hooks The Hooks API for the DHCPv6 Server

 @section dhcpv6HooksIntroduction Introduction
11 12
 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.
13
 An overview of the API and a tutorial for writing such code can be found in
14
 the @ref hooksdgDevelopersGuide.  Information for Kea maintainers can be
15
 found in the @ref hooksComponentDeveloperGuide.
16

Francis Dupont's avatar
Francis Dupont committed
17
 This manual is more specialized and is aimed at developers of hook
18 19 20
 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:
21 22 23 24 25 26 27 28 29 30 31

 - 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.
   - <b>in/out</b> - 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.
32 33 34
 - 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.
35 36 37 38
 - 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.
39 40 41

@section dhcpv6HooksHookPoints Hooks in the DHCPv6 Server

42 43 44 45
The following list is roughly ordered by appearance of specific hook points during
packet processing, but the exact order depends on the actual processing. Hook points
that are not specific to packet processing (e.g. lease expiration) will be added
to the end of this list.
46

47 48 49 50 51
 @subsection dhcpv6HooksBuffer6Receive buffer6_receive

 - @b Arguments:
   - name: @b query6, type: isc::dhcp::Pkt6Ptr, direction: <b>in/out</b>

52
 - @b Description: This callout is executed when an incoming DHCPv6
53 54
   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
55 56 57
   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
58
   the @c options_ field (that will eventually contain a list of objects
59 60 61 62
   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
63
   usually better to install your callout on the "pkt6_receive" hook point.
64

65
 - <b>Next step status</b>: If any callout sets the status to SKIP, the
66 67
   server will assume that the callout parsed the buffer and added the
   necessary option objects to the @c options_ field; the server will not
68 69 70
   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,
71
   see the description of the skip flag in the "pkt6_receive" hook point.
72

73 74 75
 @subsection dhcpv6HooksPkt6Receive pkt6_receive

 - @b Arguments:
Tomek Mrugalski's avatar
Tomek Mrugalski committed
76
   - name: @b query6, type: isc::dhcp::Pkt6Ptr, direction: <b>in/out</b>
77

78
 - @b Description: This callout is executed when an incoming DHCPv6
79 80
   packet is received and its content is parsed. The sole argument
   "query6" contains a pointer to an @c isc::dhcp::Pkt6 object that contains
81
   all information regarding incoming packet, including its source and
82
   destination addresses, the interface over which it was received, a list
83
   of all options present within and relay information.  All fields of
84
   the "query6" object can be modified at this time, except data_. (data_
85
   contains the incoming packet as raw buffer. By the time this hook is
86
   reached, that information has already been parsed and is available though
87 88
   other fields in the Pkt6 object.  For this reason, modification of the
   @c data_ field would have no effect.)
89

90
 - <b>Next step status</b>: If any callout sets the status to SKIP, the server will
91 92
   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.
93 94 95 96

@subsection dhcpv6HooksSubnet6Select subnet6_select

 - @b Arguments:
Tomek Mrugalski's avatar
Tomek Mrugalski committed
97
   - name: @b query6, type: isc::dhcp::Pkt6Ptr, direction: <b>in/out</b>
98
   - name: @b subnet6, type: isc::dhcp::Subnet6Ptr, direction: <b>in/out</b>
99
   - name: @b subnet6collection, type: const isc::dhcp::Subnet6Collection *, direction: <b>in</b>
100

101
 - @b Description: This callout is executed when a subnet is being
102 103 104
   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
105
   configured being provided as "subnet6collection". The list itself must
106 107
   not be modified.

108 109
 - <b>Next step status</b>: If any callout installed on "subnet6_select"
   sets the status to SKIP, the server will not select any subnet. Packet processing
110
   will continue, but will be severely limited.
111

112 113 114 115 116 117 118
@subsection dhcpv6HooksHost6Identifier host6_identifier

 - @b Arguments:
   - name: @b query6, type isc::dhcp::Pkt6Ptr, direction: <b>in</b>
   - name: @b id_type, type isc::dhcp::Host::IdentifierType, direction: <b>in/out</b>
   - name: @b id_value, type std::vector<uint8_t>, direction: <b>out</b>

Francis Dupont's avatar
Francis Dupont committed
119
 - @b Description: this callout is executed only if flexible identifiers are
120
   enabled, i.e. host-reservation-identifiers contain 'flex-id' value. This
Francis Dupont's avatar
Francis Dupont committed
121
   callout enables external library to provide values for flexible identifiers.
122 123 124 125 126 127
   To be able to use this feature, flex_id hook library is needed.

 - <b>Next step status</b>: If a callout installed on the "host6_identifier" hook
   point sets the next step status to value other than NEXT_STEP_CONTINUE, the
   identifier will not be used.

128
@subsection dhcpv6HooksLease6Select lease6_select
129

130
 - @b Arguments:
131
   - name: @b query6, type: isc::dhcp::Pkt6Ptr, direction: <b>in</b>
132 133 134
   - name: @b subnet6, type: isc::dhcp::Subnet6Ptr, direction: <b>in</b>
   - name: @b fake_allocation, type: bool, direction: <b>in</b>
   - name: @b lease6, type: isc::dhcp::Lease6Ptr, direction: <b>in/out</b>
135

136
 - @b Description: This callout is executed after the server engine
137 138
   has selected a lease for client's request but before the lease
   has been inserted into the database. Any modifications made to the
139 140 141
   "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
142
   checking.\n\n The server processes lease requests for SOLICIT and
143 144 145 146 147 148 149
   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).

150 151
 - <b>Next step status</b>: If any callout installed on "lease6_select"
   sets the status to SKIP, the server will not assign that particular lease.
152 153
   Packet processing will continue and the client may get other addresses
   or prefixes if it requested more than one address and/or prefix.
154

155 156 157 158 159
@subsection dhcpv6HooksLease6Renew lease6_renew

 - @b Arguments:
   - name: @b query6, type: isc::dhcp::PktPtr, direction: <b>in</b>
   - name: @b lease6, type: isc::dhcp::Lease6Ptr, direction: <b>in/out</b>
160 161
   - name: @b ia_na, type: isc::dhcp::Option6IAPtr direction: <b>in/out</b>
   - name: @b ia_pd, type: isc::dhcp::Option6IAPtr, direction: <b>in/out</b>
162

163 164
 - @b Description: This callout is executed when the server engine is
   about to renew an existing lease. The client's request is provided as
165
   the "query6" argument and the existing lease with the appropriate fields
166 167 168 169
   already modified is given in the "lease6" argument. The remaining two
   arguments, "ia_na" and "ia_pd", are mutually exclusive and they provide
   pointers to the IA_NA or IA_PD option which will be sent back to the
   client. Callouts installed on the "lease6_renew" may modify the content of
170
   the "lease6" object. Care should be taken however, as that modified
171 172 173
   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
174
   with the lease may be modified as well. The only exception is the @c addr_
175 176
   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
177 178 179 180 181 182
   modify the "ia_na" and "ia_pd" arguments to match any changes in the
   "lease6" argument. If a client sends more than one IA (IA_NA/IA_PD)
   option, callouts will be called separately for each IA 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.
183

184 185
 - <b>Next step status</b>: If any callout installed on "lease6_renew"
   sets the status to SKIP, the server will not renew the lease. Under these
186 187 188
   circumstances, the callout should modify the "ia_na" or "ia_pd"
   argument to reflect this fact; otherwise the client will think the
   lease was renewed and continue to operate under this assumption.
189

190 191 192 193 194
@subsection dhcpv6HooksLease6Rebind lease6_rebind

 - @b Arguments:
   - name: @b query6, type: isc::dhcp::PktPtr, direction: <b>in</b>
   - name: @b lease6, type: isc::dhcp::Lease6Ptr, direction: <b>in/out</b>
195 196
   - name: @b ia_na, type: isc::dhcp::Option6IAPtr direction: <b>in/out</b>
   - name: @b ia_pd, type: isc::dhcp::Option6IAPtr, direction: <b>in/out</b>
197 198 199 200

 - @b Description: This callout is executed when the server engine is
   about to rebind an existing lease. The client's request is provided as
   the "query6" argument and the existing lease with the appropriate fields
201 202 203 204
   already modified is given in the "lease6" argument. The remaining two
   arguments, "ia_na" and "ia_pd", are mutually exclusive and they provide
   pointers to the IA_NA or IA_PD option which will be sent back to the
   client. Callouts installed on the "lease6_renew" may modify the content of
205 206 207 208 209 210 211
   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
212 213 214 215 216 217
   modify the "ia_na" and "ia_pd" arguments to match any changes in the
   "lease6" argument. If a client sends more than one IA (IA_NA/IA_PD)
   option, callouts will be called separately for each IA 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.
218 219 220

 - <b>Next step status</b>: If any callout installed on "lease6_rebind"
   sets the status to SKIP, the server will not rebind the lease. Under these
221 222 223
   circumstances, the callout should modify the "ia_na" or "ia_pd"
   argument to reflect this fact; otherwise the client will think the
   lease was rebound and continue to operate under this assumption.
224

225 226 227 228 229 230 231
@subsection dhcpv6HooksLease6Decline lease6_decline

 - @b Arguments:
   - name: @b query6, type: isc::dhcp::PktPtr, direction: <b>in</b>
   - name: @b lease6, type: isc::dhcp::Lease6Ptr, direction: <b>in/out</b>

 - @b Description: This callout is executed when the server engine is
Tomek Mrugalski's avatar
Tomek Mrugalski committed
232
   about to decline an existing lease. The client's DECLINE is provided as
233 234 235 236 237 238 239 240 241 242 243 244
   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.

 - <b>Next step status</b>: 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.

245 246 247 248 249 250
@subsection dhcpv6HooksLease6Release lease6_release

 - @b Arguments:
   - name: @b query6, type: isc::dhcp::PktPtr, direction: <b>in</b>
   - name: @b lease6, type: isc::dhcp::Lease6Ptr, direction: <b>in/out</b>

251 252
 - @b Description: This callout is executed when the server engine is
   about to release an existing lease. The client's request is provided
253 254
   as the "query6" argument and the existing lease is given in the "lease6"
   argument.  Although the "lease6" structure may be modified, it doesn't
255 256
   make sense to do so as it will be destroyed immediately the callouts
   finish execution.
257

258 259
 - <b>Next step status</b>: If any callout installed on "lease6_release"
   sets the status to SKIP, the server will not delete the lease, which will
260 261
   remain in the database until it expires. However, the server will send out
   the response back to the client as if it did.
262

263
@subsection dhcpv6HooksPkt6Send pkt6_send
264 265

 - @b Arguments:
266
   - name: @b query6, type: isc::dhcp::Pkt6Ptr, direction: <b>in</b>
Tomek Mrugalski's avatar
Tomek Mrugalski committed
267
   - name: @b response6, type: isc::dhcp::Pkt6Ptr, direction: <b>in/out</b>
268

269
 - @b Description: This callout is executed when server's response
270 271
   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
272 273
   packet, with set source and destination addresses, interface over which
   it will be send, list of all options and relay information.  All fields
274 275 276 277
   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.)
278

279
 - <b>Next step status</b>: If any callout sets the status to SKIP, the server
280 281
   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.
282 283
   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
284
   ignored by the client. If you want to drop the packet, please see
285
   skip flag in the "buffer6_send" hook point.
286 287 288 289 290

@subsection dhcpv6HooksBuffer6Send buffer6_send

 - @b Arguments:
   - name: @b response6, type: isc::dhcp::Pkt6Ptr, direction: <b>in/out</b>
291

292
 - @b Description: This callout is executed when server's response is
293
   assembled into binary form and is about to be send back to the
294 295
   client. The sole argument "response6" contains a pointer to an
   @c isc::dhcp::Pkt6 object that contains the packet, with set source and
296 297
   destination addresses, interface over which it will be sent, list of
   all options and relay information. All options are already encoded
298 299
   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
300
   to modify that data, it will probably be found easier to modify the
301
   option objects in a callout attached to the "pkt6_send" hook).
302

303
 - <b>Next step status</b>: If any callout sets the status to SKIP, the server
304
   will drop this response packet. However, the original request packet
305
   from a client has been processed, so server's state has most likely changed
306 307
   (e.g. lease was allocated). Setting this flag merely stops the change
   being communicated to the client.
308

309 310 311 312 313 314 315 316 317 318 319 320 321 322
@subsection dhcpv6HooksLease6Expire lease6_expire

- @b Arguments:
  - name: @b lease6, type: isc::dhcp::Lease6Ptr, direction: <b>in/out</b>
  - name: @b remove_lease, type: bool, direction: <b>in</b>

- @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
323
  set to "expired-reclaimed" in the lease database. This argument
324
  is only used by the callout if it takes responsibility for the lease
325
  reclamation, i.e. it sets the "skip" flag to "true".  The "remove_lease"
326 327
  argument is set to "true" if the "flush-reclaimed-timer-wait-time" is
  set to 0 in the server configuration file.
328

329
- <b>Next step status</b>: if the callout sets the status to SKIP, the server
330 331 332 333 334 335 336 337 338 339
  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.

Tomek Mrugalski's avatar
Tomek Mrugalski committed
340
@subsection dhcpv6HooksLease6Recover lease6_recover
341 342 343 344 345

- @b Arguments:
  - name: @b lease6, type: isc::dhcp::Lease6Ptr, direction: <b>in</b>

- @b Description: this callout is executed for each declined lease that
346 347
  has expired (was put aside for the duration of decline-probation-period)
  and is being recovered. The lease has already been stripped
348 349 350
  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
Tomek Mrugalski's avatar
Tomek Mrugalski committed
351
  the IPv6 address (which must not be modified).
352 353 354 355 356 357 358

- <b>Next step status</b>: 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.

359
@subsection dhcpv6HooksCommandProcessed command_processed
360 361

 - @b Arguments:
362 363 364 365 366 367 368 369 370 371 372 373 374
   - name: @b name, type: std::string, direction: <b>in</b>
   - name: @b arguments type: isc::data::ConstElementPtr, direction: <b>in</b>
   - name: @b response, type: isc::data::ConstElementPtr, direction: <b>in/out</b>

 - @b Description: this callout is executed after the DHCPv6 server receives
   and processes a control command over the command channel (typically unix domain socket).
   The "name" argument is the name of the command processed.
   The "arguments" argument is a pointer to the parsed JSON structure
   containing the command's input arguments.  The "response" argument
   is the parsed JSON stucture containing the response generated by
   the command processing.

 - <b>Next step status</b>: Not applicable, it's value will be ignored.
375

376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426
@section dhcpv6HooksOptionsAccess Accessing DHCPv6 Options within a Packet
When the server constructs a response message to a client it includes
DHCP options configured for this client in a response message. Apart
from the dynamically created options, such as IA_NA or ClientFQDN, it
typically includes many options specified in the server configuration
and held within the configuration structures by @c CfgMgr. Option
instances are created once, during server configuration, and the
@c CfgMgr holds pointers to those instances until the next server
reconfiguration.

When the server includes an option in a response message it copies
a pointer to the instance of this option, rather than entire option.
This ensures the good performance of response message creation. However,
it also implies that any modification to the option carried in the
DHCP response will affect an instance of this option in the server
configuration structures. This is obviously not desired as it would
affect all subsequent DHCP transactions involving this option. The
DHCP server code avoids modifying the options included in the messages
so it is possible to ensure good performance without a risk of
accidentally modifying server configuration. The situation is
different with hooks libraries which purpose is, in many cases,
to modify values of options inserted by the server.

Thus, @c Pkt class provides a mechanism to return a copy of an
option to a caller (e.g. a callout), rather than an instance
shared with the @c CfgMgr. This mechanism is enabled for all instances
of @c Pkt6 passed to the callouts, i.e. "query6" and "response6"
arguments. It is also automatically disabled when the callout
returns the control back to the server.

At every hook point, where the server passes an instance of a packet
to the callouts, the server calls
@c isc::dhcp::Pkt6::setCopyRetrievedOptions (true)
to force copying options retrieved by @c isc::dhcp::Pkt6::getOption,
@c isc::dhcp::Pkt6::getOptions, @c isc::dhcp::Pkt6::getRelayOption
and @c isc::dhcp::Pkt6::getAnyRelayOption within callouts. The copied
option replaces an original option within the packet and any
modification to the option content by the callout would only affect
the option instance associated with the packet.

On the other hand, copying each retrieved option may be expensive.
If performance of a hook library is a concern, it is possible for the
hook library to disable copying retrieved options by calling
@c isc::dhcp::Pkt6::setCopyRetrievedOptions (false) within a callout.
In this case however, the hook library implementer must be aware that
any modification of the option instance would affect the server
configuration and may disrupt server's operation. Thus, disabling
copying of retrieved options is not recommended unless the hook
library is not intended to modify configured options carried
within a packet.

427
*/