hooks.xml 76.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!ENTITY mdash  "&#x2014;" >
]>

  <chapter id="hooks-libraries">
    <title>Hooks Libraries</title>
    <section id="hooks-libraries-introduction">
      <title>Introduction</title>
      <para>
      Although Kea offers a lot of flexibility, there may be cases where
Josh Soref's avatar
Josh Soref committed
13
      its behavior needs customization.  To accommodate this possibility,
14 15 16 17 18 19 20 21 22 23 24 25 26 27
      Kea includes the idea of "Hooks".  This feature lets Kea load one
      or more dynamically-linked libraries (known as "hooks libraries")
      and, at various points in its processing ("hook points"), call
      functions in them.  Those functions perform whatever custom
      processing is required.
      </para>
      <para>
      Hooks libraries are attached to individual Kea processes, not to
      Kea as a whole.  This means (for example) that it is possible
      to associate one set of libraries with the DHCP4 server and a
      different set to the DHCP6 server.
      </para>
      <para>
      Another point to note is that it is possible for a process to
28 29 30 31 32 33
      load multiple libraries.  When processing reaches a hook point,
      Kea calls the hooks library functions attached to it.  If multiple
      libraries have attached a function to a given hook point, Kea calls
      all of them, in the order in which the libraries are specified in
      the configuration file. The order may be important: consult the
      documentation of the libraries to see if this is the case.
34 35 36 37
      </para>
      <para>
      The next section describes how to configure hooks libraries. If you
      are interested in writing your own hooks library, information can be
38
      found in the <ulink url="https://jenkins.isc.org/job/Fedora20_32_doxygen_doc/doxygen/">Kea
39 40 41 42 43 44 45 46 47 48
      Developer's Guide</ulink>.
      </para>
    </section> <!-- end Introduction -->
    <section>
      <title>Configuring Hooks Libraries</title>
      <para>
      The hooks libraries for a given process are configured using the
      <command>hooks-libraries</command> keyword in the
      configuration for that process. (Note that
      the word "hooks" is plural).  The value of the keyword
49 50 51
      is an array of map structures, each structure corresponding to a hooks
      library.  For example, to set up two hooks libraries for the DHCPv4
      server, the configuration would be:
52 53 54 55
<screen>
<userinput>"Dhcp4": {
    :
    "hooks-libraries": [
56 57 58 59
        {
            "library": "/opt/charging.so"
        },
        {
Tomek Mrugalski's avatar
Tomek Mrugalski committed
60 61 62 63 64 65 66 67 68 69 70
            "library": "/opt/local/notification.so",
            "parameters": {
                "mail": "spam@example.com",
                "floor": 13,
                "debug": false,
                "users": [ "alice", "bob", "charlie" ],
                "languages": {
                    "french": "bonjour",
                    "klingon": "yl'el"
                }
            }
71
        }
72 73 74 75 76
    ]
    :
}</userinput>
</screen>
      </para>
77

78
      <note><para>
79 80
        This is a change to the syntax used in Kea 0.9.2 and earlier, where
        hooks-libraries was a list of strings, each string being the name of
81
        a library.  The change was made in Kea 1.0 to facilitate the
82
        specification of library-specific parameters, a capability
83
        available in Kea 1.1.0 onwards.
84
      </para></note>
Tomek Mrugalski's avatar
Tomek Mrugalski committed
85

86 87
        <note>
          <para>
Tomek Mrugalski's avatar
Tomek Mrugalski committed
88 89 90 91
          The library reloading behavior has changed in Kea 1.1. Libraries are
          reloaded, even if their list hasn't changed. Kea does that, because
          the parameters specified for the library (or the files those
          parameters point to) may have changed.
92 93
          </para>
        </note>
Tomek Mrugalski's avatar
Tomek Mrugalski committed
94 95 96 97 98 99 100 101 102 103 104

      <para>
        Libraries may have additional parameters. Those are not mandatory in the
        sense that there may be libraries that don't require them. However, for
        specific library there is often specific requirement for specify certain
        set of parameters. Please consult the documentation for your library
        for details. In the example above, the first library has no parameters.
        The second library has five parameters, specifying mail (string
        parameter), floor (integer parameter), debug (boolean parameter) and
        even lists (list of strings) and maps (containing strings). Nested
        parameters could be used if the library supports it. This topic is
105 106
        explained in detail in the Hooks Developer's Guide in the "Configuring
        Hooks Libraries" section.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
107 108
      </para>

109 110 111 112 113 114 115 116 117 118 119 120 121
      <para>
      Notes:
        <itemizedlist mark='bullet'>
          <listitem><para>
          The full path to each library should be given.
          </para></listitem>
          <listitem><para>
          As noted above, order may be important - consult the documentation for
          each library.
          </para></listitem>
          <listitem><para>
          An empty list has the same effect as omitting the
          <command>hooks-libraries</command> configuration element all together.
Stephen Morris's avatar
Stephen Morris committed
122 123 124 125 126 127 128 129 130 131 132 133
          </para>
          <note><para>
          There is one case where this is not true: if Kea
          is running with a configuration that contains a
          <command>hooks-libraries</command> item, and that item is
          removed and the configuration reloaded, the removal will be
          ignored and the libraries remain loaded.  As a workaround,
          instead of removing the <command>hooks-libraries</command>
          item, change it to an empty list.  This will be fixed in a
          future version of Kea.
          </para></note>
          </listitem>
134 135 136 137 138 139 140
        </itemizedlist>
      </para>
      <para>
      At the present time, only the kea-dhcp4 and kea-dhcp6 processes support
      hooks libraries.
      </para>
    </section>
141 142 143 144

    <section>
      <title>Available Hooks Libraries</title>
      <para>
145
      As described above, the hooks functionality provides a way to customize
146
      a Kea server without modifying the core code.  ISC has chosen to take
147 148 149
      advantage of this feature to provide functions that may only be useful
      to a subset of Kea users.  To this end ISC has created some hooks
      libraries; these discussed in the following sections.
150 151
      </para>

152 153
      <note><para>
      Some of these libraries will be available with the base code while others
154 155
      will be shared with organizations supporting development of Kea
      , possibly as a 'benefit' or 'thank you' for helping to sustain
156
      the larger Kea project. If you would like to get access to those
157
      libraries, please consider taking out a support contract: this includes
158
      professional support, advance security notifications, input into our
159
      roadmap planning, and many other benefits, while helping
160 161 162 163 164 165
      making Kea sustainable in the long term.
      </para></note>

      <para>Currently the following libraries are available or planned from ISC:

        <table frame="all" id="hook-libs">
166
          <title>List of available hooks libraries</title>
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
          <tgroup cols='3'>
          <colspec colname='name' />
          <colspec colname='avail' />
          <colspec colname='description' />
          <thead>
            <row>
              <entry>Name</entry>
              <entry>Availability</entry>
              <entry>Since</entry>
              <entry>Description</entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry>user_chk</entry>
              <entry>Kea sources</entry>
              <entry>Kea 0.8</entry>
185 186
              <entry>Reads known users list from a file. Unknown users
              will be assigned a
187
              lease from the last subnet defined in the configuration file,
188 189 190 191
              e.g. to redirect them a captive portal. This demonstrates how an
              external source of information can be used to influence the Kea
              allocation engine. This hook is part of the Kea source code and is
              available in the src/hooks/dhcp/user_chk directory.</entry>
192 193 194 195 196
            </row>
            <row>
              <entry>Forensic Logging</entry>
              <entry>Support customers</entry>
              <entry>Kea 1.1.0</entry>
197
              <entry>This library provides hooks that record a detailed log of
