summaryrefslogtreecommitdiff
path: root/doc/guide/hooks.xml
blob: cd16c7d550e61394ee6e8a5ab54f70250ed522a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
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
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
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
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
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
759
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
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
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
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
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
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
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
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
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
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
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
1264
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
1369
1370
1371
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
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
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
1560
1561
1562
1563
1564
1565
1566
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
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
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
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
<!--
 - Copyright (C) 2014-2018 Internet Systems Consortium, Inc. ("ISC")
 -
 - This Source Code Form is subject to the terms of the Mozilla Public
 - License, v. 2.0. If a copy of the MPL was not distributed with this
 - file, You can obtain one at http://mozilla.org/MPL/2.0/.
-->

<!-- Converted by db4-upgrade version 1.1 -->
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="hooks-libraries">

    <title>Hooks Libraries</title>
    <section xml:id="hooks-libraries-introduction">
      <title>Introduction</title>
      <para>
      Although Kea offers a lot of flexibility, there may be cases where
      its behavior needs customization.  To accommodate this possibility,
      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>
        The hooks concept also allows keeping the core Kea code reasonably small
        by moving features that some, but not all users find useful to external
        libraries. People who don't need specific functionality simply don't
        load the libraries.
      </para>
      <para>
      Hooks libraries are loaded by 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
      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.
      </para>
      <para>
      The next section describes how to configure hooks libraries. If you
      are interested in writing your own hooks library, information can be
      found in the <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://jenkins.isc.org/job/Kea_doc/doxygen">Kea
      Developer's Guide</link>.
      </para>

      <para>
        Note that some libraries are available under different licenses.
      </para>
      <para>
        Note that some libraries may require additional dependencies and/or
        compilation switches to be enabled, e.g. Radius library introduced in
        Kea 1.4 requires FreeRadius-client library to be present. If
        --with-free-radius option is not specified, the Radius library will not
        be built.
      </para>
    </section> <!-- end Introduction -->

    <section>
      <title>Installing Hook packages</title>

      <note>
        <simpara>The installation procedure has changed in 1.4.0. Kea 1.3.0 and
        earlier needed special switches passed to configure script to detect the
        hook libraries. Please see this KB article: <uri
        xmlns:xlink="http://www.w3.org/1999/xlink"
        xlink:href="https://kb.isc.org/article/AA-01587">https://kb.isc.org/article/AA-01587</uri>
        .</simpara>
      </note>

      <para>Some hook packages are included in the base Kea sources. There is no
      need to do anything special to compile or install them, they are covered
      by the usual building and installation procedure. ISC also provides several
      additional hooks in form of various packages. All of those packages follow
      the same installation procedure that is similar to base Kea, but has
      several additional steps. For your convenience, the whole procedure is
      described here. Please refer to <xref linkend="installation"/> for general
      overview.</para>

      <para>
        1. Download the package. You will receive detailed instructions how to
        get it separately. This will be a file with a name similar to
        kea-premium-1.4.0.tar.gz. Your name may differ depending on which
        package you got.
      </para>

      <para>
        2. If you have the sources for the corresponding version of the
        open-source Kea package still on your system (from when you installed
        Kea), skip this step.  Otherwise extract the Kea source from the
        original tarball you downloaded.  For example, if you downloaded Kea
        1.4.0., you should have a tarball called kea-1.4.0.tar.gz on your
        system. Unpack this tarball:

<screen>
$ <userinput>tar zxvf kea-1.4.0.tar.gz</userinput>
</screen>

        This will unpack the tarball into the kea-1.4.0 subdirectory of your
        current working directory.
      </para>

      <para>
        3. Unpack the Kea premium tarball into the directory into which Kea was
        unpacked. For example, assuming that you followed step 2 and that Kea
        1.4.0 has been unpacked into a kea-1.4.0 subdirectory and that the Kea
        premium tarball is in your current directory, the following steps will
        unpack the premium tarball into the correct location:
<screen>
  $ <userinput>cd kea-1.4.0</userinput>
  $ <userinput>tar xvf ../kea-premium-1.4.0.tar.gz</userinput>
</screen>
        Note that unpacking the Kea premium package will put the files into a
        directory named premium. Regardless of the name of your package, the
        directory will always be called premium, just its content may vary.
      </para>

      <para>
        4. Run autoreconf tools. This step is necessary to update Kea's build
        script to include additional directory. If this tool is not already
        available on your system, you need to install automake and autoconf
        tools. To generate configure script, please use:
<screen>
  $ <userinput>autoreconf -i</userinput>
</screen>
      </para>
      <para>
        5. Rerun configure, using the same configure options as you used when
        originally building Kea. You can check if configure has detected the
        premium package by inspecting the summary printed when it exits.  The
        first section of the output should look something like:
<screen>
Package:
  Name:            kea
  Version:         1.4.0
  Extended version:1.4.0 (tarball)
  OS Family:       Linux
  Using GNU sed:   yes
  Premium package: yes
  Included Hooks:  forensic_log flex_id host_cmds
</screen>

The last line indicates which specific hooks were detected. Note that some
hooks may require its own dedicated switches, e.g. radius hook requires
extra switches for FreeRADIUS. Please consult later sections of this
chapter for details.
      </para>

      <para>
        6. Rebuild Kea
<screen>
  $ <userinput>make</userinput>
</screen>
If your machine has multiple CPU cores, interesting option to consider here
is -j X, where X is the number of available cores.
      </para>

      <para>
        7. Install Kea sources together with hooks:
<screen>
$ <userinput>sudo make install</userinput>
</screen>
      Note that as part of the installation procedure, the install script will
      eventually venture into premium/ directory and will install additional
      hook libraries and associated files.
      </para>
      <para>
      The installation location of the hooks libraries depends whether you
      specified --prefix parameter to the configure script. If you did not,
      the default location will be /usr/local/lib/hooks. You can verify the
      libraries are installed properly with this command:
<screen>
$ <userinput>ls -l /usr/local/lib/hooks/*.so</userinput>
/usr/local/lib/hooks/libdhcp_flex_id.so
/usr/local/lib/hooks/libdhcp_host_cmds.so
/usr/local/lib/hooks/libdhcp_lease_cmds.so
/usr/local/lib/hooks/libdhcp_legal_log.so
/usr/local/lib/hooks/libdhcp_subnet_cmds.so
</screen>
      The exact list you see will depend on the packages you have.
      If you specified directory via --prefix, the hooks libraries
      will be located in {prefix directory}/lib/hooks.
      </para>
    </section>

    <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
      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:
<screen>
<userinput>"Dhcp4": {
    :
    "hooks-libraries": [
        {
            "library": "/opt/charging.so"
        },
        {
            "library": "/opt/local/notification.so",
            "parameters": {
                "mail": "spam@example.com",
                "floor": 13,
                "debug": false,
                "users": [ "alice", "bob", "charlie" ],
                "languages": {
                    "french": "bonjour",
                    "klingon": "yl'el"
                }
            }
        }
    ]
    :
}</userinput>
</screen>
      </para>

      <note><para>
        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
        a library.  The change was made in Kea 1.0 to facilitate the
        specification of library-specific parameters, a capability
        available in Kea 1.1.0 onwards. Libraries should allow a parameter
        entry where to put comments as it is done for many configuration
        scopes with comment and user context.
      </para></note>

        <note>
          <para>
          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.
          </para>
        </note>

      <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
        explained in detail in the Hooks Developer's Guide in the "Configuring
        Hooks Libraries" section.
      </para>

      <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.
          </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>
        </itemizedlist>
      </para>
      <para>
      At the present time, only the kea-dhcp4 and kea-dhcp6 processes support
      hooks libraries.
      </para>
    </section>

    <section>
      <title>Available Hooks Libraries</title>
      <para>
      As described above, the hooks functionality provides a way to customize
      a Kea server without modifying the core code.  ISC has chosen to take
      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.
      </para>

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

      <para>The following table provides a list of libraries currently available
      from ISC. It is important to pay attention to which libraries may be loaded
      by which Kea processes. It is a common mistake to configure the <command>
      kea-ctrl-agent</command> process to load libraries that should, in fact,
      be loaded by the <command>kea-dhcp4 </command> or <command>kea-dhcp6</command>
      processes.  If a library from ISC doesn't work as expected, please make sure
      that it has been loaded by the correct process per the table below.

      <warning>
        <para>
          While the Kea Control Agent includes the "hooks" functionality,
          (i.e. hooks libraries can be loaded by this process), none of ISC's
          current hooks libraries should be loaded by the Control Agent.
        </para>
      </warning>

        <table frame="all" xml:id="hook-libs">
          <title>List of available hooks libraries</title>
          <tgroup cols="3">
          <colspec colname="name"/>
          <colspec colname="avail"/>
          <colspec colname="module"/>
          <colspec colname="description"/>
          <thead>
            <row>
              <entry>Name</entry>
              <entry>Availability</entry>
              <entry>Since</entry>
              <entry>Load by process</entry>
              <entry>Description</entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry>user_chk</entry>
              <entry>Kea sources</entry>
              <entry>Kea 0.8</entry>
              <entry>
                <simplelist>
                  <member>kea-dhcp4</member>
                  <member>kea-dhcp6</member>
                </simplelist>
              </entry>
              <entry>Reads known users list from a file. Unknown users
              will be assigned a
              lease from the last subnet defined in the configuration file,
              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>
            </row>
            <row>
              <entry>Forensic Logging</entry>
              <entry>Support customers</entry>
              <entry>Kea 1.1.0</entry>
              <entry>
                <simplelist>
                  <member>kea-dhcp4</member>
                  <member>kea-dhcp6</member>
                </simplelist>
              </entry>
              <entry>This library provides hooks that record a detailed log of
              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
              a different set of information, you may use it as a template or
              example and create your own custom logging hooks.</entry>
            </row>
            <row>
              <entry>Flexible Identifier</entry>
              <entry>Support customers</entry>
              <entry>Kea 1.2.0</entry>
              <entry>
                <simplelist>
                  <member>kea-dhcp4</member>
                  <member>kea-dhcp6</member>
                </simplelist>
              </entry>
              <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
              or DUID in DHCPv6. However, there are sometimes scenarios 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
              hook application. It allows defining an expression, similar to
              the one used in client classification,
              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.
              </entry>
            </row>
            <row>
              <entry>Host Commands</entry>
              <entry>Support customers</entry>
              <entry>Kea 1.2.0</entry>
              <entry>
                <simplelist>
                  <member>kea-dhcp4</member>
                  <member>kea-dhcp6</member>
                </simplelist>
              </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>
            <row>
              <entry>Subnet Commands</entry>
              <entry>Support customers</entry>
              <entry>Kea 1.3.0</entry>
              <entry>
                <simplelist>
                  <member>kea-dhcp4</member>
                  <member>kea-dhcp6</member>
                </simplelist>
              </entry>
              <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
              or restart. This hooks library allows for incremental changes
              to the subnet configuration such as: adding a subnet, removing
              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>

            <row>
              <entry>Lease Commands</entry>
              <entry>Kea sources</entry>
              <entry>Kea 1.3.0</entry>
              <entry>
                <simplelist>
                  <member>kea-dhcp4</member>
                  <member>kea-dhcp6</member>
                </simplelist>
              </entry>
              <entry>The lease commands hook library offers a number of new
              commands used to manage leases. Kea provides a way to store lease
              information in various backends: memfile, MySQL, PostgreSQL and
              Cassandra. This library provides a unified interface that can
              manipulate leases in an unified, safe way. In particular, it
              allows: 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 of the subnet to which it is supposed to belong.
              It provides a way to manage user contexts associated with leases.
              </entry>
            </row>

            <row>
              <entry>High Availability</entry>
              <entry>Kea sources</entry>
              <entry>Kea 1.4.0</entry>
              <entry>
                <simplelist>
                  <member>kea-dhcp4</member>
                  <member>kea-dhcp6</member>
                </simplelist>
              </entry>
              <entry>Minimizing a risk of DHCP service unavailability is
              achieved by setting up a pair of the DHCP servers in a network.
              Two modes of operation are supported. The first one is called load
              balancing and is sometimes referred to as active-active. Each
              server can handle selected group of clients in this network or all
              clients, if it detects that its partner has became unavailable.
              It is also possible
              to designate one server to serve all DHCP clients, and leave
              another server as "standby". This mode is called hot standby and
              is sometimes referenced to as active-passive. This server will
              activate its DHCP function when it detects that its partner is not
              available.  Such cooperation between the DHCP servers requires
              that these servers constantly communicate with each other to send
              updates about allocated leases and to periodically test whether
              their partners are still operational. The hook library also
              provides an ability to send lease updates to external backup
              server, making it much easier to have a replacement that is almost
              up to date. The "libdhcp_ha" library provides such functionality
              for Kea DHCP servers.
              </entry>
            </row>
            <row>
              <entry>Radius</entry>
              <entry>Support customers</entry>
              <entry>Kea 1.4.0</entry>
              <entry>
                <simplelist>
                  <member>kea-dhcp4</member>
                  <member>kea-dhcp6</member>
                </simplelist>
              </entry>
              <entry>The RADIUS Hook library allows Kea to interact with the
              RADIUS servers using access and accounting mechanisms. The access
              mechanism may be used for access control, assigning specific IPv4
              or IPv6 addresses reserved by RADIUS, dynamically assigning
              addresses from designated pools chosen by RADIUS or rejecting
              the client's messages altogether. The accounting mechanism allows
              RADIUS server to keep track of device activity over time.
              </entry>
            </row>
            <row>
              <entry>Host Cache</entry>
              <entry>Support customers</entry>
              <entry>Kea 1.4.0</entry>
              <entry>
                <simplelist>
                  <member>kea-dhcp4</member>
                  <member>kea-dhcp6</member>
                </simplelist>
              </entry>
              <entry>Some of the database backends, such as RADIUS, are
              considered slow and may take a long time to respond. Since Kea in
              general is synchronous, the backend performance directly affects
              the DHCP performance. To minimize the impact and improve
              performance, the Host Cache library provides a way to cache
              responses from other hosts. This includes negative caching,
              i.e. the ability to remember that there is no client information
              in the database.
              </entry>
            </row>
          </tbody>
          </tgroup>
          </table>

      </para>
      <para>
        ISC hopes to see more hooks libraries become available as time
        progresses, both developed internally and externally. Since
        this list may evolve dynamically, we decided to keep it on a
        wiki page, available at this link: <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://kea.isc.org/wiki/Hooks">http://kea.isc.org/wiki/Hooks</link>.
        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
        mailing lists and someone will update it.
      </para>
      <para>
        The libraries developed by ISC are described in detail in the following sections.
      </para>
      <section>
        <title>user_chk: Checking User Access</title>
        <para>
          The user_chk library is the first hooks library published by ISC. It
          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
              possible using the hooks interface.</para>
            </listitem>
          </itemizedlist>
        </para>
        <para>
          Once loaded, the library allows segregating incoming requests into
          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>
          As an example of use, this behavior may be used to put unknown users into a
          separate subnet that leads to a walled garden, where they can only
          access a registration portal. Once they fill in necessary data, their
          details are added to the known clients file and they get a proper
          address after their device is restarted.
        </para>

        <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
        and external source of information about clients and alter Kea's
        behavior is useful and remains of educational value.
        </para></note>

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

          <itemizedlist>
            <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
            either the hardware address or the DUID from the request
            formatted as a string of hex digits, with or without
            ":" delimiters.</para></listitem>
          </itemizedlist>

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

          <itemizedlist>
            <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>
          </itemizedlist>

          A sample user registry file is shown below:

<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>

        <para>As with any other hooks libraries provided by ISC, internals of the
        user_chk code are well documented. You can take a look at the  <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://jenkins.isc.org/job/Kea_doc/doxygen/d8/db2/libdhcp_user_chk.html">Kea Developer's Guide section dedicated to the user_chk library</link>
        that discusses how the code works internally. That, together with
        our general entries in <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://jenkins.isc.org/job/Kea_doc/doxygen">Hooks
        Framework section</link> should give you some pointers how to extend
        this library and perhaps even write your own from scratch.</para>

      </section>
      <section>
        <title>legal_log: Forensic Logging Hooks</title>
        <para>
        This section describes the forensic log hooks library. This library
        provides hooks that record a detailed log of lease assignments
        and renewals into a set of log files.  Currently this library
        is only available to ISC customers with a support contract.

        <note>
          <para>This library may only be loaded by <command>kea-dhcp4</command>
          or <command>kea-dhcp6</command> process.
          </para>
        </note>
        </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>
        <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>
        <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 "path" and "base-name" are supplied in the
          configuration as described below see
          <xref linkend="forensic-log-configuration"/>.  The next part of the name is
          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
          be distinct.  See the examples in <xref linkend="forensic-log-configuration"/>.
          </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,
          a prepended timestamp and has the following sections:
<screen>
timestamp address duration device-id {client-info} {relay-info} {user-context}
</screen>
          </para>
          <para>
          Where:
          <itemizedlist>
            <listitem><para>
            timestamp - the current date and time the log entry was written
            in "%Y-%m-%d %H:%M:%S %Z" strftime format ("%Z" is the time zone
            name).
            </para></listitem>
            <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 "infinite duration".
            </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>
            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.
            The circuit id and remote id are presented as hex strings
            </para></listitem>
            <listitem><para>
            user-context - the optional user context associated to the lease.
            </para></listitem>
          </itemizedlist>
          </para>
          <para>
          For instance (line breaks added for readability, they would not
          be present in the log file).
<screen>
2018-01-06 01:02:03 CET 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>
        <para>
        In addition to logging lease activity driven by DHCPv4 client traffic, it also
        logs entries for the following lease management control channel commands:
        lease4-add, lease4-update, and lease4-del.  Each entry is a single string
        with no embedded end-of-line markers and they will typically have the following
        forms:
        </para>
        <para>
        <command>lease4-add:</command>
<screen>
*timestamp* Administrator added a lease of address: *address* to a device with hardware address: *device-id*
</screen>
        Dependent on the arguments of the add command, it may also include the
        client-id and duration.
        </para>
        <para>
        Example:
<screen>
2018-01-06 01:02:03 CET Administrator added a lease of address: 192.0.2.202 to a device with hardware address: 
1a:1b:1c:1d:1e:1f for 1 days 0 hrs 0 mins 0 secs
</screen>
        </para>
        <para>
        <command>lease4-update:</command>
<screen>
*timestamp* Administrator updated information on the lease of address: *address* to a device with hardware address: *device-id*
</screen>
        Dependent on the arguments of the update command, it may also include the
        client-id and lease duration.
        </para>
        <para>
        Example:
<screen>
2018-01-06 01:02:03 CET Administrator updated information on the lease of address: 192.0.2.202 to a device 
with hardware address: 1a:1b:1c:1d:1e:1f, client-id: 1234567890
</screen>
        </para>
        <para>
        <command>lease4-del:</command>
        Deletes have two forms, one by address and one by identifier and identifier type:
<screen>
*timestamp* Administrator deleted the lease for address: *address*
</screen>
        or
<screen>
*timestamp* Administrator deleted a lease for a device identified by: *identifier-type* of *identifier*
</screen>
        Currently only a type of @b hw-address (hardware address) is supported.
        </para>
        <para>
        Examples:
<screen>
2018-01-06 01:02:03 CET Administrator deleted the lease for address: 192.0.2.202

2018-01-06 01:02:12 CET Administrator deleted a lease for a device identified by: hw-address of 1a:1b:1c:1d:1e:1f
</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,
          a prepended timestamp and has the following sections:
<screen>
timestamp address duration device-id {relay-info}* {user-context}
</screen>
          </para>
          <para>
          Where:
          <itemizedlist>
            <listitem><para>
            timestamp - the current date and time the log entry was written
            in "%Y-%m-%d %H:%M:%S %Z" strftime format ("%Z" is the time zone
            name).
            </para></listitem>
            <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
            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.
            </para></listitem>
            <listitem><para>
            user-context - the optional user context associated to the lease.
            </para></listitem>
          </itemizedlist>
          </para>
          <para>
          For instance (line breaks added for readability, they would not
          be present in the log file).
<screen>
2018-01-06 01:02:03 PST 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>
        <para>
        In addition to logging lease activity driven by DHCPv6 client traffic, it also
        logs entries for the following lease management control channel commands:
        lease6-add, lease6-update, and lease6-del.  Each entry is a single string
        with no embedded end-of-line markers and they will typically have the following
        forms:
        </para>
        <para>
        <command>lease6-add:</command>
<screen>
*timestamp* Administrator added a lease of address: *address* to a device with DUID: *DUID*
</screen>
        Dependent on the arguments of the add command, it may also include the hardware address and duration.
        </para>
        <para>
        Example:
<screen>
2018-01-06 01:02:03 PST Administrator added a lease of address: 2001:db8::3 to a device with DUID:
1a:1b:1c:1d:1e:1f:20:21:22:23:24 for 1 days 0 hrs 0 mins 0 secs
</screen>
        </para>
        <para>
        <command>lease6-update:</command>
<screen>
*timestamp* Administrator updated information on the lease of address: *address* to a device with DUID: *DUID*
</screen>
        Dependent on the arguments of the update command, it may also include the hardware address and lease duration.
        </para>
        <para>
        Example:
<screen>
2018-01-06 01:02:03 PST Administrator updated information on the lease of address: 2001:db8::3 to a device with
DUID: 1a:1b:1c:1d:1e:1f:20:21:22:23:24, hardware address: 1a:1b:1c:1d:1e:1f
</screen>
        </para>
        <para>
        <command>lease6-del:</command>
        Deletes have two forms, one by address and one by identifier and identifier type:
<screen>
*timestamp* Administrator deleted the lease for address: *address*
</screen>
        or
<screen>
*timestamp* Administrator deleted a lease for a device identified by: *identifier-type* of *identifier*
</screen>
        Currently only a type of DUID is supported.
        </para>
        <para>
Examples:
<screen>
2018-01-06 01:02:03 PST Administrator deleted the lease for address: 2001:db8::3

2018-01-06 01:02:11 PST Administrator deleted a lease for a device identified by: duid of 1a:1b:1c:1d:1e:1f:20:21:22:23:24
</screen>
        </para>
        </section>
        <section xml:id="forensic-log-configuration">
        <title>Configuring the Forensic Log Hooks</title>
          <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
          "--prefix" 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>
    "hooks-libraries": [
        {
            "library": "/usr/local/lib/libdhcp_legal_log.so",
            "parameters": {
                "path": "/var/kea/var",
                "base-name": "kea-forensic4"
            }
        },
        ...
    ] </userinput>
}
</screen>
          </para>
          <para>
          To configure it for kea-dhcp6, the commands are simply as shown below:
<screen>
"Dhcp6": { <userinput>
    "hooks-libraries": [
        {
            "library": "/usr/local/lib/libdhcp_legal_log.so",
            "parameters": {
                "path": "/var/kea/var",
                "base-name": "kea-forensic6"
            }
        },
        ...
    ] </userinput>
}
</screen>
          </para>
          <para>
          Two Hook Library parameters are supported:
          <itemizedlist>
            <listitem><para>
            path - the directory in which the forensic file(s) will be written.  The
            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
            the current system date to form the current forensic file name.  It defaults
            to <filename>kea-legal</filename>.
            </para></listitem>
          </itemizedlist>
          </para>

          <para>
            If it is desired to restrict forensic logging to certain subnets, the
            "legal-logging" boolean parameter can be specified within a user context of
            these subnets. For example:
<screen>
"Dhcpv4" {
    "subnet4": [
        {
            "subnet": "192.0.2.0/24",
            "pools": [
                {
                     "pool": "192.0.2.1 - 192.0.2.200"
                }
            ],
            <userinput>"user-context": {
                "legal-logging": false
            }</userinput>
        }
    ]
}
</screen>
              disables legal logging for the subnet "192.0.2.0/24". If this parameter
              is not specified, it defaults to 'true', which enables legal logging for
              the subnet.
          </para>

          <para>
            The following example demonstrates how to selectively disable legal logging
            for an IPv6 subnet.
<screen>
"Dhcpv6": {
    "subnet6": [
        {
            "subnet": "2001:db8:1::/64",
            "pools": [
                 {
                     "pool": "2001:db8:1::1-2001:db8:1::ffff"
                 }
            ],
            <userinput>"user-context": {
                "legal-logging": false
            }</userinput>
        }
    ]
}
</screen>
          </para>

          <para>
            See <xref linkend="dhcp4-user-contexts"/> and <xref linkend="dhcp6-user-contexts"/>
            to learn more about user contexts in Kea configuration.
          </para>
        </section>

        <section id="forensic-log-database">
        <title>Database backend</title>
          <para>
          Log entries can be inserted into a database when Kea is configured
          with database backend support: a table named 'logs' is used with a
          timestamp (timeuuid for Cassandra CQL) generated by the database
          software and a text log with the same format than for files
          without the timestamp.
          </para>
          <para>
          Please refer to <xref linkend="mysql-database"/> for MySQL,
          to <xref linkend="pgsql-database"/> for PostgreSQL or
          to <xref linkend="cql-database"/> for Cassandra CQL.
          The logs table is part of the Kea database schemas.
          </para>
          <para>
          Configuration parameters are extended by standard lease database
          parameters as defined in <xref linkend="database-configuration4"/>.
          The "type" parameter should be "mysql", "postgresql",  "cql" or
          be "logfile". When it is absent or set to "logfile" files are
          used.
          </para>
          <para>
          This database feature is experimental and will be likely
          improved, for instance to add an address / prefix index (currently
          the only index is the timestamp). No specific tools is provided
          to operate the database but standard tools are applicable,
          for instance to dump the logs table from a CQL database:
<screen>
$ <userinput>echo 'SELECT dateOf(timeuuid), log FROM logs;' | cqlsh -k <replaceable>database-name</replaceable></userinput>

 system.dateof(timeuuid)         | log
---------------------------------+---------------------------------------
 2018-01-06 01:02:03.227000+0000 | Address: 192.2.1.100 has been renewed ...
 ...
(12 rows)
$
</screen>
          </para>
        </section>
      </section>

      <section xml:id="flex-id">
        <title>flex_id: Flexible Identifiers for Host Reservations</title>
        <para>
          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
          scenarios 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
        hook application.</para>

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

        <note>
          <para>This library may only be loaded by <command>kea-dhcp4</command>
          or <command>kea-dhcp6</command> process.
          </para>
        </note>
      </para>

        <para>The library allows for defining an expression, using notation
        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 a mandatory parameter identifier-expression and optional
          boolean parameter replace-client-id:
<screen>
"Dhcp6": { <userinput>
    "hooks-libraries": [
        {
            "library": "/path/libdhcp_flex_id.so",
            "parameters": {
                "identifier-expression": "<userinput>expression</userinput>",
                "replace-client-id": "<userinput>false</userinput>"
            }
        },
        ...
    ] </userinput>
}
</screen>
        </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
          interface-id option inserted by the relay agent. After adding "flex-id"
          host-reservation-identifiers goal can be achieved by using the
          following configuration:
<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
    "host-reservation-identifiers": ["duid", "flex-id"], // add "flex-id" to reservation identifiers
    "hooks-libraries": [
        {
            "library": "/path/libdhcp_flex_id.so",
            "parameters": {
                "identifier-expression": "<userinput>substring(relay6[0].option[18].hex,0,8)</userinput>"
            }
        },
        ...
    ]
}
</screen>
        </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>
<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>

        <para>
          When "replace-client-id" is set to false (which is the default setting),
          the flex-id hook library uses evaluated flexible identifier solely for
          identifying host reservations, i.e. searching for reservations within a
          database. This is a functional equivalent of other identifiers,
          similar to hardware address or circuit-id. However,
          this mode of operation has an implication that if a client device is
          replaced, it may cause a conflict between an existing lease (allocated
          for old device) and the new lease being allocated for the new device. The
          conflict arises because the same flexible identifier is computed for the
          replaced device and the server will try to allocate the same lease. The
          mismatch between client identifiers sent by new device and old device causes
          the server to refuse this new allocation until the old lease expires.
          A manifestation of this problem is dependant on specific expression
          used as flexible identifier and is likely to appear if you only use options
          and other parameters that are identifying where the device is
          connected (e.g. circuit-id), rather than the device identification
          itself (e.g. MAC address).
        </para>

        <para>
          The flex-id library offers a way to overcome the problem with lease conflicts
          by dynamically replacing client identifier (or DUID in DHCPv6 case) with a
          value derived from flexible identifier. The server processes the client's
          query as if flexible identifier was sent in the client identifier (or DUID)
          option. This guarantees that returning client (for which the same flexible
          identifier is evaluated) will be assigned the same lease despite the client
          identifier and/or MAC address change.
        </para>

        <para>
          The following is a stub configuration that enables this behavior:
<screen>
"Dhcp4": { <userinput>
    "hooks-libraries": [
        {
            "library": "/path/libdhcp_flex_id.so",
            "parameters": {
                "identifier-expression": "<userinput>expression</userinput>",
                "replace-client-id": "<userinput>true</userinput>"
            }
        },
        ...
    ] </userinput>
}
</screen>
        </para>

        <para>
          In the DHCPv4 case, the value derived from the flexible identifier is formed
          by prepending 1 byte with a value of zero to flexible identifier. In the IPv6
          case, it is formed by prepanding two zero bytes before the flexible identifier.
        </para>

        <para>
          Note that for this mechanism to take effect, the DHCPv4 server must be configured
          to respect the client identifier option value during lease allocation, i.e.
          "match-client-id" must be set to true. See
          <xref linkend="dhcp4-match-client-id"/> for details. No additional settings
          are required for DHCPv6.
        </para>
        <para>
          If "replace-client-id" option is set to true, the value of "echo-client-id"
          parameter (that governs whether to send back a client-id option or
          not) is ignored.
        </para>

        <para>
          The <xref linkend="lease-cmds"/> section describes commands used to retrieve,
          update and delete leases using various identifiers, e.g. "hw-address",
          "client-id". The lease_cmds library doesn't natively support querying for
          leases by flexible identifier. However, when "replace-client-id" is set to
          true, it makes it possible to query for leases using a value derived from
          the flexible identifier. In the DHCPv4 case, the query will look similar to this:
<screen>
{
    "command": "lease4-get",
    "arguments": {
        "identifier-type": "client-id",
        "identifier": "00:<userinput>54:64:45:66</userinput>",
        "subnet-id": 44
    }
}
</screen>

            where hexadecimal value of "54:64:45:66" is a flexible identifier computed
            for the client.
        </para>

        <para>
          In the DHCPv6 case, the corresponding query will look similar to this:
<screen>
{
    "command": "lease6-get",
    "arguments": {
        "identifier-type": "duid",
        "identifier": "00:00:<userinput>54:64:45:66</userinput>",
        "subnet-id": 10
    }
}</screen>

        </para>
      </section>

      <section xml: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.

        <note>
          <para>This library may only be loaded by <command>kea-dhcp4</command>
          or <command>kea-dhcp6</command> process.
          </para>
        </note>
        </para>

        <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-databases description in
          <xref linkend="hosts-databases-configuration4"/> and <xref linkend="hosts-databases-configuration6"/>) and it must not operate in
          read-only mode. If the hosts-databases are not specified or are 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
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://kea.isc.org/wiki/ControlAPIRequirements">Control API
Requirements </link> 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
          Agent (see <xref linkend="kea-ctrl-agent"/>).
        </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 for the 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": {
        <userinput>"reservation":
            {
                "subnet-id":1,
                "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" ]
            }</userinput>
    }
}</screen>

Here is an example of complex IPv6 reservation:
<screen>
{
    "command": "reservation-add",
    "arguments": {
        <userinput>"reservation":
            {
                "subnet-id":1,
                "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"
                    }
                ]
            }</userinput>
    }
}</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": "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-databases parameter must be specified in your configuration and
          databases 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": [

    ],
    "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": [

    ],
    "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>

        </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
            deletion was successful or 1 if it was not. A descriptive text is
            provided in case of error. Example results look as follows:
<screen>
{
    "result": 1,
    "text": "Host not deleted (not found)."
}</screen>

<screen>
{
    "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>
      </section>

      <!-- ================================================================= -->
      <!-- === lease_cmds ================================================== -->
      <!-- ================================================================= -->

      <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="hooks-lease-cmds.xml"/>

      <section xml: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 and shared network
          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. An ability to manage shared networks (listing,
          retrieving details, adding new ones, removing existing ones, adding
          subnets to and removing from shared networks) is also provided.
        </para>

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

        <note>
          <para>This library may only be loaded by <command>kea-dhcp4</command>
          or <command>kea-dhcp6</command> process.
          </para>
        </note>
        </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 specified 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>

          <listitem>
          <simpara>
            <command>network4-list/network6-list</command>: lists all configured
            shared networks
          </simpara>
          </listitem>
          <listitem>
          <simpara>
            <command>network4-get/network6-get</command>: retrieves detailed
            information about specified shared network
          </simpara>
          </listitem>
          <listitem>
          <simpara>
            <command>network4-add/network6-add</command>: adds a new shared
            network to the server's configuration
          </simpara>
          </listitem>
          <listitem>
          <simpara>
            <command>network4-del/network6-del</command>: removes a shared
            network from the server's configuration
          </simpara>
          </listitem>
          <listitem>
          <simpara>
            <command>network4-subnet-add/network6-subnet-add</command>: adds
            existing subnet to existing shared network
          </simpara>
          </listitem>
          <listitem>
          <simpara>
            <command>network4-subnet-del/network6-subnet-del</command>: removes
            a subnet from existing shared network and demotes it to a plain
            subnet.
          </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": {
    "subnets": [
        {
            "id": 10,
            "subnet": "10.0.0.0/8"
        },
        {
            "id": 100,
            "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": {
    "subnets": [
        {
            "id": 11,
            "subnet": "2001:db8:1::/64"
        },
        {
            "id": 233,
            "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": {
        "id": 10
    }
}</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,
    "text": "Info about IPv4 subnet 10.0.0.0/8 (id 10) returned",
    "arguments": {
        "subnets": [
            {
                "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": {
        "id": 11
    }
}
</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,
    "text": "Info about IPv6 subnet 2001:db8:1::/64 (id 11) returned",
    "arguments": {
        "subnets": [
            {
                "subnet": "2001:db8:1::/64",
                "id": 1,
                "option-data": [
                    ...
                ]
                ....
            }
        ]
    }
}
</screen>
        </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": {
        "subnets": [ {
            "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": {
        "subnets": [
            {
                "id": 123,
                "subnet": "10.20.30.0/24"
            }
        ]
    }
}
</screen>
        </para>
      </section>

      <section>
        <title>subnet6-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>subnet6-add</command>. The commands described in
          <xref linkend="host-cmds"/> should be used to add, remove and
          modify static reservations.
<screen>
{
    "command": "subnet6-add",
    "arguments": {
        "subnet6": [ {
            "id": 234,
            "subnet": "2001:db8:1::/64",
            ...
        } ]
    }
}
</screen>
        </para>

        <para>
          The response to this command has the following structure:
<screen>
{
    "result": 0,
    "text": "IPv6 subnet added",
    "arguments": {
        "subnet6": [
            {
                "id": 234,
                "subnet": "2001:db8:1::/64"
            }
        ]
    }
}
</screen>
        </para>

        <para>
          It is recommended, but not mandatory to specify subnet
          id. If not specified, Kea will try to assign the next
          subnet-id value. This automatic ID value generator is
          simple. It returns a previously automatically assigned value
          increased by 1. This works well, unless you manually create
          a subnet with a value bigger than previously used. For
          example, if you call subnet4-add five times, each without
          id, Kea will assign IDs: 1,2,3,4 and 5 and it will work just
          fine. However, if you try to call subnet4-add five times,
          with the first subnet having subnet-id of value 3 and
          remaining ones having no subnet-id, it will fail. The first
          command (with explicit value) will use subnet-id 3, the
          second command will create a subnet with id of 1, the third
          will use value of 2 and finally the fourth will have the
          subnet-id value auto-generated as 3. However, since there is
          already a subnet with that id, it will fail.
        </para>
        <para>
          The general recommendation is to either: never use explicit
          values (so the auto-generated values will always work) or
          always use explicit values (so the auto-generation is never
          used). You can mix those two approaches only if you
          understand how the internal automatic subnet-id generation works.
        </para>

      </section>

      <section>
        <title>subnet4-del command</title>
        <para>
          This command is used to remove a subnet from the server's configuration.
          This command has no effect on other configured subnets but removing
          a subnet has certain implications which the server's administrator
          should be aware of.
        </para>
        <para>
          In most cases the server has assigned some leases to the clients
          belonging to the subnet. The server may also be configured with
          static host reservations which are associated with this subnet.
          The current implementation of the <command>subnet4-del</command>
          removes neither the leases nor host reservations associated with
          a subnet. This is the safest approach because the server doesn't
          loose track of leases assigned to the clients from this subnet.
          However, removal of the subnet may still cause configuration
          errors and conflicts. For example: after removal of the subnet,
          the server administrator may add a new subnet with the ID used
          previously for the removed subnet. This means that the existing
          leases and static reservations will be in conflict with this
          new subnet. Thus, we recommend that this command is used with extreme
          caution.
        </para>
        <para>
          This command can also be used to completely delete an IPv4 subnet that
          is part of a shared network. If you want to simply remove the subnet
          from a shared network and keep the subnet configuration, use
          <command>network4-subnet-del</command> command instead.
        </para>

        <para>The command has the following structure:
<screen>
{
    "command": "subnet4-del",
    "arguments": {
        "id": 123
    }
}
</screen>
        </para>
        <para>
          The example successful response may look like this:
<screen>
{
    "result": 0,
    "text": "IPv4 subnet 192.0.2.0/24 (id 123) deleted",
    "arguments": {
        "subnets": [
            {
                "id": 123,
                "subnet": "192.0.2.0/24"
            }
        ]
    }
}
</screen>
        </para>
      </section>

      <section>
        <title>subnet6-del command</title>
        <para>
          This command is used to remove a subnet from the server's configuration.
          This command has no effect on other configured subnets but removing
          a subnet has certain implications which the server's administrator
          should be aware of.
        </para>
        <para>
          In most cases the server has assigned some leases to the clients
          belonging to the subnet. The server may also be configured with
          static host reservations which are associated with this subnet.
          The current implementation of the <command>subnet6-del</command>
          removes neither the leases nor host reservations associated with
          a subnet. This is the safest approach because the server doesn't
          loose track of leases assigned to the clients from this subnet.
          However, removal of the subnet may still cause configuration
          errors and conflicts. For example: after removal of the subnet,
          the server administrator may add a new subnet with the ID used
          previously for the removed subnet. This means that the existing
          leases and static reservations will be in conflict with this
          new subnet. Thus, we recommend that this command is used with extreme
          caution.
        </para>
        <para>
          This command can also be used to completely delete an IPv6 subnet that
          is part of a shared network. If you want to simply remove the subnet
          from a shared network and keep the subnet configuration, use
          <command>network6-subnet-del</command> command instead.
        </para>

        <para>The command has the following structure:
<screen>
{
    "command": "subnet6-del",
    "arguments": {
        "id": 234
    }
}
</screen>
        </para>
        <para>
          The example successful response may look like this:
<screen>
{
    "result": 0,
    "text": "IPv6 subnet 2001:db8:1::/64 (id 234) deleted",
    "subnets": [
        {
            "id": 234,
            "subnet": "2001:db8:1::/64"
        }
    ]
}
</screen>
        </para>
      </section>

      <section>
        <title>network4-list, network6-list commands</title>
        <para>
          These commands are used to retrieve full list of currently configured
          shared networks. The list contains only very basic information about
          each shared network. If more details are needed, please use
          <command>network4-get</command> or <command>network6-get</command> to
          retrieve all information available. This command does not require any
          parameters and its invocation is very simple:
<screen>
{
    "command": "network4-list"
}
</screen>
An example response for <command>network4-list</command> looks as follows:
<screen>
{
    "arguments": {
        "shared-networks": [
            { "name": "floor1" },
            { "name": "office" }
        ]
    },
    "result": 0,
    "text": "2 IPv4 network(s) found"
}</screen>
<command>network6-list</command> follows exactly the same syntax for
both the query and the response.
        </para>
    </section>

    <section>
        <title>network4-get, network6-get commands</title>
        <para>
          These commands are used to retrieve detailed information
          about shared networks, including subnets currently
          being part of a given network. Both commands take one
          mandatory parameter <command>name</command>, which specify
          the name of shared network. An example command to retrieve
          details about IPv4 shared network with a name "floor13"
          looks as follows:
<screen>
{
    "command": "network4-get",
    "arguments": {
        "name": "floor13"
    }
}</screen>
An example response could look as follows:
<screen>
{
    "result": 0,
    "text": "Info about IPv4 shared network 'floor13' returned",
    "arguments": {
        "shared-networks": [
        {
            "match-client-id": true,
            "name": "floor13",
            "option-data": [ ],
            "rebind-timer": 90,
            "relay": {
                "ip-address": "0.0.0.0"
            },
            "renew-timer": 60,
            "reservation-mode": "all",
            "subnet4": [
                {
                    "subnet": "192.0.2.0/24",
                    "id": 5,
                    // many other subnet specific details here
                },
                {
                    "id": 6,
                    "subnet": "192.0.3.0/31",
                    // many other subnet specific details here
                }
            ],
            "valid-lifetime": 120
        }
        ]
    }
}
</screen>
Note that actual response contains many additional fields that are
omitted here for clarity. The response format is exactly the same as
used in <command>config-get</command>, just is limited to returning
shared networks information.
        </para>
    </section>

    <section>
        <title>network4-add, network6-add commands</title>
        <para>
          These commands are used to add a new shared network. New
          network has to have unique name. This command requires one parameter
          <command>shared-networks</command>, which is a list and
          should contain exactly one entry that defines the
          network. The only mandatory element for a network is its
          name. Although it does not make operational sense, it is
          allowed to add an empty shared network that does not have
          any subnets in it. That is allowed for testing purposes, but
          having empty networks (or with only one subnet) is
          discouraged in production environments. For details regarding
          syntax, see <xref linkend="shared-network4"/> and <xref
          linkend="shared-network6"/>.
        </para>
        <note><para>As opposed to parameter inheritance during full
          new configuration processing, this command does not fully handle
          parameter inheritance and any missing parameters will be
          filled with default values, rather than inherited from
          global scope.</para></note>
        <para>
          An example that showcases how to add a new IPv4 shared network looks
          as follows:
<screen>
{
    "command": "network4-add",
    "arguments": {
        "shared-networks": [ {
            "name": "floor13",
            "subnet4": [
            {
                "id": 100,
                "pools": [ { "pool": "192.0.2.2-192.0.2.99" } ],
                "subnet": "192.0.2.0/24",
                "option-data": [
                    {
                        "name": "routers",
                        "data": "192.0.2.1"
                    }
                ]
            },
            {
                "id": 101,
                "pools": [ { "pool": "192.0.3.2-192.0.3.99" } ],
                "subnet": "192.0.3.0/24",
                "option-data": [
                    {
                        "name": "routers",
                        "data": "192.0.3.1"
                    }
                ]
            } ]
        } ]
    }
}
</screen>
Assuming there was no shared network with a name floor13 and no subnets with id
100 and 101 previously configured, the command will be successful and will
return the following response:
<screen>
{
    "arguments": {
        "shared-networks": [ { "name": "floor13" } ]
    },
    "result": 0,
    "text": "A new IPv4 shared network 'floor13' added"
}
</screen>
The <command>network6-add</command> uses the same syntax for both the query and
the response. However, there are some parameters that are IPv4-only
(e.g. match-client-id) and some are IPv6-only (e.g. interface-id). The same
applies to subnets within the network.
        </para>
    </section>
    <section>
        <title>network4-del, network6-del commands</title>
        <para>
          These commands are used to delete existing shared
          networks. Both commands take exactly one parameter 'name' that
          specifies the name of the network to be removed. An example invocation
          of <command>network4-del</command> command looks as follows:
<screen>
{
    "command": "network4-del",
    "arguments": {
        "name": "floor13"
    }
}
</screen>
Assuming there was such a network configured, the response will look similar to
the following:
<screen>
{
    "arguments": {
        "shared-networks": [
            {
                "name": "floor13"
            }
        ]
    },
    "result": 0,
    "text": "IPv4 shared network 'floor13' deleted"
}</screen>
The <command>network6-del</command> command uses exactly the same syntax for
both the command and the response.
        </para>

        <para>If there are any subnets belonging to the shared network
        being deleted, they will be demoted to a plain subnet. There
        is an optional parameter called
        <command>subnets-action</command> that, if specified, takes
        one of two possible values: <command>keep</command> (which is
        the default) and <command>delete</command>. It controls
        whether the subnets be demoted to plain subnets or removed. An
        example usage in network6-del command that deletes the shared
        network and all subnets in it could looks like as follows:
<screen>
{
    "command": "network4-del",
    "arguments": {
        "name": "floor13",
        "subnets-action": "delete"
    }
}
</screen>
        </para>

        <para>Alternatively, if you want to completely remove the
        subnets, you may use <command>subnet4-del</command> or
        <command>subnet6-del</command> commands.</para>

    </section>
    <section>
        <title>network4-subnet-add, network6-subnet-add commands</title>
        <para>
          These commands are used to add existing subnets to existing shared
          networks. There are several ways to add new shared network. System
          administrator can add the whole shared network at once, either by
          editing a configuration file or by calling
          <command>network4-add</command> or <command>network6-add</command>
          commands with desired subnets in it. This approach works better for completely
          new shared subnets. However, there may be cases when an existing
          subnet is running out of addresses and needs to be extended with
          additional address space. In other words another subnet has to be
          added on top of it. For this scenario, a system administrator can use
          <command>network4-add</command> or <command>network6-add</command> and
          then add existing subnet to this newly created shared network  using
          <command>network4-subnet-add</command> or
          <command>network6-subnet-add</command>.
        </para>
        <para>
          The <command>network4-subnet-add</command> and
          <command>network6-subnet-add</command> commands take two parameters:
          <command>id</command>, which is an integer and specifies subnet-id of existing subnet to
          be added to a shared network; and <command>name</command>, which
          specifies name of the shared network the subnet will be added to. The
          subnet must not belong to any existing network. In case you want to
          reassign a subnet from one shared network to another, please use
          <command>network4-subnet-del</command> or
          <command>network6-subnet-del</command> commands first.
        </para>
        <para>
          An example invocation of <command>network4-subnet-add</command>
          command looks as follows:
<screen>
{
    "command": "network4-subnet-add",
    "arguments": {
        "name": "floor13",
        "id": 5
    }
}</screen>
Assuming there is a network named 'floor13', there is a subnet with subnet-id 5
and it is not a part of existing network, the command will return a response
similar to the following:
<screen>
{
    "result": 0,
    "text": "IPv4 subnet 10.0.0.0/8 (id 5) is now part of shared network 'floor1'"
}</screen>
        The <command>network6-subnet-add</command> command uses exactly the same syntax for
both the command and the response.
        </para>

        <note><para>As opposed to parameter inheritance during full
          new configuration processing or when adding a new shared network with
          new subnets, this command does not fully handle
          parameter inheritance and any missing parameters will be
          filled with default values, rather than inherited from
          global scope or from the shared network.</para></note>
    </section>
    <section>
        <title>network4-subnet-del, network6-subnet-del commands</title>
        <para>
          These commands are used to remove a subnet that is part of existing shared
          network and demote it to a plain, stand-alone subnet. If you want to
          remove a subnet completely, use <command>subnet4-del</command> or
          <command>subnet6-del</command> commands instead.
          The <command>network4-subnet-del</command> and
          <command>network6-subnet-del</command> commands take two parameters:
          <command>id</command>, which is an integer and specifies subnet-id of
          existing subnet to be removed from a shared network; and
          <command>name</command>, which specifies name of the shared network
          the subnet will be removed from.
        </para>
        <para>An example invocation of the
        <command>network4-subnet-del</command> command looks as follows:
 <screen>
 {
    "command": "network4-subnet-del",
    "arguments": {
        "name": "floor13",
        "id": 5
    }
 }</screen>
 Assuming there was a subnet with subnet-id equal to 5 that was part of a shared
 network named 'floor13', the response would look similar to the following:
<screen>
{
    "result": 0,
    "text": "IPv4 subnet 10.0.0.0/8 (id 5) is now removed from shared network 'floor13'"
}</screen>
The <command>network6-subnet-del</command> command uses exactly the same syntax for
both the command and the response.
        </para>
    </section>

    </section> <!-- end of subnet commands -->

    <!-- section high-availability-library -->
    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="hooks-ha.xml"/>

    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="hooks-radius.xml"/>

    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="hooks-host-cache.xml"/>

    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="hooks-stat-cmds.xml"/>

  </section>

    <section xml:id="user-context">
      <title>User contexts</title>
      <para>Hook libraries can have their own configuration parameters. That is
      convenient if the parameter applies to the whole library. However,
      sometimes it is very useful if certain configuration entities are extended
      with additional configuration data. This is where the concept of user
      contexts comes in. A sysadmin can define an arbitrary set of data and
      attach it to Kea structures, as long as the data is specified as JSON map.
      In particular, it is possible to define fields that are integers, strings,
      boolean, lists and maps. It is possible to define nested structures of
      arbitrary complexity. Kea does not use that data on its own, simply stores
      and makes it available for the hook libraries.
      </para>
      <para>
        Another use case for user contexts may be storing comments and other
        information that will be retained by Kea. Regular comments are discarded
        when configuration is loaded, but user contexts are retained. This is
        useful if you want your comments to survive config-set, config-get
        operations for example.
      </para>
      <para>
        If user context is supported in a given context, the parser translates
        "comment" entries into user context with a "comment" entry. The pretty
        print of a configuration does the opposite operation and puts "comment"
        entries at the beginning of maps as it seems to be the common usage.
      </para>
      <para>
        As of Kea 1.3, the structures that allow user contexts are
        pools of all types (addresses and prefixes) and subnets. Kea
        1.4 extended user context support to the global scope, interfaces config,
        shared networks, subnets, client classes, option datas and definitions,
        host reservations, control socket, dhcp ddns, loggers and server id.
        These are supported in both DHCPv4 and DHCPv6 at the exception
        of server id which is DHCPv6 only.
      </para>
    </section>
   </chapter>