198 199 200 201 202 203
              lease assignments and renewals into a set of log files. In many
              legal jurisdictions companies, especially ISPs, must record
              information about the addresses they have leased to DHCP
              clients. This library is designed to help with that
              requirement. If the information that it records is sufficient it
              may be used directly. If your jurisdiction requires that you save
204
              a different set of information, you may use it as a template or
205 206 207
              example and create your own custom logging hooks.</entry>
            </row>
            <row>
Francis Dupont's avatar
Francis Dupont committed
208
              <entry>Flexible Identifier</entry>
209
              <entry>Support customers</entry>
210
              <entry>Kea 1.2.0</entry>
211 212 213 214
              <entry>Kea software provides a way to handle host reservations
              that include addresses, prefixes, options, client classes and
              other features. The reservation can be based on hardware address,
              DUID, circuit-id or client-id in DHCPv4 and using hardware address
215
              or DUID in DHCPv6. However, there are sometimes scenarios where the
216 217 218
              reservation is more complex, e.g. uses other options that
              mentioned above, uses part of specific options or perhaps even a
              combination of several options and fields to uniquely identify a
Tomek Mrugalski's avatar
Tomek Mrugalski committed
219
              client. Those scenarios are addressed by the Flexible Identifiers
220
              hook application. It allows defining an expression, similar to
Francis Dupont's avatar
Francis Dupont committed
221
              the one used in client classification,
222 223 224
              e.g. substring(relay6[0].option[37],0,6). Each incoming packet is
              evaluated against that expression and its value is then searched
              in the reservations database.
225 226
              </entry>
            </row>
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
            <row>
              <entry>Host Commands</entry>
              <entry>Support customers</entry>
              <entry>Kea 1.2.0</entry>
              <entry>Kea provides a way to store host reservations in a
              database. In many larger deployments it is useful to be able to
              manage that information while the server is running. This library
              provides management commands for adding, querying and deleting
              host reservations in a safe way without restarting the server.
              In particular, it validates the parameters, so an attempt to
              insert incorrect data, e.g. add a host with conflicting identifier
              in the same subnet will be rejected. Those commands are
              exposed via command channel (JSON over unix sockets) and Control
              Agent (JSON over RESTful interface). Additional commands and
              capabilities related to host reservations will be added in the
              future.</entry>
            </row>
244 245 246 247
            <row>
              <entry>Subnet Commands</entry>
              <entry>Support customers</entry>
              <entry>Kea 1.3.0</entry>
248 249 250
              <entry>In deployments in which subnet configuration needs to
              be frequently updated, it is a hard requirement that such updates be
              performed without the need for a full DHCP server reconfiguration
251
              or restart. This hooks library allows for incremental changes
252
              to the subnet configuration such as: adding a subnet, removing
253 254 255 256 257 258
              a subnet. It also allows for listing all available subnets and
              fetching detailed information about a selected subnet. The
              commands exposed by this library do not affect other subnets
              or configuration parameters currently used by the server.
              </entry>
            </row>
259 260 261 262 263
          </tbody>
          </tgroup>
          </table>

      </para>
264
      <para>
265
        ISC hopes to see more hooks libraries become available as time
266
        progresses, both developed internally and externally. Since
267
        this list may evolve dynamically, we decided to keep it on a
268 269
        wiki page, available at this link: <ulink
        url="http://kea.isc.org/wiki/Hooks">http://kea.isc.org/wiki/Hooks</ulink>.
270 271
        If you are a developer or are aware of any hooks libraries not
        listed there, please send a note to the kea-users or kea-dev
272
        mailing lists and someone will update it.
273
      </para>
274
      <section>
275
        <title>user_chk: Checking User Access</title>
276
        <para>
277
          The user_chk library is the first hooks library published by ISC. It
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
          attempts to serve several purposes:

          <itemizedlist>
            <listitem>
              <para>To assign "new" or "unregistered" users to a
              restricted subnet, while "known" or "registered" users are assigned
              to unrestricted subnets.</para>
            </listitem>
            <listitem>
              <para>To allow DHCP response options or vendor option
              values to be customized based upon user identity. </para>
            </listitem>
            <listitem>
              <para>To provide a real time record of the user registration
              activity which can be sampled by an external consumer.</para>
            </listitem>
            <listitem>
              <para> To serve as a demonstration of various capabilities
296
              possible using the hooks interface.</para>
297 298 299 300
            </listitem>
          </itemizedlist>
        </para>
        <para>
Francis Dupont's avatar
Francis Dupont committed
301
          Once loaded, the library allows segregating incoming requests into
302 303 304 305 306 307 308 309
          known and unknown clients. For known clients, the packets are
          processed mostly as usual, except it is possible to override certain
          options being sent. That can be done on a per host basis. Clients
          that are not on the known hosts list will be treated as unknown and
          will be assigned to the last subnet defined in the configuration file.
        </para>

        <para>
310
          As an example of use, this behavior may be used to put unknown users into a
311 312
          separate subnet that leads to a walled garden, where they can only
          access a registration portal. Once they fill in necessary data, their
313
          details are added to the known clients file and they get a proper
314 315 316
          address after their device is restarted.
        </para>

317 318 319 320
        <note><para>This library was developed several years before the host
        reservation mechanism has become available. Currently host reservation is
        much more
        powerful and flexible, but nevertheless the user_chk capability to consult
321
        and external source of information about clients and alter Kea's
322
        behavior is useful and remains of educational value.
323 324 325 326
        </para></note>

        <para>
          The library reads the /tmp/user_chk_registry.txt file while being
327
          loaded and each time an incoming packet is processed. The file is expected
328 329 330 331
          to have each line contain a self-contained JSON snippet which must
          have the following two entries:

          <itemizedlist>
332 333 334 335
            <listitem><para><command>type</command>, whose value
            is "HW_ADDR" for IPv4 users or "DUID" for IPv6
            users</para></listitem>
            <listitem><para><command>id</command>, whose value is
Francis Dupont's avatar
Francis Dupont committed
336
            either the hardware address or the DUID from the request
337 338
            formatted as a string of hex digits, with or without
            ":" delimiters.</para></listitem>
339 340 341 342 343
          </itemizedlist>

and may have the zero or more of the following entries:

          <itemizedlist>
344 345 346 347 348
            <listitem><para><command>bootfile</command> whose value
            is the pathname of the desired file</para></listitem>
            <listitem><para><command>tftp_server</command> whose
            value is the hostname or IP address of the desired
            server</para></listitem>
349 350
          </itemizedlist>

351
          A sample user registry file is shown below:
352 353 354 355 356 357 358 359

<screen>{ "type" : "HW_ADDR", "id" : "0c:0e:0a:01:ff:04", "bootfile" : "/tmp/v4bootfile" }
{ "type" : "HW_ADDR", "id" : "0c:0e:0a:01:ff:06", "tftp_server" : "tftp.v4.example.com" }
{ "type" : "DUID", "id" : "00:01:00:01:19:ef:e6:3b:00:0c:01:02:03:04", "bootfile" : "/tmp/v6bootfile" }
{ "type" : "DUID", "id" : "00:01:00:01:19:ef:e6:3b:00:0c:01:02:03:06", "tftp_server" : "tftp.v6.example.com" }</screen>

        </para>

360
        <para>As with any other hooks libraries provided by ISC, internals of the
361 362 363 364 365 366 367 368
        user_chk code are well documented. You can take a look at the  <ulink
        url="https://jenkins.isc.org/job/Fedora20_32_doxygen_doc/doxygen/d8/db2/libdhcp_user_chk.html">Kea Developer's Guide section dedicated to the user_chk library</ulink>
        that discusses how the code works internally. That, together with
        our general entries in <ulink
        url="https://jenkins.isc.org/job/Fedora20_32_doxygen_doc/doxygen/">Hooks
        Framework section</ulink> should give you some pointers how to extend
        this library and perhaps even write your own from scratch.</para>

369
      </section>
370
      <section>
371
        <title>legal_log: Forensic Logging Hooks</title>
372
        <para>
373
        This section describes the forensic log hooks library. This library
Francis Dupont's avatar
Francis Dupont committed
374
        provides hooks that record a detailed log of lease assignments
375
        and renewals into a set of log files.  Currently this library
376
        is only available to ISC customers with a support contract.
377 378 379 380 381 382 383 384 385 386
        </para>
        <para>
        In many legal jurisdictions companies, especially ISPs, must record
        information about the addresses they have leased to DHCP clients.
        This library is designed to help with that requirement.  If the
        information that it records is sufficient it may be used directly.
        If your jurisdiction requires that you save a different set of
        information you may use it as a template or example and create your
        own custom logging hooks.
        </para>
387 388 389 390 391 392 393
        <para>
        This logging is done as a set of hooks to allow it to be customized
        to any particular need.  Modifying a hooks library is easier and
        safer than updating the core code.  In addition by using the hooks
        features those users who don't need to log this information can
        leave it out and avoid any performance penalties.
        </para>
394 395 396 397 398 399 400 401 402 403 404
        <section>
        <title>Log File Naming</title>
          <para>
          The names for the log files have the following form:
          </para>
<screen>
path/base-name.CCYYMMDD.txt
</screen>
          <para>
          The &quot;path&quot; and &quot;base-name&quot; are supplied in the
          configuration as described below see
405
          <xref linkend="forensic-log-configuration"/>.  The next part of the name is
406 407 408 409 410
          the date the log file was started, with four digits for year, two digits
          for month and two digits for day.  The file is rotated on a daily basis.
          </para>
          <note><para>
          When running Kea servers for both DHCPv4 and DHCPv6 the log names must
411
          be distinct.  See the examples in <xref linkend="forensic-log-configuration"/>.
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
          </para></note>
        </section>
        <section>
        <title>DHCPv4 Log Entries</title>
          <para>
          For DHCPv4 the library creates entries based on DHCPREQUEST messages
          and corresponding DHCPv4 leases intercepted by lease4_select
          (for new leases) and lease4_renew (for renewed leases) hooks.
          </para>
          <para>
          An entry is a single string with no embedded end-of-line markers
          and has the following sections:
<screen>
address duration device-id {client-info} {relay-info}
</screen>
          </para>
          <para>
          Where:
          <itemizedlist>
            <listitem><para>
            address - the leased IPv4 address given out and whether it was
            assigned or renewed.
            </para></listitem>
            <listitem><para>
            duration - the lease lifetime expressed in days (if present),
            hours, minutes and seconds.  A lease lifetime of 0xFFFFFFFF will be
            denoted with the text &quot;infinite duration&quot;.
            </para></listitem>
            <listitem><para>
            device-id - the client's hardware address shown as numerical type
            and hex digit string.
            </para></listitem>
            <listitem><para>
            client-info - the DHCP client id option (61) if present, shown as
            a hex string.
            </para></listitem>
            <listitem><para>
Tomek Mrugalski's avatar
Tomek Mrugalski committed
449 450 451
            relay-info - for relayed packets the giaddr and the RAI circuit-id,
            remote-id and subscriber-id options (option 82 sub
            options: 1, 2 and 6) if present.
452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497
            The circuit id and remote id are presented as hex strings
            </para></listitem>
          </itemizedlist>
          </para>
          <para>
          For instance (line breaks added for readability, they would not
          be present in the log file).
<screen>
Address: 192.2.1.100 has been renewed for 1 hrs 52 min 15 secs to a device with
hardware address: hwtype=1 08:00:2b:02:3f:4e, client-id: 17:34:e2:ff:09:92:54
connected via relay at address: 192.2.16.33, identified by circuit-id:
68:6f:77:64:79 and remote-id: 87:f6:79:77:ef
</screen>
          </para>
        </section>
        <section>
        <title>DHCPv6 Log Entries</title>
          <para>
          For DHCPv6 the library creates entries based on lease management
          actions intercepted by the lease6_select (for new leases), lease6_renew
          (for renewed leases) and lease6_rebind (for rebound leases).
          </para>
          <para>
          An entry is a single string with no embedded end-of-line markers
          and has the following sections:
<screen>
address duration device-id {relay-info}*
</screen>
          </para>
          <para>
          Where:
          <itemizedlist>
            <listitem><para>
            address - the leased IPv6 address or prefix given out and whether
            it was assigned or renewed.
            </para></listitem>
            <listitem><para>
            duration - the lease lifetime expressed in days (if present),
            hours, minutes and seconds.  A lease lifetime of 0xFFFFFFFF will be
            denoted with the text "infinite duration".
            </para></listitem>
            <listitem><para>
            device-id - the client's DUID and hardware address (if present).
            </para></listitem>
            <listitem><para>
            relay-info - for relayed packets the content of relay agent
Tomek Mrugalski's avatar
Tomek Mrugalski committed
498 499 500 501 502 503 504
            messages, remote-id (code 37), subscriber-id (code 38) and
            interface-id (code 18) options if present. Note that
            interface-id option, if present, identifies the whole interface the
            relay agent received the message on. This typically translates to a
            single link in your network, but it depends on your specific network
            topology. Nevertheless, this is useful information to better scope
            down the location of the device, so it is being recorded, if present.
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519
            </para></listitem>
          </itemizedlist>
          </para>
          <para>
          For instance (line breaks added for readability, they would not
          be present in the log file).
<screen>
Address:2001:db8:1:: has been assigned for 0 hrs 11 mins 53 secs to a device with
DUID: 17:34:e2:ff:09:92:54 and hardware address: hwtype=1 08:00:2b:02:3f:4e
(from Raw Socket) connected via relay at address: fe80::abcd for client on
link address: 3001::1, hop count: 1, identified by remote-id:
01:02:03:04:0a:0b:0c:0d:0e:0f and subscriber-id: 1a:2b:3c:4d:5e:6f
</screen>
          </para>
        </section>
520 521
        <section id="forensic-log-configuration">
        <title>Configuring the Forensic Log Hooks</title>
522 523 524 525 526 527 528 529 530 531 532 533
          <para>
          To use this functionality the hook library must be included in the
          configuration of the desired DHCP server modules. The legal_log
          library is installed alongside the Kea libraries in
          <filename>[kea-install-dir]/lib</filename> where
          <filename>kea-install-dir</filename> is determined by the
          &quot;--prefix&quot; option of the configure script.  It defaults to
          <filename>/usr/local</filename>.  Assuming the
          default value then, configuring kea-dhcp4 to load the legal_log
          library could be done with the following Kea4 configuration:
<screen>
"Dhcp4": { <userinput>
534 535 536 537 538 539 540 541
    "hooks-libraries": [
        {
            "library": "/usr/local/lib/libdhcp_legal_log.so",
            "parameters": {
                "path": "/var/kea/var",
                "base-name": "kea-forensic4"
            }
        },
542 543 544 545 546 547 548 549 550
        ...
    ] </userinput>
}
</screen>
          </para>
          <para>
          To configure it for kea-dhcp6, the commands are simply as shown below:
<screen>
"Dhcp6": { <userinput>
551 552 553 554 555 556 557 558
    "hooks-libraries": [
        {
            "library": "/usr/local/lib/libdhcp_legal_log.so",
            "parameters": {
                "path": "/var/kea/var",
                "base-name": "kea-forensic6"
            }
        },
559 560 561 562 563 564 565 566 567
        ...
    ] </userinput>
}
</screen>
          </para>
          <para>
          Two Hook Library parameters are supported:
          <itemizedlist>
            <listitem><para>
568
            path - the directory in which the forensic file(s) will be written.  The
569 570 571 572 573
            default value is
            <filename>[prefix]/kea/var</filename>.  The directory must exist.
            </para></listitem>
            <listitem><para>
            base-name - an arbitrary value which is used in conjunction with
Francis Dupont's avatar
Francis Dupont committed
574
            the current system date to form the current forensic file name.  It defaults
575 576 577 578 579 580
            to <filename>kea-legal</filename>.
            </para></listitem>
          </itemizedlist>
          </para>
        </section>
      </section>
581

582
      <section id="flex-id">
583 584
        <title>flex_id: Flexible Identifiers for Host Reservations</title>
        <para>
Tomek Mrugalski's avatar
Tomek Mrugalski committed
585 586 587 588 589 590 591 592 593 594
          This section describes a hook application dedicated to generate
          flexible identifiers for host reservation. Kea software provides a way
          to handle host reservations that include addresses, prefixes, options,
          client classes and other features. The reservation can be based on
          hardware address, DUID, circuit-id or client-id in DHCPv4 and using
          hardware address or DUID in DHCPv6. However, there are sometimes
          scenario where the reservation is more complex, e.g. uses other
          options that mentioned above, uses part of specific options or perhaps
          even a combination of several options and fields to uniquely identify
          a client. Those scenarios are addressed by the Flexible Identifiers
595 596 597 598 599
        hook application.</para>

        <para>Currently this library is only available to ISC customers with a
        support contract.</para>

600
        <para>The library allows for defining an expression, using notation
601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616
        initially used for client classification only. See <xref
        linkend="classification-using-expressions" /> for detailed description
        of the syntax available. One notable difference is that for client
        classification the expression currently has to evaluate to either true
        or false, while the flexible identifier expression is expected to
        evaluate to a string that will be used as identifier. It is a valid case
        for the expression to evaluate to empty string (e.g. in cases where a
        client does not sent specific options). This expression is then
        evaluated for each incoming packet. This evaluation generates an
        identifier that is used to identify the client. In particular, there may
        be host reservations that are tied to specific values of the flexible
        identifier.</para>

        <para>
          The library can be loaded in similar way as other hook libraries. It
          takes one mandatory parameter identifier-expression:
Tomek Mrugalski's avatar
Tomek Mrugalski committed
617 618 619 620 621 622 623 624 625 626 627 628 629
<screen>
"Dhcp6": { <userinput>
    "hooks-libraries": [
        {
            "library": "/path/libdhcp_flex_id.so",
            "parameters": {
                "identifier-expression": "<userinput>expression</userinput>"
            }
        },
        ...
    ] </userinput>
}
</screen>
630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647
        </para>

        <para>
          The flexible identifier library supports both DHCPv4 and DHCPv6.
        </para>

        <para>
          EXAMPLE: Let's consider a case of an IPv6 network that has an
          independent interface for each of the connected customers. Customers
          are able to plug in whatever device they want, so any type of
          identifier (e.g. a client-id) is unreliable. Therefore the operator
          may decide to use an option inserted by a relay agent to differentiate
          between clients. In this particular deployment, the operator verified
          that the interface-id is unique for each customer facing
          interface. Therefore it is suitable for usage as reservation. However,
          only the first 6 bytes of the interface-id are interesting, because
          remaining bytes are either randomly changed or not unique between
          devices. Therefore the customer decided to use first 6 bytes of the
648 649 650
          interface-id option inserted by the relay agent. After adding "flex-id"
          host-reservation-identifiers goal can be achieved by using the
          following configuration:
Tomek Mrugalski's avatar
Tomek Mrugalski committed
651 652 653 654 655 656 657 658
<screen>
"Dhcp6": {
    "subnet6": [{ ..., // subnet definition starts here
    "reservations": [
        <userinput>"flex-id": "'port1234'"</userinput>, // value of the first 8 bytes of the interface-id
        "ip-addresses": [ "2001:db8::1" ]
    ],
    }], // end of subnet definitions
659
    "host-reservation-identifiers": ["duid", "flex-id"], // add "flex-id" to reservation identifiers
Tomek Mrugalski's avatar
Tomek Mrugalski committed
660 661 662 663
    "hooks-libraries": [
        {
            "library": "/path/libdhcp_flex_id.so",
            "parameters": {
664
                "identifier-expression": "<userinput>substring(relay6[0].option[18].hex,0,8)</userinput>"
Tomek Mrugalski's avatar
Tomek Mrugalski committed
665 666 667 668 669 670
            }
        },
        ...
    ]
}
</screen>
671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691
        </para>

        <para>
          NOTE: Care should be taken when adjusting the expression. If the
          expression changes, then all the flex-id values may change, possibly
          rendering all reservations based on flex-id unusable until they're
          manually updated. Therefore it is strongly recommended to start with
          the expression and a handful reservations, adjust the expression as
          needed and only after it was confirmed the expression does exactly
          what is expected out of it go forward with host reservations on any
          broader scale.
        </para>

        <para>
          flex-id values in host reservations can be specified in two
          ways. First, they can be expressed as hex string, e.g. bar string
          can be represented as 626174. Alternatively, it can be expressed
          as quoted value (using double and single quotes), e.g. "'bar'".
          The former is more convenient for printable characters, while hex
          string values are more convenient for non-printable characters.
        </para>
692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711
<screen>
"Dhcp6": {
    "subnet6": [{ ..., // subnet definition starts here
    "reservations": [
        <userinput>"flex-id": "01:02:03:04:05:06"</userinput>, // value of the first 8 bytes of the interface-id
        "ip-addresses": [ "2001:db8::1" ]
    ],
    }], // end of subnet definitions
    "host-reservation-identifiers": ["duid", "flex-id"], // add "flex-id" to reservation identifiers
    "hooks-libraries": [
        {
            "library": "/path/libdhcp_flex_id.so",
            "parameters": {
                "identifier-expression": "<userinput>vendor[4491].option[1026].hex</userinput>"
            }
        },
        ...
    ]
}
</screen>
712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732
      </section>

      <section id="host-cmds">
        <title>host_cmds: Host Commands</title>
        <para>
          This section describes a hook application that offers a number of new
          commands used to query and manipulate host reservations. Kea provides
          a way to store host reservations in a database. In many larger
          deployments it is useful to be able to manage that information while
          the server is running. This library provides management commands for
          adding, querying and deleting host reservations in a safe way without
          restarting the server.  In particular, it validates the parameters, so
          an attempt to insert incorrect data e.g. add a host with conflicting
          identifier in the same subnet will be rejected. Those commands are
          exposed via command channel (JSON over unix sockets) and Control Agent
          (JSON over RESTful interface). Additional commands and capabilities
          related to host reservations will be added in the future.
        </para>

        <para>Currently this library is only available to ISC customers with a
        support contract.</para>
733

734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758
        <para>
          Currently three commands are supported: reservation-add (which adds
          new host reservation), reservation-get (which returns existing
          reservation if specified criteria are matched) and reservation-del
          (which attempts to delete a reservation matching specified
          criteria). To use commands that change the reservation information
          (currently these are reservation-add and reservation-del, but this
          rule applies to other commands that may be implemented in the future),
          hosts database must be specified (see hosts-database description in
          <xref linkend="hosts-database-configuration4"/> and <xref
          linkend="hosts-database-configuration6"/>) and it must not operate in
          read-only mode. If the hosts-database is not specified or is running
          in read-only mode, the host_cmds library will load, but any attempts
          to use reservation-add or reservation-del will fail.
        </para>

        <para>
          Additional host reservation commands are planned in the future. For
          a description of envisaged commands, see
<ulink url="http://kea.isc.org/wiki/ControlAPIRequirements">Control API
Requirements </ulink> document.</para>

        <para>
          All commands are using JSON syntax. They can be issued either using
          control channel (see <xref linkend="ctrl-channel"/>) or via Control
759
          Agent (see <xref linkend="kea-ctrl-agent"/>).
760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807
        </para>

        <para>
          The library can be loaded in similar way as other hook libraries. It
          does not take any parameters. It supports both DHCPv4 and DHCPv6
          servers.
<screen>
"Dhcp6": { <userinput>
    "hooks-libraries": [
        {
            "library": "/path/libdhcp_host_cmds.so"
        }
        ...
    ] </userinput>
}
</screen>
        </para>

        <section>
          <title>reservation-add command</title>
        <para>
          <command>reservation-add</command> allows insertion of a new host.  It
          takes a set of arguments that vary depending on the nature of the host
          reservation. Any parameters allowed in the configuration file that
          pertain to host reservation are permitted here. For details regarding
          IPv4 reservations, see <xref linkend="host-reservation-v4"/> and <xref
          linkend="host-reservation-v6"/>. There is one notable addition. A
          <command>subnet-id</command> must be specified.  This parameter is
          mandatory, because reservations specified in the configuration file
          are always defined within a subnet, so the subnet they belong to is
          clear. This is not the case with reservation-add, therefore the
          subnet-id must be specified explicitly. An example command can be as
          simple as:
<screen>{
    "command": "reservation-add",
    "arguments": {
        <userinput>"reservation": {
            "subnet-id": 1,
            "hw-address": "1a:1b:1c:1d:1e:1f",
            "ip-address": "192.0.2.202"
        }</userinput>
    }
}</screen> but can also take many more parameters, for example:

<screen>
{
    "command": "reservation-add",
    "arguments": {
808
        <userinput>"reservation":
809
            {
810
                "subnet-id":1,
811 812 813 814 815 816 817 818 819 820 821 822
                "client-id": "01:0a:0b:0c:0d:0e:0f",
                "ip-address": "192.0.2.205",
                "next-server": "192.0.2.1",
                "server-hostname": "hal9000",
                "boot-file-name": "/dev/null",
                "option-data": [
                    {
                        "name": "domain-name-servers",
                        "data": "10.1.1.202,10.1.1.203"
                    }
                ],
                "client-classes": [ "special_snowflake", "office" ]
823
            }</userinput>
824 825
    }
}</screen>
826

827 828 829 830 831
Here is an example of complex IPv6 reservation:
<screen>
{
    "command": "reservation-add",
    "arguments": {
832
        <userinput>"reservation":
833
            {
834
                "subnet-id":1,
835 836 837 838 839 840 841 842 843 844 845 846 847 848 849
                "duid": "01:02:03:04:05:06:07:08:09:0A",
                "ip-addresses": [ "2001:db8:1:cafe::1" ],
                "prefixes": [ "2001:db8:2:abcd::/64" ],
                "hostname": "foo.example.com",
                "option-data": [
                    {
                        "name": "vendor-opts",
                        "data": "4491"
                    },
                    {
                        "name": "tftp-servers",
                        "space": "vendor-4491",
                        "data": "3000:1::234"
                    }
                ]
850
            }</userinput>
851 852
    }
}</screen>
853
        </para>
854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925

        <para>
          The command returns a status that indicates either a success (result
          0) or a failure (result 1). Failed command always includes text
          parameter that explains the cause of failure. Example results:
          <screen>{ "result": 0, "text": "Host added." }</screen> Example failure:
          <screen>{ "result": 1, "text": "Mandatory 'subnet-id' parameter missing." }</screen>
        </para>

        <para>
          As <command>reservation-add</command> is expected to store the host,
          hosts-database parameter must be specified in your configuration and
          the database must not run in read-only mode. In the future versions
          it will be possible to modify the reservations read from a
          configuration file. Please contact ISC if you are interested in this
          functionality.
        </para>
        </section>

        <section>
          <title>reservation-get command</title>
          <para><command>reservation-get</command> can be used to query the host
          database and retrieve existing reservations. There are two types of
          parameters this command supports: (subnet-id, address) or (subnet-id,
          identifier-type, identifier). The first type of query is used when the
          address (either IPv4 or IPv6) is known, but the details of the
          reservation aren't. One common use case of this type of query is to
          find out whether a given address is reserved or not. The second query
          uses identifiers. For maximum flexibility, Kea stores the host
          identifying information as a pair of values: type and the actual
          identifier. Currently supported identifiers are "hw-address", "duid",
          "circuit-id", "client-id" and "flex-id", but additional types may be
          added in the future. If any new identifier types are defined in the
          future, reservation-get command will support them
          automatically.</para>

          <para>
            An example command for getting a host reservation by (subnet-id,
            address) pair looks as follows:
<screen>
{
    "command": "reservation-get",
    "arguments": {
        "subnet-id": 1,
        "ip-address": "192.0.2.202"
    }
}</screen>

An example query by (subnet-id, identifier-type, identifier) looks as follows:
<screen>
{
    "command": "reservation-get",
    "arguments":
        "subnet-id": 4,
        "identifier-type": "hw-address",
        "identifier": "01:02:03:04:05:06"
    }
}</screen>

          </para>
          <para><command>reservation-get</command> typically returns result 0
          when the query was conducted properly. In particular, 0 is returned
          when the host was not found. If the query was successful a number
          of host parameters will be returned. An example of a query that
          did not find the host looks as follows:
<screen>{ "result": 0, "text": "Host not found." }</screen>

An example result returned when the host was found:
<screen>{
  "arguments": {
    "boot-file-name": "bootfile.efi",
    "client-classes": [
926

927 928 929 930 931 932
    ],
    "hostname": "somehost.example.org",
    "hw-address": "01:02:03:04:05:06",
    "ip-address": "192.0.2.100",
    "next-server": "192.0.0.2",
    "option-data": [
933

934 935 936 937 938 939 940 941 942 943 944
    ],
    "server-hostname": "server-hostname.example.org"
  },
  "result": 0,
  "text": "Host found."
}</screen>

An example result returned when the query was malformed:<screen>
{ "result": 1, "text": "No 'ip-address' provided and 'identifier-type'
                        is either missing or not a string." }</screen>
</para>
945

946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989
        </section>

        <section>
          <title>reservation-del command</title>
          <para><command>reservation-del</command> can be used to delete a
          reservation from the host database. There are two types of parameters
          this command supports: (subnet-id, address) or (subnet-id,
          identifier-type, identifier). The first type of query is used when the
          address (either IPv4 or IPv6) is known, but the details of the
          reservation aren't. One common use case of this type of query is to
          remove a reservation (e.g. you want a specific address to no longer be
          reserved). The second query uses identifiers. For maximum flexibility,
          Kea stores the host identifying information as a pair of values: type
          and the actual identifier. Currently supported identifiers are
          "hw-address", "duid", "circuit-id", "client-id" and "flex-id", but
          additional types may be added in the future. If any new identifier
          types are defined in the future, reservation-get command will support
          them automatically.</para>

          <para>
            An example command for deleting a host reservation by (subnet-id,
            address) pair looks as follows:
<screen>
{
    "command": "reservation-del",
    "arguments": {
        "subnet-id": 1,
        "ip-address": "192.0.2.202"
    }
}</screen>

An example deletion by (subnet-id, identifier-type, identifier) looks as follows:
<screen>
{
    "command": "reservation-del",
    "arguments":
        "subnet-id": 4,
        "identifier-type": "hw-address",
        "identifier": "01:02:03:04:05:06"
    }
}</screen>
          </para>
          <para>
            <command>reservation-del</command> returns result 0 when the host
990
            deletion was successful or 1 if it was not. A descriptive text is
991 992 993 994 995 996 997
            provided in case of error. Example results look as follows:
<screen>
{
    "result": 1,
    "text": "Host not deleted (not found)."
}</screen>

998
<screen>
999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011
{
    "result": 0,
    "text": "Host deleted."
}</screen>

<screen>
{
    "result": 1,
    "text": "Unable to delete a host because there is no hosts-database
             configured."
}</screen>
          </para>
        </section>
1012 1013
      </section>

1014 1015 1016 1017 1018 1019 1020
      <!-- ================================================================= -->
      <!-- === lease_cmds ================================================== -->
      <!-- ================================================================= -->

      <section id="lease-cmds">
        <title>lease_cmds: Lease Commands</title>
        <para>
1021
          This section describes the hook library that offers a number of new
1022 1023
          commands used to manage leases. Kea provides a way to store lease
          information in several backends (memfile, MySQL, PostgreSQL and
1024
          Cassandra). This library provides a unified interface that can
1025 1026 1027 1028 1029 1030
          manipulate leases in an unified, safe way. In particular, it allows
          things previously impossible: manipulate leases in memfile while Kea
          is running, sanity check changes, check lease existence and remove all
          leases belonging to specific subnet. It can also catch more obscure
          errors, like adding a lease with subnet-id that does not exist in the
          configuration or configuring a lease to use an address that is outside
1031
          of the subnet to which it is supposed to belong.
1032 1033 1034 1035
        </para>

        <para>There are many use cases when an administrative command may be
        useful: during migration between servers (possibly even between
1036
        different vendors), when a certain network is being retired, when a
1037
        device has been disconnected and the sysadmin knows for sure that it
1038
        will not be coming back. The "get" queries may be useful for automating
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051
        certain management and monitoring tasks. They can also act as
        preparatory steps for lease updates and removals.</para>

        <para>
          This library provides the following commands:
          <itemizedlist>
            <listitem>
              <para><command>lease4-add</command> - adds new IPv4 lease;</para>
            </listitem>
            <listitem>
              <para><command>lease6-add</command> - adds new IPv6 lease;</para>
            </listitem>
            <listitem>
1052 1053
              <para><command>lease4-get</command> - checks if an IPv4 lease with
              the specified parameters exists and returns it if it does;</para>
1054 1055
            </listitem>
            <listitem>
1056 1057
              <para><command>lease6-get</command> - checks if an IPv6 lease with
              the specified parameters exists and returns it if it does;</para>
1058 1059 1060
            </listitem>
            <listitem>
              <para><command>lease4-del</command> - attempts to delete an IPv4
1061
              lease with the specified parameters;</para>
1062 1063 1064
            </listitem>
            <listitem>
              <para><command>lease6-del</command> - attempts to delete an IPv6
1065
              lease with the specified parameters;</para>
1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094
            </listitem>
            <listitem>
              <para><command>lease4-update</command> - updates an IPv4 lease;</para>
            </listitem>
            <listitem>
              <para><command>lease6-update</command> - updates an IPv6 lease;</para>
            </listitem>
            <listitem>
              <para><command>lease4-wipe</command> - removes all leases from a
              specific IPv4 subnet;</para>
            </listitem>
            <listitem>
              <para><command>lease6-wipe</command> - removes all leases from a
              specific IPv6 subnet;</para>
            </listitem>
          </itemizedlist>

        </para>

        <para>Lease commands library is part of the open source code and is
        available to every Kea user.</para>

        <para>
          All commands are using JSON syntax. They can be issued either using
          control channel (see <xref linkend="ctrl-channel"/>) or via Control
          Agent (see <xref linkend="kea-ctrl-agent"/>).
        </para>

        <para>
1095
          The library can be loaded in the same way as other hook libraries. It
1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117
          does not take any parameters. It supports both DHCPv4 and DHCPv6
          servers.
<screen>
"Dhcp6": { <userinput>
    "hooks-libraries": [
        {
            "library": "/path/libdhcp_lease_cmds.so"
        }
        ...
    ] </userinput>
}
</screen>
        </para>

        <section>
          <title>lease4-add, lease6-add commands</title>
        <para>
          <command>lease4-add</command> and <command>lease6-add</command>
          commands allow creation of a new lease. Typically Kea creates a lease
          on its own, when it first sees a new device. However, sometimes it may
          be convenient to create the lease administratively. The
          <command>lease4-add</command> command requires at least three
1118 1119
          parameters: an IPv4 address, a subnet-id and an identifier: hardware
          (MAC) address. The simplest successful call might look as follows:
1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132
<screen>
{
    "command": "lease4-add",
    "arguments": {
        "subnet-id": 44,
        "ip-address": "192.0.2.202",
        "hw-address": "1a:1b:1c:1d:1e:1f"
    }
}
</screen>
        </para>

        <para><command>lease6-add</command> command requires four
1133
        paramaters: an IPv6 address, a subnet-id, and IAID value
1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158
        (identity association identifier, a value sent by clients) and
        a DUID:
<screen>
{
    "command": "lease6-add",
    "arguments": {
        "subnet-id": 66,
        "ip-address": "2001:db8::3",
        "duid": "1a:1b:1c:1d:1e:1f:20:21:22:23:24",
        "iaid": 1234
    }
}</screen>

<command>lease6-add</command> can be also used to add leases for IPv6
prefixes. In this case there are two parameters that must be
specified: type (set to value of &quot;IA_PD&quot;) and a prefix
length. The actual prefix is set using ip-address field. For example,
to configure a lease for prefix 2001:db8:abcd::/48, the following
command can be used:

<screen>
{
    "command": "lease6-add",
    "arguments": {
        "subnet-id": 66,
1159
        "type": "IA_PD",
1160 1161 1162 1163 1164 1165 1166 1167 1168 1169
        "ip-address": "2001:db8:abcd::",
        "prefix-len": 48,
        "duid": "1a:1b:1c:1d:1e:1f:20:21:22:23:24",
        "iaid": 1234
    }
}</screen>

The commands can take a number of additional optional parameters:
          <itemizedlist>
            <listitem>
1170
              <para><command>valid-lft</command> - specifies the lifetime of the
1171
              lease, expressed in seconds. If not specified, the value
1172
              configured in the subnet related to specified subnet-id is
1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184
              used.</para>
            </listitem>
            <listitem>
              <para><command>expire</command> - timestamp of the lease
              expiration time, expressed in unix format (seconds since 1 Jan
              1970). If not specified, the default value is now + valid
              lifetime.</para>
            </listitem>
            <listitem>
              <para><command>fqdn-fwd</command> - specifies whether the lease
              should be marked as if forward DNS update was conducted. Note this
              only affects the lease parameter and the actual DNS update will
1185
              not be conducted at the lease insertion time. If configured, a DNS
1186 1187 1188 1189 1190 1191 1192 1193 1194
              update to remove the A or AAAA records will be conducted when the
              lease is removed due to expiration or being released by a
              client. If not specifed, the default value is false. Hostname
              parameter must be specified in fqdn-fwd is set to true.</para>
            </listitem>
            <listitem>
              <para><command>fqdn-rev</command> - specifies whether the lease
              should be marked as if reverse DNS update was conducted. Note this
              only affects the lease parameter and the actual DNS update will
1195
              not be conducted at the lease insertion time. If configured, a DNS
1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218
              update to remove the PTR record will be conducted when the lease
              is removed due to expiration or being released by a client. If not
              specifed, the default value is false. Hostname parameter must be
              specified in fqdn-fwd is set to true.</para>
            </listitem>
            <listitem>
              <para><command>hostname</command> - specifies the hostname to be
              associated with this lease. Its value must be non-empty if either
              fqdn-fwd or fwdn-rev are set to true. If not specified, the
              default value is an empty string.</para>
            </listitem>
            <listitem>
              <para><command>hw-address</command> - hardware (MAC) address can
              be optionally specified for IPv6 lease. It is mandatory parameter
              for IPv4 lease.</para>
            </listitem>
            <listitem>
              <para><command>client-id</command> - client identifier is an
              optional parameter that can be specified for IPv4 lease.</para>
            </listitem>
            <listitem>
              <para><command>preferred-lft</command> - Preferred lifetime is an
              optional parameter for IPv6 leases. If not specified, the value
1219
              configured for the subnet corresponding to the specified subnet-id
1220 1221 1222 1223 1224
              is used. This parameter is not used in IPv4.</para>
            </listitem>
          </itemizedlist>
        </para>

1225
        <para>Here's an example of more complex lease addition:
1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263

<screen>
{
    "command": "lease6-add",
    "arguments": {
        "subnet-id": 66,
        "ip-address": "2001:db8::3",
        "duid": "01:02:03:04:05:06:07:08",
        "iaid": 1234,
        "hw-address": "1a:1b:1c:1d:1e:1f",
        "preferred-lft": 500,
        "valid-lft": 1000,
        "expire": 12345678,
        "fqdn-fwd": true,
        "fqdn-rev": true,
        "hostname": "urania.example.org"
    }
}
</screen>
        </para>

        <para>
          The command returns a status that indicates either a success (result
          0) or a failure (result 1). Failed command always includes text
          parameter that explains the cause of failure. Example results:
          <screen>{ "result": 0, "text": "Lease added." }</screen> Example failure:
          <screen>{ "result": 1, "text": "missing parameter 'ip-address' (&lt;string&gt;:3:19)" }</screen>
        </para>


        <section>
          <title>lease4-get, lease6-get commands</title>
          <para><command>lease4-get</command> or <command>lease6-get</command>
          can be used to query the lease database and retrieve existing
          leases. There are two types of parameters the
          <command>lease4-get</command> supports: (address) or (subnet-id,
          identifier-type, identifier). There are two types for
          <command>lease6-get</command>: (address,type) or (subnet-id,
1264
          identifier-type, identifier, IAID, type). The first type of query is
1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368
          used when the address (either IPv4 or IPv6) is known, but the details
          of the lease aren't. One common use case of this type of query is to
          find out whether a given address is being used or not. The second
          query uses identifiers. For maximum flexibility, Kea stores the host
          identifying information as a pair of values: type and the actual
          identifier. Currently supported identifiers are "hw-address", "duid",
          "circuit-id", "client-id" and "flex-id", but additional types may be
          added in the future. If any new identifier types are defined in the
          future, reservation-get command will support them
          automatically.</para>

          <para>
            An example <command>lease4-get</command> command for getting a lease
            by an IPv4 address looks as follows:
<screen>
{
    "command": "lease4-get",
    "arguments": {
        "ip-address": "192.0.2.1"
    }
}
</screen>
          </para>

          <para>An example of the <command>lease6-get</command> query
          looks as follows:
<screen>
{
  "command": "lease6-get",
  "arguments": {
    "ip-address": "2001:db8:1234:ab::",
    "type": "IA_PD"
  }
}</screen>
          </para>

          <para>An example query by (subnet-id, identifier-type,
          identifier) for IPv4 lease looks as follows:
<screen>
{
    "command": "lease4-get",
    "arguments": {
        "identifier-type": "hw-address",
        "identifier": "08:08:08:08:08:08",
        "subnet-id": 44
    }
}</screen>

          </para>

          <para>An example query by (subnet-id, identifier-type,
          identifier, iaid, type) for IPv6 lease looks as follows:
<screen>
{
    "command": "lease4-get",
    "arguments": {
        "identifier-type": "duid",
        "identifier": "08:08:08:08:08:08",
        "iaid": 1234567,
        "type": "IA_NA",
        "subnet-id": 44
    }
}</screen>
The type is an optional parameter. Supported values are: IA_NA
(non-temporary address) and IA_PD (IPv6 prefix) are supported.
If not specified, IA_NA is assumed.
          </para>

          <para><command>leaseX-get</command> returns a result that indicates a
          result of the operation and lease details, if found. It has one of the
          following values: 0 (success), 1 (error) or 2 (empty). The empty
          result means that a query has been completed properly, but the object
          (a lease in this case) has not been found. The lease parameters, if
          found, are returned as arguments.
          </para>

          <para>
An example result returned when the host was found:
<screen>{
  "arguments": {
    "client-id": "42:42:42:42:42:42:42:42",
    "cltt": 12345678,
    "fqdn-fwd": false,
    "fqdn-rev": true,
    "hostname": "myhost.example.com.",
    "hw-address": "08:08:08:08:08:08",
    "ip-address": "192.0.2.1",
    "state": 0,
    "subnet-id": 44,
    "valid-lft": 3600
  },
  "result": 0,
  "text": "IPv4 lease found."
}</screen>
</para>

        </section>

        <section>
          <title>lease4-del, lease6-del commands</title>
          <para><command>leaseX-del</command> can be used to delete a lease from
          the lease database. There are two types of parameters this command
          supports, similar to leaseX-get commands: (address) for both v4 and
          v6, (subnet-id, identifier-type, identifier) for v4 and (subnet-id,
1369
          identifier-type, identifier, type, IAID) for v6. The first type of
1370
          query is used when the address (either IPv4 or IPv6) is known, but the
1371
          details of the lease are not. One common use case of this type of query
1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403
          is to remove a lease (e.g. you want a specific address to no longer be
          used, no matter who may use it). The second query uses
          identifiers. For maximum flexibility, this interface uses identifiers
          as a pair of values: type and the actual identifier. Currently
          supported identifiers are "hw-address" and "duid", but additional
          types may be added in the future. </para>

          <para>
            An example command for deleting a host reservation by address looks
            as follows:
<screen>
{
    "command": "lease4-del",
    "arguments": {
        "ip-address": "192.0.2.202"
    }
}</screen>

An example IPv4 lease deletion by (subnet-id, identifier-type, identifier) looks
as follows:

<screen>{
  "command": "lease4-del",
  "arguments": {
    "identifier": "08:08:08:08:08:08",
    "identifier-type": "hw-address",
    "subnet-id": 44
  }
}</screen>
          </para>

          <para><command>leaseX-get</command> returns a result that
1404
          indicates a outcome of the operation. It has one of the
1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415
          following values: 0 (success), 1 (error) or 2 (empty). The
          empty result means that a query has been completed properly,
          but the object (a lease in this case) has not been found.
          </para>
        </section>

        <section>
          <title>lease4-update, lease6-update commands</title>
          <para><command>lease4-update</command> and
          <command>lease6-update</command> commands can be used to update
          existing leases. Since all lease database backends are indexed by IP
1416 1417
          addresses, it is not possible to update an address. All other fields
          may be updated. If an address needs to be changed, please use
1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439
          <command>leaseX-del</command> followed by
          <command>leaseX-add</command> commands.</para>

          <para>To use <command>leaseX-update</command> the lease must
          be present in the lease database. If the lease is not there,
          an error will be returned. Please use
          <command>leaseX-add</command> to add new leases. You may
          check if a lease is present using
          <command>leaseX-get</command>, if needed.</para>

          <para>
            An example command updating IPv6 lease looks as follows:
<screen>{
  "command": "lease4-update",
  "arguments": {
    "ip-address": "192.0.2.1",
    "hostname": "newhostname.example.org",
    "hw-address": "1a:1b:1c:1d:1e:1f",
    "subnet-id": 44
  }
}</screen>
          </para>
1440

1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459
          <para>
            An example command updating IPv6 lease looks as follows:
<screen>{
  "command": "lease6-update",
  "arguments": {
    "ip-address": "2001:db8::1",
    "duid": "88:88:88:88:88:88:88:88",
    "iaid": 7654321,
    "hostname": "newhostname.example.org",
    "subnet-id": 66
  }
}</screen>
          </para>
        </section>

        <section>
          <title>lease4-wipe, lease6-wipe commands</title>
          <para><command>lease4-wipe</command> and
          <command>lease6-wipe</command> are designed to remove all
1460
          leases associated with a given subnet. This administrative
1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484
          task is expected to be used when existing subnet is being
          retired. Note that the leases are not properly expired,
          there are no DNS updates conducted, no log messages and
          hooks are not called for leases being removed.</para>

          <para>An example of <command>lease4-wipe</command> looks as follows:
<screen>{
  "command": "lease4-wipe",
  "arguments": {
    "subnet-id": 44
  }
}</screen>
          </para>

          <para>An example of <command>lease6-wipe</command> looks as follows:
<screen>{
  "command": "lease6-wipe",
  "arguments": {
    "subnet-id": 66
  }
}</screen>
          </para>

          <para>The commands return a textual description of the
1485
          number of leases removed and 0 (success) status code if any
1486 1487 1488 1489 1490 1491 1492 1493
          leases were removed and 2 (empty) if there were no
          leases. Status code 1 (error) may be returned in case the
          parameeters are incorrect or some other exception is
          encountered.</para>

          <para>Note: not all backends support this command.</para>
        </section>
      </section>
1494
    </section>
1495

1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559
      <section id="subnet-cmds">
        <title>subnet_cmds: Subnet Commands</title>
        <para>
          This section describes a hook application that offers a number of new
          commands used to query and manipulate subnet configurations in Kea.
          This application is very useful in deployments with a large number of
          subnets being managed by the DHCP servers and when the subnets are
          frequently updated. The commands offer lightweight approach for
          manipulating subnets without a need to fully reconfigure the server
          and without affecting existing servers' configurations.
        </para>

        <para>Currently this library is only available to ISC customers with a
        support contract.</para>

        <para>The following commands are currently supported:
        <itemizedlist mark='bullet'>
          <listitem>
            <simpara><command>subnet4-list/subnet6-list</command>: lists all configured subnets
            </simpara>
          </listitem>
          <listitem>
          <simpara>
            <command>subnet4-get/subnet6-get</command>: retrieves detailed information about a selected subnet
          </simpara>
          </listitem>
          <listitem>
          <simpara>
            <command>subnet4-add/subnet6-add</command>: adds new subnet into server's configuration
          </simpara>
          </listitem>
          <listitem>
          <simpara>
            <command>subnet4-del/subnet6-del</command>: removes a subnet from the server's configuration
          </simpara>
          </listitem>
        </itemizedlist>
        </para>

        <section>
          <title>subnet4-list command</title>
          <para>
            This command is used to list all currently configured subnets. The
            subnets are returned in a brief form, i.e. a subnet identifier
            and subnet prefix is included for each subnet. In order to retrieve
            the detailed information about the subnet the
            <command>subnet4-get</command> should be used.
          </para>
          <para>
            This command has the simple structure:
<screen>
{
    "command": "subnet4-list"
}
</screen>
          </para>
          <para>
            The list of subnets returned as a result of this command is returned
            in the following format:
<screen>
{
    "result": 0,
    "text": "2 IPv4 subnets found",
    "arguments": {
1560
    "subnets": [
1561
        {
1562
            "id": 10,
1563 1564 1565
            "subnet": "10.0.0.0/8"
        },
        {
1566
            "id": 100,
1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603
            "subnet": "192.0.2.0/24"
        }
    ]
}
</screen>
          </para>
          <para>
            If no IPv4 subnets are found, an error code is returned along with
            the error description.
          </para>
        </section>

        <section>
          <title>subnet6-list command</title>
          <para>
            This command is used to list all currently configured subnets. The
            subnets are returned in a brief form, i.e. a subnet identifier
            and subnet prefix is included for each subnet. In order to retrieve
            the detailed information about the subnet the
            <command>subnet6-get</command> should be used.
          </para>
          <para>
            This command has the simple structure:
<screen>
{
    "command": "subnet6-list"
}
</screen>
          </para>
          <para>
            The list of subnets returned as a result of this command is returned
            in the following format:
<screen>
{
    "result": 0,
    "text": "2 IPv6 subnets found",
    "arguments": {
1604
    "subnets": [
1605
        {
1606
            "id": 11,
1607 1608 1609
            "subnet": "2001:db8:1::/64"
        },
        {
1610
            "id": 233,
1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634
            "subnet": "3000::/16"
        }
    ]
}
</screen>
          </para>
          <para>
            If no IPv6 subnets are found, an error code is returned along with
            the error description.
          </para>
        </section>

      <section>
        <title>subnet4-get command</title>
        <para>This command is used to retrieve detailed information about the
        specified subnet. This command usually follows the
        <command>subnet4-list</command>, which is used to discover available
        subnets with their respective subnet identifiers and prefixes. Any of
        those parameters can be then used in <command>subnet4-get</command>
        to fetch subnet information:
<screen>
{
    "command": "subnet4-get",
    "arguments": {
1635
        "id": 10
1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655
    }
}</screen>

or

<screen>
{
    "command": "subnet4-get",
    "arguments": {
        "subnet": "10.0.0.0/8"
    }
}
</screen>
        </para>

        <para>
          If the subnet exists the response will be similar to this:
<screen>
{
    "result": 0,
1656
    "text": "Info about IPv4 subnet 10.0.0.0/8 (id 10) returned",
1657
    "arguments": {
1658
        "subnets": [
1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686
            {
                "subnet": "10.0.0.0/8",
                "id": 1,
                "option-data": [
                    ....
                ]
                ...
            }
        ]
    }
}

</screen>
        </para>
      </section>

      <section>
        <title>subnet6-get command</title>
        <para>This command is used to retrieve detailed information about the
        specified subnet. This command usually follows the
        <command>subnet6-list</command>, which is used to discover available
        subnets with their respective subnet identifiers and prefixes. Any of
        those parameters can be then used in <command>subnet6-get</command>
        to fetch subnet information:
<screen>
{
    "command": "subnet6-get",
    "arguments": {
1687
        "id": 11
1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705
    }
}
</screen>

or

<screen>
{
    "command": "subnet6-get",
    "arguments": {
        "subnet": "2001:db8:1::/64"
    }
}</screen>

If the subnet exists the response will be similar to this:
<screen>
{
    "result": 0,
1706
    "text": "Info about IPv6 subnet 2001:db8:1::/64 (id 11) returned",
1707
    "arguments": {
1708
        "subnets": [
1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719
            {
                "subnet": "2001:db8:1::/64",
                "id": 1,
                "option-data": [
                    ...
                ]
                ....
            }
        ]
    }
}
1720
</screen>
1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743
        </para>
      </section>

      <section>
        <title>subnet4-add</title>
        <para>
          This command is used to create and add new subnet to the existing
          server configuration. This operation has no impact on other
          subnets. The subnet identifier must be specified and must be
          unique among all subnets. If the identifier or a subnet prefix is
          not unique an error is reported and the subnet is not added.
        </para>
        <para>
          The subnet information within this command has the same structure
          as the subnet information in the server configuration file with the
          exception that static host reservations must not be specified
          within <command>subnet4-add</command>. The commands described in
          <xref linkend="host-cmds"/> should be used to add, remove and
          modify static reservations.
<screen>
{
    "command": "subnet4-add",
    "arguments": {
1744
        "subnets": [ {
1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760
            "id": 123,
            "subnet": "10.20.30.0/24",
            ...
        } ]
    }
}
</screen>
        </para>

        <para>
          The response to this command has the following structure:
<screen>
{
    "result": 0,
    "text": "IPv4 subnet added",
    "arguments": {
1761
        "subnets": [
1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785