
..
    File generated by "tools/add-config-examples-to-arm.py". Do not edit by hand.

.. _config-examples:

######################
Configuration Examples
######################

This is the set of configuration examples included in ``doc/examples`` in the
sources of Kea version |release|.


.. _config-example-ddns:

====
ddns
====

.. _config-example-ddns-all-keys-netconf-json:

--------------------------
ddns/all-keys-netconf.json
--------------------------

.. code-block::
    :linenos:

    // WARNING: This example configuration is not meant for production use.
    // The Kea Kea's DHCP-DDNS server can refuse this configuration because
    // it may contain mutually exclusive configuration parameters.
    //
    // The primary purpose of the example file is to provide a comprehensive
    // list of parameters supported by the Kea DHCP-DDNS server along with the
    // brief description of each parameter.
    //
    // This stable version is used for YANG as we do not want to update code
    // and models each time a keyword is added to the syntax.
    {
        // Kea DHCP-DDNS server configuration begins here.
        "DhcpDdns": {

        // Global Parameters

        // IP address D2 will listen for update requests at.
        // Default is 127.0.0.1
        "ip-address": "127.0.0.1",

        // Port D2 will listen for update requests on.
        // Default is 53001.
        "port": 53001,

        // Maximum time to we will wait for a DNS server to respond to us.
        // Unit is the millisecond, default is 100ms.
        "dns-server-timeout" : 100,

        // Protocol to use for Name Change Requests from a Kea DHCP server.
        // Currently only 'UDP' is supported.
        "ncr-protocol": "UDP",

        // Format to use for Name Change Requests from a Kea DHCP server.
        // Currently only 'JSON' is supported.
        "ncr-format": "JSON",

        // Command control socket configuration parameters for Kea DHCP-DDNS server.
        "control-socket": {

            // Location of the UNIX domain socket file the DHCP-DDNS server uses
            // to receive control commands from the local server administrator.
            "socket-name": "kea-ddns-ctrl-socket",

            // Control socket type used by the Kea DHCP-DDNS server.
            // The 'unix' socket is currently the only supported type.
            "socket-type": "unix"
        },

        // List of hook libraries and their specific configuration parameters
        // to be loaded by Kea DHCP-DDNS server.
        "hooks-libraries": [
            {
                // Location of the hook library to be loaded.
                "library": "ddns-server-commands.so",

                // Hook library-specific configuration parameters.
                "parameters": { }
            }
        ],

        // Forward DDNS (Dynamic DNS).
        "forward-ddns": {

            // List of DDNS domains.
            "ddns-domains": [
                {
                    // Name of the zone (required).
                    "name": "example.com.",

                    // Name of the TSIG key used to protect DNS updates for
                    // names in the domain.
                    "key-name": "d2.md5.key",

                    // List of DNS servers where to send DNS updates.
                    "dns-servers": [
                        {
                            // DNS server IP address (required).
                            "ip-address": "2001:db8:1::10",

                            // DNS server UDP port. Default is 53 (DNS service).
                            "port": 7802,

                            // Name of the TSIG key used to protect DNS updates
                            // sent to the DNS server.
                            "key-name": "d2.sha1.key"
                        }
                    ]
                }
            ]
        },

        // Reverse DDNS (Dynamic DNS).
        "reverse-ddns": {

            // List of DDNS domains.
            "ddns-domains": [
                {
                    // Name of the zone (required).
                    "name": "2.0.192.in-addr.arpa.",

                    // Name of the TSIG key used to protect DNS updates for
                    // names in the domain.
                    "key-name": "d2.sha1.key",

                    // List of DNS servers where to send DNS updates.
                    "dns-servers": [
                        {
                            // DNS server IP address (required).
                            "ip-address": "172.16.1.1",

                            // DNS server UDP port. Default is 53 (DNS service).
                            "port": 5301,

                            // Name of the TSIG key used to protect DNS updates
                            "key-name": "d2.md5.key"
                        }
                    ]
                }
            ]
        },

        // List of TSIG keys used to protect DNS updates.
        "tsig-keys": [
            {
                // Name of the TSIG key (required).
                "name": "d2.md5.key",

                // Algorithm of the TSIG key (required).
                // The value must be a valid algorithm name e.g.
                // HMAC-MD5, HMAC-SHA1, HMAC-SHA224, ...
                "algorithm": "HMAC-MD5",

                // Number of bits in the digest. Default is 0 which means
                // to use all bits provided by the algorithm. Too short values
                // (depending on the algorithm) are rejected.
                "digest-bits": 0,

                // Secret of the TSIG key (required) in base-64.
                "secret": "LSWXnfkKZjdPJI5QxlpnfQ=="
            }
        ],

        // List of loggers used by the servers using this configuration file.
        "loggers": [
            {
                // Debug level, a value between 0..99. The greater the value
                // the more detailed the debug log.
                "debuglevel": 99,

                // Name of the logger.
                "name": "kea-dhcp-ddns",

                // Configures how the log should be output.
                "output-options": [
                    {
                        // Determines whether the log should be flushed to a file.
                        "flush": true,

                        // Specifies maximum filesize before the file is rotated.
                        "maxsize": 10240000,

                        // Specifies the maximum number of rotated files to be kept.
                        "maxver": 1,

                        // Specifies the logging destination.
                        "output": "stdout",

                        // Specifies log entry content
                        "pattern": "%D{%Y-%m-%d %H:%M:%S.%q} %-5p [%c/%i] %m\n"
                    }
                ],

                // Specifies logging severity, i.e. "ERROR", "WARN", "INFO", "DEBUG".
                "severity": "INFO"
            }
        ],

        // Look at sample1 example for the use of user-contexts.
        "user-context": { }
    }

    }

.. _config-example-ddns-all-keys-json:

------------------
ddns/all-keys.json
------------------

.. code-block::
    :linenos:

    // WARNING: This example configuration is not meant for production use.
    // The Kea Kea's DHCP-DDNS server can refuse this configuration because
    // it may contain mutually exclusive configuration parameters.
    //
    // The primary purpose of the example file is to provide a comprehensive
    // list of parameters supported by the Kea DHCP-DDNS server along with the
    // brief description of each parameter.
    //
    // This current version should be up to date, i.e. new keywords should be
    // added in this file at the same time as in the parser specification.
    {
        // Kea DHCP-DDNS server configuration begins here.
        "DhcpDdns": {

        // Global Parameters

        // IP address D2 will listen for update requests at.
        // Default is 127.0.0.1
        "ip-address": "127.0.0.1",

        // Port D2 will listen for update requests on.
        // Default is 53001.
        "port": 53001,

        // Maximum time to we will wait for a DNS server to respond to us.
        // Unit is the millisecond, default is 100ms.
        "dns-server-timeout" : 100,

        // Protocol to use for Name Change Requests from a Kea DHCP server.
        // Currently only 'UDP' is supported.
        "ncr-protocol": "UDP",

        // Format to use for Name Change Requests from a Kea DHCP server.
        // Currently only 'JSON' is supported.
        "ncr-format": "JSON",

        // Command control socket configuration parameters for Kea DHCP-DDNS server.
        "control-sockets": [
            {
                // Control socket type used by the Kea DHCP-DDNS server.
                // Must be unix, http or https.
                "socket-type": "unix",

                // Location of the UNIX domain socket file the DHCP-DDNS
                // server uses to receive control commands from the
                // local server administrator.
                "socket-name": "kea-ddns-ctrl-socket"
            },
            {
                // Control socket type used by the Kea DHCP-DDNS server.
                // Must be unix, http or https.
                "socket-type": "https",

                // Address of the HTTPS socket the Kea DHCP-DDNS server should
                // listen for incoming queries.
                "socket-address": "127.0.0.1",

                // Port of the HTTPS socket the Kea DHCP-DDNS server
                // should listen for incoming queries.
                "socket-port": 8053,

                // TLS trust anchor (Certificate Authority). This is a
                // file name or a directory path. Make sense with other
                // TLS parameters only for the https control socket type.
                "trust-anchor": "my-ca",

                // TLS server certificate file name.
                "cert-file": "my-cert",

                // TLS server private key file name.
                "key-file": "my-key",

                // TLS require client certificates flag. Default is
                // true and means require client certificates. False
                // means they are optional.
                "cert-required": true,

                // Optional authentication.
                "authentication": {
                    // Required authentication type. The only supported
                    // value is basic for the basic HTTP authentication.
                    "type": "basic",

                    // An optional parameter is the basic HTTP
                    // authentication realm.  Its default is
                    // "kea-dhcp-ddns-server"
                    "realm": "kea-dhcp-ddns-server",

                    // This optional parameter can be used to specify a common
                    // prefix for files handling client credentials.
                    "directory": "/usr/local/share/kea/kea-creds",

                    // This list specifies the user ids and passwords to
                    // use for basic HTTP authentication. If empty or not
                    // present any client is authorized.
                    "clients": [
                        // This specifies an authorized client.
                        {
                            // The user id must not be empty or contain
                            // the ':' character. It is a mandatory parameter.
                            "user": "admin",

                            // If password is not specified an empty
                            // password is used.
                            "password": "1234"
                        },

                        // This specifies a hidden client.
                        {
                            // The user id is the content of the
                            // file /usr/local/share/kea/kea-creds/hiddenu.
                            "user-file": "hiddenu",

                            // The password is the content of the
                            // file /usr/local/share/kea/kea-creds/hiddenp.
                            "password-file": "hiddenp"
                        },

                        // This specifies a hidden client using a secret
                        // in a file.
                        {
                            // The secret is the content of the file
                            // /usr/local/share/kea/kea-creds/hiddens which must be in
                            // the <user-id>:<password> format.
                            "password-file": "hiddens"
                        }
                    ]
                }
            }
        ],

        // List of hook libraries and their specific configuration parameters
        // to be loaded by Kea DHCP-DDNS server.
        "hooks-libraries": [
            {
                // Location of the hook library to be loaded.
                "library": "ddns-server-commands.so",

                // Hook library-specific configuration parameters.
                "parameters": { }
            }
        ],

        // Forward DDNS (Dynamic DNS).
        "forward-ddns": {

            // List of DDNS domains.
            "ddns-domains": [
                {
                    // Name of the zone (required).
                    "name": "example.com.",

                    // Name of the TSIG key used to protect DNS updates for
                    // names in the domain.
                    "key-name": "d2.md5.key",

                    // List of DNS servers where to send DNS updates.
                    "dns-servers": [
                        {
                            // DNS server IP address (required).
                            "ip-address": "2001:db8:1::10",

                            // DNS server UDP port. Default is 53 (DNS service).
                            "port": 7802,

                            // Name of the TSIG key used to protect DNS updates
                            // sent to the DNS server.
                            "key-name": "d2.sha1.key"
                        }
                    ]
                }
            ]
        },

        // Reverse DDNS (Dynamic DNS).
        "reverse-ddns": {

            // List of DDNS domains.
            "ddns-domains": [
                {
                    // Name of the zone (required).
                    "name": "2.0.192.in-addr.arpa.",

                    // Name of the TSIG key used to protect DNS updates for
                    // names in the domain.
                    "key-name": "d2.sha1.key",

                    // List of DNS servers where to send DNS updates.
                    "dns-servers": [
                        {
                            // DNS server IP address (required).
                            "ip-address": "172.16.1.1",

                            // DNS server UDP port. Default is 53 (DNS service).
                            "port": 5301,

                            // Name of the TSIG key used to protect DNS updates
                            "key-name": "d2.md5.key"
                        }
                    ]
                }
            ]
        },

        // List of TSIG keys used to protect DNS updates.
        "tsig-keys": [
            {
                // Name of the TSIG key (required).
                "name": "d2.md5.key",

                // Algorithm of the TSIG key (required).
                // The value must be a valid algorithm name e.g.
                // HMAC-MD5, HMAC-SHA1, HMAC-SHA224, ...
                "algorithm": "HMAC-MD5",

                // Number of bits in the digest. Default is 0 which means
                // to use all bits provided by the algorithm. Too short values
                // (depending on the algorithm) are rejected.
                "digest-bits": 0,

                // Secret of the TSIG key (required) in base-64.
                "secret": "LSWXnfkKZjdPJI5QxlpnfQ=="
            },
            {
                "name": "d2.sha1.key",
                "algorithm": "HMAC-SHA1",

                // An alternative to secret: specify a file where the secret
                // can be found. i.e. the secret is the content of the file.
                "secret-file": "/usr/local/share/kea/d2-sha1-secret"
            }
        ],

        // List of loggers used by the servers using this configuration file.
        "loggers": [
            {
                // Debug level, a value between 0..99. The greater the value
                // the more detailed the debug log.
                "debuglevel": 99,

                // Name of the logger.
                "name": "kea-dhcp-ddns",

                // Configures how the log should be output.
                "output-options": [
                    {
                        // Determines whether the log should be flushed to a file.
                        "flush": true,

                        // Specifies maximum filesize before the file is rotated.
                        "maxsize": 10240000,

                        // Specifies the maximum number of rotated files to be kept.
                        "maxver": 1,

                        // Specifies the logging destination.
                        "output": "stdout",

                        // Specifies log entry content
                        "pattern": "%D{%Y-%m-%d %H:%M:%S.%q} %-5p [%c/%i] %m\n"
                    }
                ],

                // Specifies logging severity, i.e. "ERROR", "WARN", "INFO", "DEBUG".
                "severity": "INFO"
            }
        ],

        // Look at sample1 example for the use of user-contexts.
        "user-context": { }
    }

    }

.. _config-example-ddns-comments-json:

------------------
ddns/comments.json
------------------

.. code-block::
    :linenos:

    // This is an example configuration file for D2, Kea's DHCP-DDNS processor.
    // It uses embedded comments which will be included in configuration objects
    // within user-contexts rather than stripped away by at lexical analysis.

    {
    "DhcpDdns":
    {

        // Global scope
        "comment": "A DHCP-DDNS server",
        "ip-address": "127.0.0.1",
        "port": 53001,
        "dns-server-timeout" : 1000,

        // In control sockets.
        "control-sockets": [
            {
                "socket-type": "unix",
                "socket-name": "kea-ddns-ctrl-socket",
                "user-context": { "comment": "Indirect comment" }
            },
            {
                "comment": "HTTP control socket",
                "socket-type": "http",
                "socket-address": "::1",
                "socket-port": 8053,
                // In authentication
                "authentication": {
                    "comment": "basic HTTP authentication",
                    "type": "basic",
                    // In basic HTTP authentication clients
                    "clients": [ {
                        "comment": "admin is authorized",
                        "user": "admin",
                        "password": "1234"
                    } ]
                }
            }
        ],

        "forward-ddns":
        {
            "ddns-domains":
            [
                // In DDNS domain
                {
                    "comment": "DdnsDomain for zone 'four.example.com.'",
                    "name": "four.example.com.",
                    "key-name": "d2.md5.key",
                    // In DNS server
                    "dns-servers":
                    [
                        {
                            "comment": "four.example.com. server",
                            "ip-address": "172.16.1.1"
                        }
                    ]
                }
            ]
        },

        // In TSIG key
        "tsig-keys":
        [
            {
                "comment": "four.example.com. key",
                "name": "d2.md5.key",
                "algorithm": "HMAC-MD5",
                "secret": "LSWXnfkKZjdPJI5QxlpnfQ=="
            }
        ],

        // In loggers
        "loggers": [
            {
                "comment": "A logger",
                "name": "kea-dhcp-ddns",
                "severity": "info"
            }
        ]
    }

    }

.. _config-example-ddns-gss-tsig-json:

------------------
ddns/gss-tsig.json
------------------

.. code-block::
    :linenos:

    // This is an example configuration file for D2, Kea's DHCP-DDNS processor.
    // It uses the GSS-TSIG hook library.
    {
    "DhcpDdns": {
        // The following parameters are used to receive NCRs (NameChangeRequests)
        // from the local Kea DHCP server. Make sure your kea-dhcp4 and kea-dhcp6
        // matches this.
        "ip-address": "127.0.0.1",
        "port": 53001,
        "dns-server-timeout" : 1000,

        // Forward zone: secure.example.org. It uses GSS-TSIG. It is served
        // by two DNS servers, which listen for DDNS requests at 192.0.2.1
        // and 192.0.2.2.
        "forward-ddns":
        {
            "ddns-domains":
            [
                // DdnsDomain for zone "secure.example.org."
                {
                    "name": "secure.example.org.",
                    "comment": "DdnsDomain example",
                    "dns-servers":
                    [
                        {
                          // This server has an entry in gss/servers and
                          // thus will use GSS-TSIG.
                            "ip-address": "192.0.2.1"
                        },
                        {
                          // This server also has an entry there, so will
                          // use GSS-TSIG, too.
                            "ip-address": "192.0.2.2",
                            "port": 5300
                        }
                    ]
                }
            ]
        },

        // Reverse zone: we want to update the reverse zone "2.0.192.in-addr.arpa".
        "reverse-ddns":
        {
            "ddns-domains":
            [
                {
                    "name": "2.0.192.in-addr.arpa.",
                    "dns-servers":
                    [
                        {
                            // There is GSS-TSIG definition for this server (see
                            // DhcpDdns/gss-tsig/servers), so it will use
                            // Krb/GSS-TSIG.
                            "ip-address": "192.0.2.1"
                        }
                    ]
                }
            ]
        },

        // The GSS-TSIG hook is loaded and its configuration is specified here.
        "hooks-libraries": [
        {
            "library": "libddns_gss_tsig.so",
            "parameters": {
                // This section governs the GSS-TSIG integration. Each server
                // mentioned in forward-ddns and/or reverse-ddns needs to have
                // an entry here to be able to use GSS-TSIG defaults (optional,
                // if specified they apply to all the GSS-TSIG servers, unless
                // overwritten on specific server level).

                "server-principal": "DNS/server.example.org@EXAMPLE.ORG",
                "client-principal": "DHCP/admin.example.org@EXAMPLE.ORG",

                // client-keytab and credentials-cache can both be used to
                // store client keys. As credentials cache is more flexible,
                // it is recommended to use it. Typically, using both at the
                // same time may cause problems.
                // "client-keytab": "FILE:/etc/dhcp.keytab", // toplevel only
                "credentials-cache": "FILE:/etc/ccache",     // toplevel only

                "gss-replay-flag": true, // GSS anti replay service
                "gss-sequence-flag": false, // no GSS sequence service
                "tkey-lifetime": 3600, // 1 hour
                "rekey-interval": 2700, // 45 minutes
                "retry-interval": 120, // 2 minutes
                "tkey-protocol": "TCP",
                "fallback": false,

                // The list of GSS-TSIG capable servers
                "servers": [
                    {
                        // First server (identification is required)
                        "id": "server1",
                        "domain-names": [ ], // if not specified or empty, will
                                             // match all domains that want to
                                             // use this IP+port pair
                        "ip-address": "192.0.2.1",
                        "port": 53,
                        "server-principal": "DNS/server1.example.org@EXAMPLE.ORG",
                        "client-principal": "DHCP/admin1.example.org@EXAMPLE.ORG",
                        "gss-replay-flag": false, // no GSS anti replay service
                        "gss-sequence-flag": false, // no GSS sequence service
                        "tkey-lifetime": 7200, // 2 hours
                        "rekey-interval": 5400, // 90 minutes
                        "retry-interval": 240, // 4 minutes
                        "tkey-protocol": "TCP",
                        "fallback": true // if no key is available fallback to the
                                         // standard behavior (vs skip this server)
                    },
                    {
                        // The second server (it has most of the parameters missing
                        // as those are using the defaults specified above)
                        "id": "server2",
                        "ip-address": "192.0.2.2",
                        "port": 5300
                    }
                ]
            }
        }
        ]

        // Additional parameters, such as logging, control socket and
        // others omitted for clarity.
    }

    }

.. _config-example-ddns-sample1-json:

-----------------
ddns/sample1.json
-----------------

.. code-block::
    :linenos:

    // This is an example configuration file for D2, Kea's DHCP-DDNS processor.
    // It supports updating two Forward DNS zones "four.example.com" and
    // "six.example.com"; and one Reverse DNS zone, "2.0.192.in-addr.arpa."

    {
    // ------------------ DHCP-DDNS ---------------------
    "DhcpDdns":
    {

    // --------------  Global Parameters ----------------
    //   D2 will listen for update requests for Kea DHCP servers at 127.0.0.1
    //   on port 53001.  Maximum time to we will wait for a DNS server to
    //   respond to us is 1000 ms.

        "ip-address": "127.0.0.1",
        "port": 53001,
        "dns-server-timeout" : 1000,

    // One extra feature that requires some explanation is
    // user-context. This is a structure that you can define at global scope,
    // in ddns domain, dns server, tsig key and others. It is parsed by
    // Kea, but not used directly.  It is intended to keep anything you
    // may want to put there - comments, extra designations, floor or
    // department names etc.
    // A comment entry is translated into a user-context with a "comment"
    // property so you can include comments inside the configuration itself.

        "user-context": { "version": 1 },

    // ----------------- Control Socket -----------------

        "control-socket":
        {
            "socket-type": "unix",
            "socket-name": "kea-ddns-ctrl-socket"
        },

    // ----------------- Hooks Libraries -----------------

        "hooks-libraries":
        [
            // Hook libraries list may contain more than one library.
            {
                // The only necessary parameter is the library filename.
                "library": "ddns-server-commands.so",

                // Some libraries may support parameters. Make sure you
                // type this section carefully, as the server does not validate
                // it (because the format is library-specific).
                "parameters":
                {
                    "param1": "foo"
                }
            }
        ],

    // ----------------- Forward DDNS  ------------------
    //   1. Zone - "four.example.com.
    //      It uses TSIG, key name is "d2.md5.key"
    //      It is served by one DNS server which listens for DDNS requests at
    //      172.16.1.1 on the default port 53 (standard DNS port)
    //   2. Zone - "six.example.com."
    //      It does not use TSIG.
    //      It is server by one DNS server at "2001:db8:1::10" on port 7802

        "forward-ddns":
        {
            "ddns-domains":
            [
    //           DdnsDomain for zone "four.example.com."
                {
                    "comment": "DdnsDomain example",
                    "name": "four.example.com.",
                    "key-name": "d2.md5.key",
                    "dns-servers":
                    [
                        {
                            "ip-address": "172.16.1.1"
                        }
                    ]
                },

    //           DdnsDomain for zone "six.example.com."
                {
                    "name": "six.example.com.",
                    "dns-servers":
                    [
                        {
                            "ip-address": "2001:db8:1::10",
                            "port": 7802
                        }
                    ]
                }
            ]
        },

    // ----------------- Reverse DDNS  ------------------
    // We will update Reverse DNS for one zone "2.0.192.in-addr-arpa". It
    // uses TSIG with key "d2.sha1.key" and is served by two DNS servers:
    // one listening at "172.16.1.1" on 53001 and the other at "192.168.2.10".
        "reverse-ddns":
        {
            "ddns-domains":
            [
                {
                    "name": "2.0.192.in-addr.arpa.",
                    "key-name": "d2.sha1.key",
                    "dns-servers":
                    [
                        {
                            "ip-address": "172.16.1.1",
                            "port": 53001
                        },
                        {
                            "ip-address": "192.168.2.10"
                        }
                    ]
                }
            ]
        },

    // ------------------ TSIG keys ---------------------
    //   Each key has a name, an algorithm (HMAC-MD5, HMAC-SHA1, HMAC-SHA224...)
    //   and a base-64 encoded shared secret.
        "tsig-keys":
        [
            {
                "name": "d2.md5.key",
                "algorithm": "HMAC-MD5",
                "secret": "LSWXnfkKZjdPJI5QxlpnfQ=="
            },
            {
                "name": "d2.sha1.key",
                "algorithm": "HMAC-SHA1",
                "secret": "hRrp29wzUv3uzSNRLlY68w=="
            },
            {
                "name": "d2.sha256.key",
                "algorithm": "HMAC-SHA256",
                "secret-file": "/usr/local/share/kea/d2-sha256-secret"
            },
            {
                "name": "d2.sha512.key",
                "algorithm": "HMAC-SHA512",
                "digest-bits": 256,
                "secret": "/4wklkm04jeH4anx2MKGJLcya+ZLHldL5d6mK+4q6UXQP7KJ9mS2QG29hh0SJR4LA0ikxNJTUMvir42gLx6fGQ=="
            }
        ],

    // The following configures logging. It assumes that messages with at least
    // informational level (info, warn, error and fatal) should be logged to stdout.
    // It also specifies a custom log pattern.
        "loggers": [
            {
                "name": "kea-dhcp-ddns",
                "output-options": [
                    {
                        "output": "stdout",
                        // Several additional parameters are possible in addition
                        // to the typical output. Flush determines whether logger
                        // flushes output to a file. Maxsize determines maximum
                        // filesize before the file is rotated. maxver
                        // specifies the maximum number of rotated files being
                        // kept.
                        "flush": true,
                        "maxsize": 204800,
                        "maxver": 4,
                        "pattern": "%d [%c/%i] %m\n"
                    }
                ],
                "debuglevel": 0,
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-ddns-template-json:

------------------
ddns/template.json
------------------

.. code-block::
    :linenos:

    // This file may be used a template for constructing DHCP-DDNS JSON
    // configuration.
    // It must start with a left-curly-bracket.
    {

    "DhcpDdns" :
    {
    // --------------  Global Parameters ----------------
    //    All of the global parameters have default values as shown.  If these
    //    are satisfactory you may omit them.
    //    "ip-address" : "127.0.0.1",
    //    "port" : 53001,
    //    "dns-server-timeout" : 100,
    //    "ncr-protocol" : "UDP"
    //    "ncr-format" : "JSON"

    // ----------------- Control Socket -----------------

    //    "control-socket":
    //    {
    //        "socket-type": "unix",
    //        "socket-name": "kea-ddns-ctrl-socket"
    //    },

    // ----------------- Forward DDNS  ------------------
        "forward-ddns" :
        {
            "ddns-domains" :
            [
    //            {
    //                "name" : "<zone name 1>",
    //                "key-name" : "<key name>",
    //                "dns-servers" :
    //                [
    //                    {
    //                        "ip-address" : "<ip address>"
    //                       ,"port" : 53
    //                    }
    //                    ,
    //                    {
    //                        next DNS server for this DdnsDomain
    //                    }
    //                    :
    //                ]
    //            }
    //            ,
    //            {
    //                 next Forward DdnsDomain
    //            }
    //            :
            ]
        },

    // ----------------- Reverse DDNS  ------------------
        "reverse-ddns" :
        {
            "ddns-domains" :
            [
    //            {
    //                "name" : "<reverse zone name 1>",
    //                "key-name" : "<key name>",
    //                "dns-servers" :
    //                [
    //                    {
    //                        "ip-address" : "<ip address>"
    //                        ,"port" : 53
    //                    }
    //                    ,
    //                    {
    //                        next DNS server for this DdnsDomain
    //                    }
    //                    :
    //                ]
    //            }
    //            ,
    //            {
    //                 next Reverse DdnsDomain
    //            }
    //            :
            ]
        },
    // ------------------ TSIG keys ---------------------
        "tsig-keys" :
        [
    //        {
    //            "name" : "<key name>",
    //            "algorithm" : "<algorithm name>",
    //            Valid values for algorithm are:    HMAC-MD5, HMAC-SHA1,
    //                                               HMAC-SHA224, HMAC-SHA256,
    //                                               HMAC-SHA384, HMAC-SHA512
    //            "digest-bits" : 256,
    //            Minimum truncated length in bits.
    //            Default 0 (means truncation is forbidden).
    //            "secret" : "1234" (shared secret value)
    //        }
    //        ,
    //        {
    //                next TSIG Key
    //        }
        ]

    // Logging
    //    ,"loggers":
    //    [
    //        {
    //            "name": "kea-dhcp-ddns",
    //            "severity": "info"
    //        }
    //    ]
    }

    // It must end with an right-curly-bracket.
    }

.. _config-example-kea4:

====
kea4
====

.. _config-example-kea4-advanced-json:

------------------
kea4/advanced.json
------------------

.. code-block::
    :linenos:

    // This is an example configuration file for DHCPv4 server in Kea.
    // It covers some of the more advanced features. This file may not be coherent
    // as its main purpose is to demonstrate the features. They don't necessarily
    // have to make sense used together.

    // The new parser supports 3 comment styles:

    // This is C++ style.

    # This is a bash style.

    /* This is a C style comment. */

    /* C style comment
       can span
       multiple lines */

    { "Dhcp4":

    {
        // Kea is told to listen on eth0 interface only.
        "interfaces-config": {
            "interfaces": [ "eth0" ],

            // This specifies what type of socket Kea uses. Currently supported
            // are 'raw' (which is the default) and 'udp'. Raw has the benefit
            // of receiving all traffic every time and a downside of bypassing
            // all firewall rules and having marginally bigger performance impact.
            // 'udp' is generally better if you have only relayed traffic. Kea
            // than opens up normal UDP socket and the kernel does all the
            // Ethernet/IP stack processing.
            "dhcp-socket-type": "udp",

            // Typically the DHCP server will send its response back on the same
            // interface the query came in. This is the default ("same-as-inbound").
            // However, sometimes it is useful to have the ability to send the
            // packet as plain UDP packet and let the kernel and the routing tables
            // determine the right interface ("use-routing"). This option only works
            // for "dhcp-socket-type" set to "udp" and is ignored otherwise.
            "outbound-interface": "use-routing",

            // This makes interfaces to be re-detected at each (re-)configuration.
            // By default it is true.
            "re-detect": true
        },

        "sanity-checks": {
            // This parameter determines what to do when a new lease appears in the
            // system (i.e. either is read from disk during memfile startup or is
            // added via lease commands). There are five modes supported:
            // none - do nothing, accept them as is
            // warn - if subnet-id problems are detected, print a warning, but
            //        otherwise load the lease as is. This is the default value.
            // fix - attempt to fix the lease by finding appropriate subnet-id value.
            //       if there is no suitable subnet, the lease is loaded as is.
            // fix-del - attempt to fix the lease by finding appropriate subnet-id
            //           value. If there is no suitable subnet, the lease is deleted.
            // del - delete leases that have incorrect subnet-id values.
            "lease-checks": "fix-del"
        },

        // Option 43 last resort definition can make well-formed messages
        // to be rejected because they use not compatible "raw" value,
        // and different vendors may define different sub-options.
        // The option definition should be applied to avoid these problems,
        // for instance by defining at the global scope the option as binary.
        // In client-classes the option may be redefined as carrying vendor
        // dependent sub-options.
        "option-def": [ {
            "name": "vendor-encapsulated-options",
            "code": 43,
            "type": "binary"
        } ],

        // We need to specify the database used to store leases. As of
        // June 2022, three database backends are supported: MySQL,
        // PostgreSQL and the in-memory database, Memfile.
        // We'll use memfile because it doesn't require any prior set up.
        // For memfile, it's important to always specify lfc-interval, so
        // the lease file would not grow without bounds and be sanitized
        // once per hour.
        "lease-database": {
            "type": "memfile",
            "lfc-interval": 3600
        },

        // This defines a control socket. If defined, Kea will open a UNIX socket
        // and will listen for incoming commands. See section 15 of the Kea User's
        // Guide for list of supported commands.
        "control-socket": {
            "socket-type": "unix",
            "socket-name": "kea4-ctrl-socket"
        },

        // Addresses will be assigned with a lifetime of 4000 seconds.
        // The client is told to start renewing after 1000 seconds. If the server
        // does not respond within 2000 seconds of the lease being granted, client
        // is supposed to start REBIND procedure (emergency renewal that allows
        // switching to a different server).
        "valid-lifetime": 4000,
        "renew-timer": 1000,
        "rebind-timer": 2000,

        // RFC6842 says that the server is supposed to echo back client-id option.
        // However, some older clients do not support this and are getting confused
        // when they get their own client-id. Kea can disable RFC6842 support.
        "echo-client-id": false,

        // Some clients don't use stable client identifier, but rather
        // generate them during each boot. This may cause a client that
        // reboots frequently to get multiple leases, which may not be
        // desirable. As such, sometimes admins prefer to tell their DHCPv4
        // server to ignore client-id value altogether and rely exclusively
        // on MAC address. This is a parameter that is defined globally, but
        // can be overridden on a subnet level.
        "match-client-id": true,

        // By default, Kea ignores requests by clients for unknown IP addresses,
        // because other non-cooperating DHCP servers could reside on the same
        // network (RFC 2131). This parameter is defined globally, but can be
        // overridden on a subnet level
        "authoritative": false,

        // The following list defines subnets. Each subnet consists of at
        // least subnet and pool entries. One extra feature that requires
        // some explanation is user-context. This is a structure that you can
        // define in subnets, pools and others. It is parsed by Kea, but not
        // used directly.  It is intended to keep anything you may want to
        // put there - comments, extra designations, floor or department
        // names etc. These structures will be made available to Kea hooks.
        // A comment entry is translated into a user-context with a
        // "comment" property so you can include comments inside the
        // configuration itself.
        "subnet4": [
            {
                "pools": [ {
                    "pool":  "192.0.2.1 - 192.0.2.200",
                    "user-context": { "info": "what a large pool" }
                } ],
                "id": 1,
                "subnet": "192.0.2.0/24",
                "user-context": {
                    "comment": "Our first subnet!"
                }
                // Equivalent using smart parser
                // "comment": "Our first subnet!"
            },
            {
                // This particular subnet has match-client-id value changed.
                // This causes Kea to ignore client-id values in this subnet
                // and rely exclusively on MAC addresses.
                "pools": [ { "pool": "192.0.3.100 - 192.0.3.200" } ],
                "id": 2,
                "subnet": "192.0.3.0/24",
                "match-client-id": false
            },
            {
                "pools": [ { "pool": "192.0.4.1 - 192.0.4.254" } ],
                "id": 3,
                "subnet": "192.0.4.0/24",

                // Sometimes the relay may use an IPv4 address that does
                // not match the subnet. This is discouraged, but there are
                // valid cases when it makes sense. One case is when there
                // is a shared subnet.
                "relay": {
                    "ip-addresses": [ "192.168.1.1" ]
                }
            },
            {
                // This particular subnet has the authoritative value changed.
                // This causes Kea to reply to requests for unknown IP addresses
                // with a DHCPNAK message.
                "pools": [ { "pool": "192.0.5.100 - 192.0.5.200" } ],
                "id": 4,
                "subnet": "192.0.5.0/24",
                "authoritative": true
            }
        ],

        // The following configures logging. It assumes that messages with
        // at least informational level (info, warn, error and fatal) should
        // be logged to stdout.
        "loggers": [
              {
                "name": "kea-dhcp4",
                  "output-options": [
                      {
                          "output": "stdout",
                          // Several additional parameters are possible in addition
                          // to the typical output. Flush determines whether logger
                          // flushes output to a file. Maxsize determines maximum
                          // filesize before the file is rotated. maxver
                          // specifies the maximum number of rotated files being
                          // kept.
                          "flush": true,
                          "maxsize": 204800,
                          "maxver": 4,
                          // We use pattern to specify custom log message layout
                          "pattern": "%d{%y.%m.%d %H:%M:%S.%q} %-5p [%c/%i] %m\n"
                      }
                  ],
                  "severity": "INFO"
              }
          ]
      }

    }

.. _config-example-kea4-all-keys-netconf-json:

--------------------------
kea4/all-keys-netconf.json
--------------------------

.. code-block::
    :linenos:

    // WARNING: This example configuration is not meant for production use.
    // The Kea DHCPv4 server will refuse this configuration because it contains
    // mutually exclusive configuration parameters.
    //
    // The primary purpose of the example file is to provide a comprehensive
    // list of parameters supported by the Kea DHCPv4 server, along with a brief
    // description of each parameter.
    //
    // This stable version is used for YANG, as we do not want to update code
    // and models each time a keyword is added to the syntax.
    {
        // Kea DHCPv4 server configuration begins here.
        "Dhcp4": {
            // Global flag selecting an IP address allocation strategy for all
            // subnets. Use "random" for a random allocation strategy.
            "allocator": "iterative",

            // Global authoritative flag to handle requests by clients for
            // unknown IP addresses (ignore if disabled, NAK if enabled).
            "authoritative": false,

            // Global bootfile name to be set in the 'file' field.
            "boot-file-name": "/dev/null",

            // Ordered list of client classes used by the DHCPv4 server.
            "client-classes": [
                {
                    // Class-specific bootfile name to be set in the 'file' field.
                    "boot-file-name": "/usr/local/share/kea/bootfile.efi",

                    // Class name.
                    "name": "phones_server1",

                    // Class-specific next server address to use in bootstrap, which
                    // is set in 'siaddr' field.
                    "next-server": "10.2.3.4",

                    // Class-specific DHCPv4 options list.
                    "option-data": [],

                    // Class-specific DHCPv4 option definitions, i.e. custom formats
                    // specified for non-standard options.
                    "option-def": [],

                    // Class-specific optional server hostname, which is set in
                    // 'sname' field.
                    "server-hostname": "",

                    // Class selection expression. The DHCP packet is assigned to this
                    // class when the given expression evaluates to true.
                    "test": "member('HA_server1')",

                    // Class valid lifetime.
                    "valid-lifetime": 6000,

                    // Class min valid lifetime.
                    "min-valid-lifetime": 4000,

                    // Class max valid lifetime.
                    "max-valid-lifetime": 8000,

                    // If greater than zero, it is the lifetime of leases temporarily allocated
                    // on DISCOVER. When zero (the default), leases are not allocated on DISCOVER.
                    "offer-lifetime" : 65
                },
                {
                    // Default value of the class-specific bootfile name. An empty name
                    // means that the bootfile name is unspecified.
                    "boot-file-name": "",

                    // Second class name.
                    "name": "phones_server2",

                    // Default value of the class-specific next server address. The
                    // zero IPv4 address means that it is unspecified.
                    "next-server": "0.0.0.0",

                    // Class-specific DHCPv4 options list.
                    "option-data": [],

                    // Class-specific DHCPv4 option definitions, i.e. custom formats
                    // specified for non-standard options.
                    "option-def": [],

                    // Class-specific optional server hostname, which is set in
                    // 'sname' field.
                    "server-hostname": "",

                    // Class selection expression. The DHCP packet is assigned to this
                    // class when the given expression evaluates to true.
                    "test": "member('HA_server2')"
                },
                {
                    // Third class name.
                    "name": "late",

                    // Boolean flag indicating whether the class expression is only evaluated
                    // when the selected configuration (i.e. pool, subnet, shared-network)
                    // includes this class name in its "evaluate-additional-classes" list. The
                    // default value false means that the class test expression must
                    // always be evaluated.
                    "only-in-additional-list": true,

                    // Class selection expression.
                    "test": "member('ALL')"
                },
                {
                    // Fourth class name.
                    "name": "my-template-class",

                    // Template class flag that holds the expression used to generate the names for all
                    // the spawned subclasses. In this case, the classes are named after the client ID.
                    "template-test": "substring(option[61].hex, 0, all)"
                }
            ],

            // Parameters for triggering behaviors compatible with broken or
            // non-compliant clients, relays, or other agents
            "compatibility": {
                // Ignore DHCP Server Identifier option if set to true.
                // Enabling this will cause Kea to accept any query, even
                // if the address in the option belongs to another server,
                // instead of dropping it. This config option defaults to
                // false, as enabling it breaks RFC compliance.
                "ignore-dhcp-server-identifier": false,

                // Ignore Relay Agent Information Link Selection suboption if set
                // to true. Enabling this will cause Kea to use normal subnet
                // selection logic instead of attempting to use the subnet
                // specified in the suboption. This config option defaults to
                // false, as enabling it breaks RFC compliance.
                "ignore-rai-link-selection": false,

                // Parse options more leniently where fields can be deduced
                // deterministically, even if against RFC or common practice.
                "lenient-option-parsing": true,

                // Boolean flag indicating whether .0 and .255 addresses
                // must be considered as never free in subnets with a prefix length
                // of 24 or less. The default is false, as these addresses are not
                // special; only the first and the last addresses are.
                "exclude-first-last-24": false
            },

            // Command control socket configuration parameters for the Kea DHCPv4 server.
            "control-sockets": [
                {
                    // Control socket type used by the Kea DHCPv4 server.
                    // Must be unix, http or https.
                    "socket-type": "unix",

                   // Location of the UNIX domain socket file the DHCPv4
                   // server uses to receive control commands from the
                   // local server administrator.
                   "socket-name": "kea4-ctrl-socket"
                },
                {
                    // Control socket type used by the Kea DHCPv4 server.
                    // Must be unix, http or https.
                    "socket-type": "https",

                    // Address of the HTTPS socket the Kea DHCPv4 server should
                    // listen for incoming queries.
                    "socket-address": "127.0.0.1",

                    // Port of the HTTPS socket the Kea DHCPv4 server
                    // should listen for incoming queries. If enabling HA
                    // and multi-threading, the 8000 port is used by the
                    // HA hook library http listener. When using HA hook
                    // library with multi-threading to function, make sure
                    // the port used by dedicated listener is different
                    // (e.g. 8001) than the one specified here.  Note the
                    // commands should still be sent to a control socket.
                    // The dedicated listener is specifically for HA
                    // updates only.
                    "socket-port": 8004,

                    // TLS trust anchor (Certificate Authority). This is a
                    // file name or a directory path. Make sense with other
                    // TLS parameters only for the https control socket type.
                    "trust-anchor": "my-ca",

                    // TLS server certificate file name.
                    "cert-file": "my-cert",

                    // TLS server private key file name.
                    "key-file": "my-key",

                    // TLS require client certificates flag. Default is
                    // true and means require client certificates. False
                    // means they are optional.
                    "cert-required": true,

                    // Extra HTTP headers to add in responses.
                    "http-headers":
                    [
                        {
                            // Optional user context.
                            "user-context": { "comment": "HSTS header" },

                            // Required HTTP header name.
                            "name": "Strict-Transport-Security",

                            // Required HTTP header value.
                            "value": "max-age=31536000"
                        }
                    ],

                    // Optional authentication.
                    "authentication": {

                        // Required authentication type. The only
                        // supported value is basic for the basic HTTP
                        // authentication.
                        "type": "basic",

                        // An optional parameter is the basic HTTP
                        // authentication realm.  Its default is
                        // "kea-dhcpv4-server"
                        "realm": "kea-dhcpv4-server",

                        // This optional parameter can be used to specify a common
                        // prefix for files handling client credentials.
                        "directory": "/usr/local/share/kea/kea-creds",

                        // This list specifies the user ids and passwords
                        // to use for basic HTTP authentication. If empty
                        // or not present any client is authorized.
                        "clients": [
                            // This specifies an authorized client.
                            {
                                // The user id must not be empty or
                                // contain the ':' character. It is a
                                // mandatory parameter.
                                "user": "admin",

                                // If password is not specified an empty
                                // password is used.
                                "password": "1234"
                            },

                            // This specifies a hidden client.
                            {
                                // The user id is the content of the
                                // file /usr/local/share/kea/kea-creds/hiddenu.
                                "user-file": "hiddenu",

                                // The password is the content of the
                                // file /usr/local/share/kea/kea-creds/hiddenp.
                                "password-file": "hiddenp"
                            },

                            // This specifies a hidden client using a
                            // secret in a file.
                            {
                                // The secret is the content of the file
                                // /usr/local/share/kea/kea-creds/hiddens which must be in
                                // the <user-id>:<password> format.
                                "password-file": "hiddens"
                            }
                        ]
                    }
                }
            ],

            // Specifies a prefix to be prepended to the generated Client FQDN.
            // It may be specified at the global, shared-network, and subnet levels.
            "ddns-generated-prefix": "myhost",

            // Boolean flag indicating whether the server should ignore DHCP client
            // wishes to update DNS on its own. With that flag set to true,
            // the server will send DNS updates for both forward and
            // reverse DNS data. The default value is false, which indicates
            // that the server will delegate a DNS update to the client when
            // requested. It may be specified at the global, shared-network,
            // and subnet levels.
            "ddns-override-client-update": false,

            // Boolean flag indicating whether the server should override the DHCP
            // client's wish to not update the DNS. With this parameter
            // set to true, the server will send a DNS update even when
            // the client requested no update. It may be specified at the
            // global, shared-network, and subnet levels.
            "ddns-override-no-update": false,

            // Suffix appended to the partial name sent to the DNS. The
            // default value is an empty string, which indicates that no
            // suffix is appended. It may be specified at the global,
            // shared-network, and subnet levels.
            "ddns-qualifying-suffix": "",

            // Enumeration specifying whether the server should honor
            // the hostname or Client FQDN sent by the client or replace
            // this name. The acceptable values are: "never" (use the
            // name the client sent), "always" (replace the name the
            // client sent), "when-present" (replace the name the client
            // sent, but do not generate one when the client didn't send
            // the name), "when-not-present" (generate the name when
            // client didn't send one, otherwise leave the name the
            // client sent). The default value is "never". It may be
            // specified at the global, shared-network, and subnet levels.
            "ddns-replace-client-name": "never",

            // Boolean flag which enables or disables DDNS updating. It
            // defaults to true. It may be specified at the global, shared-
            // network, and subnet levels. It works in conjunction with
            // dhcp-ddns:enable-updates, which must be true to enable connectivity
            // to kea-dhcp-ddns.
            "ddns-send-updates": true,

            // Boolean flag, which when true instructs the server to always
            // update DNS when leases are renewed, even if the DNS information
            // has not changed. The server's default behavior (i.e. flag is false)
            // is to only update DNS if the DNS information has changed. It
            // may be specified at the global, shared-network, and subnet levels.
            "ddns-update-on-renew": true,

            // Boolean flag which is passed to kea-dhcp-ddns with each DDNS
            // update request, to indicate whether DNS update conflict
            // resolution as described in RFC 4703 should be employed for the
            // given update request. The default value for this flag is true.
            // It may be specified at the global, shared-network, and subnet levels.
            // This field has been replaced by ddns-conflict-resolution-mode.
            // Parsing is maintained only for backwards compatibility.
            // "ddns-use-conflict-resolution": true,

            // Enumeration, which is passed to kea-dhcp-ddns with each DDNS
            // update request to indicate the mode used for resolving conflicts
            // while performing DDNS updates. The acceptable values are:
            // check-with-dhcid (this includes adding a DHCID record and checking
            // that record via conflict detection as per RFC 4703,
            // no-check-with-dhcid (this will ignore conflict detection but add
            // a DHCID record when creating/updating an entry),
            // check-exists-with-dhcid (this will check if there is an existing
            // DHCID record but does not verify the value of the record matches
            // the update. This will also update the DHCID record for the entry),
            // no-check-without-dhcid (this ignores conflict detection and will
            // not add a DHCID record when creating/updating a DDNS entry).
            // The default value is "check-with-dhcid". It may be
            // specified at the global, shared-network and subnet levels.
            "ddns-conflict-resolution-mode": "check-with-dhcid",

            // When greater than 0.0, it is the percent of the lease's lifetime
            // to use for the DNS TTL.
            "ddns-ttl-percent": 0.75,

            // When greater than 0 it will be used as the DNS TTL. Specified in seconds.
            // You cannot specify both ddns-ttl and any of ddns-ttl-percent, ddns-ttl-min, or
            // ddns-ttl-max. They are mutually exclusive.
            // "ddns-ttl": 500,

            // When greater than 0 it used as the lower boundary for calculated DNS TTL values.
            // Specified in seconds.
            "ddns-ttl-min": 24000,

            // When greater than 0 it used as the upper boundary for calculated DNS TTL values.
            // Specified in seconds.
            "ddns-ttl-max": 64000,

            // Time in seconds specifying how long a declined lease should be
            // excluded from DHCP assignments. The default value is 86400 (24 hours).
            "decline-probation-period": 86400,

            // Name Change Request forwarding configuration for the Kea DHCPv4 server.
            // NCRs are sent to the Kea D2 module to update DNS upon allocation of
            // DHCP leases.
            "dhcp-ddns": {
                // Boolean flag indicating whether Kea DHCPv4 server should connect to
                // kea-dhcp-ddns. This must be true for NCRs to be created and
                // sent to kea-dhcp-ddns. By default, NCRs are not generated.
                "enable-updates": false,

                // Specifies maximum number of NCRs to queue waiting to be sent
                // to the Kea D2 server.
                "max-queue-size": 1024,

                // Packet format to use when sending NCRs to the Kea D2 server.
                // Currently, only JSON format is supported.
                "ncr-format": "JSON",

                // Socket protocol to use when sending NCRs to D2. Currently,
                // only UDP is supported.
                "ncr-protocol": "UDP",

                // IP address that the Kea DHCPv4 server should use to send
                // NCRs to D2. The default value of zero indicates that Kea
                // should pick a suitable address.
                "sender-ip": "0.0.0.0",

                // Port number that the Kea DHCPv4 server should use to send
                // NCRs to D2. The default value of zero indicates that Kea
                // should pick a suitable port.
                "sender-port": 0,

                // IP address on which D2 listens for NCRs.
                "server-ip": "127.0.0.1",

                // Port number on which D2 listens for NCRs.
                "server-port": 53001
            },

            // Specifies the first of the two consecutive ports of the UDP
            // sockets used for communication between DHCPv6 and DHCPv4
            // servers. See RFC 7341. (defaults to 0 - disabled).
            // If enabled, use e.g. 786.
            "dhcp4o6-port": 0,

            // Boolean flag indicating whether the Kea DHCPv4 server
            // should send back the Client Identifier option in its responses.
            // The default value is true, which indicates that the option
            // must be sent back if the client included it. The false
            // value instructs the server to not send this option for
            // backward compatibility with older DHCP specifications, which
            // stated that Client Identifier must not be sent back.
            "echo-client-id": true,

            // Collection of Kea DHCPv4 server parameters configuring how
            // the server should process expired DHCP leases.
            "expired-leases-processing": {
                // Specifies the number of seconds since the last removal of
                // the expired leases, when the next removal should occur.
                // If both "flush-reclaimed-timer-wait-time" and
                // "hold-reclaimed-time" are not 0, when the client sends a release
                // message the lease is expired instead of being deleted from
                // lease storage.
                "flush-reclaimed-timer-wait-time": 25,

                // Specifies the length of time in seconds to keep expired
                // leases in the lease database (lease affinity).
                // If both "flush-reclaimed-timer-wait-time" and
                // "hold-reclaimed-time" are not 0, when the client sends a release
                // message the lease is expired instead of being deleted from
                // lease storage.
                "hold-reclaimed-time": 3600,

                // Specifies the maximum number of expired leases that can be
                // processed in a single attempt to clean up expired leases
                // from the lease database. If there are more
                // expired leases, they will be processed during the next
                // cleanup attempt.
                "max-reclaim-leases": 100,

                // Specifies the maximum time in milliseconds that a single attempt
                // to clean up expired leases from the lease database may take.
                "max-reclaim-time": 250,

                // Specifies the length of time in seconds since the last attempt
                // to process expired leases before initiating the next attempt.
                "reclaim-timer-wait-time": 10,

                // Specifies the maximum number of expired lease-processing cycles
                // which didn't result in full cleanup of expired leases from the
                // lease database, after which a warning message is issued.
                "unwarned-reclaim-cycles": 5
            },

            // List of hook libraries and their specific configuration parameters
            // to be loaded by Kea DHCPv4 server.
            "hooks-libraries": [
                {
                    // Location of the hook library to be loaded.
                    "library": "libdhcp_lease_cmds.so",

                    // Hook library-specific configuration parameters.
                    "parameters": { }
                },
                {
                    // The MySQL host backend hook library required for host storage.
                    "library": "libdhcp_mysql.so"
                },
                {
                    // The PostgreSQL host backend hook library required for host storage.
                    "library": "libdhcp_pgsql.so"
                }
            ],

            // List of access credentials to external sources of IPv4 reservations,
            "hosts-databases": [
                {
                    // Name of the database to connect to.
                    "name": "keatest",

                    // Host on which the database resides.
                    "host": "localhost",

                    // Database password.
                    "password": "1234",

                    // Port on which the database is available.
                    "port": 3306,

                    // Type of database, e.g. "mysql", "postgresql".
                    "type": "mysql",

                    // Username to be used to access the database.
                    "user": "keatest",

                    // Read-only mode.
                    "readonly": false,

                    // The next entries are for OpenSSL support in MySQL.

                    // Trust anchor aka certificate authority file or directory.
                    "trust-anchor": "my-ca",

                    // Client certificate file name.
                    "cert-file": "my-cert",

                    // Private key file name.
                    "key-file": "my-key",

                    // Cipher list (see the OpenSSL ciphers command manual).
                    "cipher-list": "AES",

                    // Connection reconnect wait time.
                    // This parameter governs how long Kea waits before attempting
                    // to reconnect. Expressed in milliseconds. The default is 0
                    // (disabled) for MySQL and PostgreSQL.
                    "reconnect-wait-time": 3000,

                    // Connection maximum reconnect tries.
                    "max-reconnect-tries": 3,

                    // Action to take when connection recovery fails.
                    // Supported values: stop-retry-exit, serve-retry-exit,
                    // serve-retry-continue
                    "on-fail": "stop-retry-exit",

                    // Flag which indicates if the DB recovery should be attempted
                    // at server startup and on reconfiguration events.
                    "retry-on-startup": false,

                    // Connection connect timeout in seconds.
                    "connect-timeout": 100,

                    // Timeout of database read operations in seconds.
                    "read-timeout": 120,

                    // Timeout of database write operations in seconds.
                    "write-timeout": 180
                },
                {
                    // Name of the database to connect to.
                    "name": "keatest",

                    // Host on which the database resides.
                    "host": "localhost",

                    // Database password.
                    "password": "1234",

                    // Port on which the database is available.
                    "port": 5432,

                    // Type of database, e.g. "mysql", "postgresql".
                    "type": "postgresql",

                    // Username to be used to access the database.
                    "user": "keatest",

                    // TCP user timeout while communicating with the database.
                    // It is specified in seconds.
                    "tcp-user-timeout": 100,

                    // Trust anchor aka certificate authority file or directory.
                    "trust-anchor": "my-ca",

                    // Client certificate file name.
                    "cert-file": "my-cert",

                    // Private key file name.
                    "key-file": "my-key",

                    // SSL mode.
                    "ssl-mode": "verify-ca"
                }
            ],

            // List of host reservation identifier types to be used by the
            // Kea DHCPv4 server to fetch static reservations for
            // DHCP clients. All identifiers are used by default, which
            // means that the server will issue multiple queries to the
            // database to find if there is a reservation for a particular
            // client. If a particular deployment uses only a subset, e.g.
            // one identifier type, this identifier should be only listed
            // here to prevent unnecessary queries to the database.
            "host-reservation-identifiers": [
                "hw-address",
                "duid",
                "circuit-id",
                "client-id",
                "flex-id"
            ],

            // Specifies configuration of interfaces on which the Kea DHCPv4
            // server is listening to the DHCP queries.
            "interfaces-config": {
                // Specifies whether the server should use "udp" sockets or
                // "raw" sockets to listen to DHCP traffic. The "raw"
                // sockets are useful when direct DHCP traffic is being
                // received.
                "dhcp-socket-type": "udp",

                // Specifies a list of interfaces on which the Kea DHCPv4
                // server should listen to DHCP requests.
                "interfaces": [
                    "eth0"
                ],

                // Enumeration which indicates what interface should be used
                // to send DHCP responses to the client. The default value is
                // "same-as-inbound", which indicates that the response should
                // be sent via the interface on which the client's query
                // was received. The "use-routing" value indicates that the
                // Kea server should use the kernel's routing table to find a
                // suitable interface.
                "outbound-interface": "same-as-inbound",

                // Boolean flag indicating whether the available interfaces should
                // be re-detected upon server reconfiguration. The default value
                // is true, which means that the interfaces are always
                // re-detected.
                "re-detect": true,

                // Kea tries to bind the service sockets during initialization, but it may
                // fail due to a port being already opened or a misconfiguration. Kea can
                // suppress these errors and only log them. This flag prevents starting
                // the DHCP server without binding all sockets. If unspecified, it
                // defaults to false.
                "service-sockets-require-all": true,

                // Kea tries to bind the service sockets during initialization. This
                // option specifies how many times binding to interface will be retried.
                // The default value is 0, which means that the operation will not be
                // repeated.
                "service-sockets-max-retries": 5,

                // The time interval in milliseconds to wait before the next attempt to
                // retry opening a service socket.
                "service-sockets-retry-wait-time": 5000
            },

            // Boolean parameter which controls whether an early global host
            // reservations lookup should be performed. This lookup takes place
            // before subnet selection and when a global reservation is found
            // with some client classes, it triggers a second phase classification.
            // It can also be used to drop queries using host reservations as a
            // decision table indexed by reservation identifiers.
            "early-global-reservations-lookup": true,

            // Boolean parameter which controls the DHCP server's behavior with respect
            // to creating host reservations for the same IP address. By default
            // this flag is set to true, in which case the server prevents creation
            // of multiple host reservations for the same IP address. When this
            // parameter is set to false, the server allows for creating multiple
            // reservations for the same IP address within a subnet. This setting
            // is useful in deployments in which a given host may be communicating
            // with a DHCP server over multiple interfaces and, depending on the
            // chosen interface, a different MAC address (or other identifier) will
            // be used to identify the host. Note that some host backends do not
            // support the mode in which multiple reservations for the same IP
            // address are used. If these backends are in use and this setting
            // is attempted, a configuration error will occur. The MySQL and
            // PostgreSQL backends do support this mode.
            "ip-reservations-unique": true,

            // Boolean parameter which controls whether host reservations lookup
            // should be performed before lease lookup. This parameter has effect
            // only when multi-threading is disabled. When multi-threading is
            // enabled, host reservations lookup is always performed first to avoid
            // lease-lookup resource locking.
            "reservations-lookup-first": true,

            // Specifies credentials to access lease database.
            "lease-database": {
                // memfile backend-specific parameter specifying the interval
                // in seconds at which the lease file should be cleaned up (outdated
                // lease entries are removed to prevent the lease file from growing
                // infinitely).
                "lfc-interval": 3600,

                // Maximum number of lease-file read errors allowed before
                // loading the file is abandoned. Defaults to 0 (no limit).
                "max-row-errors": 100,

                // Name of the lease file. In the case of a database it specifies the
                // database name.
                "name": "kea-leases4.csv",

                // memfile-specific parameter indicating whether leases should
                // be saved on persistent storage (disk) or not. The true value
                // is the default and it indicates that leases are stored in
                // persistent storage. This setting must be used in production.
                // The false value should only be used for testing purposes
                // because non-stored leases will be lost upon Kea server restart.
                "persist": true,

                // Lease database backend type, i.e. "memfile", "mysql" or
                // "postgresql".
                "type": "memfile"
            },

            // Boolean value indicating whether the Kea DHCPv4 server should use the client
            // identifier value sent by the client or ignore it. The default value
            // is true, which indicates that the server should use the client identifier
            // and that it takes precedence over the client's MAC address. In deployments
            // where MAC address should take precedence, this value can be set to
            // false, in which case the clients will be identified by MAC address.
            // This is specifically useful when clients don't generate unique
            // identifiers or these identifiers are not stable, etc.
            "match-client-id": false,

            // Global value of the next server address set in 'siaddr' field.
            // The global value may be overridden in lower-level configuration
            // scopes.
            "next-server": "192.0.2.123",

            // Global value which limits the number of client packets (e.g.
            // DHCPREQUESTs) that may be parked while waiting for hook library
            // work to complete, prior to a response (e.g. DHCPACK) being sent
            // back to the client. A typical example is when kea-dhcp4 parks a
            // DHCPREQUEST while it sends the lease update(s) to its HA peer(s).
            // The packet is unparked once the update(s) have been acknowledged.
            // This value limits the number of packets that can be held pending
            // the updates. In times of heavy client traffic, this value can keep
            // kea-dhcp4 from building an insurmountable backlog of updates.
            "parked-packet-limit": 256,

            // List of global DHCP options that the Kea DHCPv4 server assigns to
            // clients.
            "option-data": [
                {
                    // Boolean flag indicating whether the given option is always
                    // sent in response or only when requested. The default
                    // value of false indicates that it is only sent when
                    // requested.
                    "always-send": false,

                    // An optional list of classes for which this option applies.
                    // If the the client matches any of the classes in this list the
                    // option will be applied. If the list is empty or is
                    // omitted this option will be applied regardless of class
                    // membership.
                    "client-classes": [ "class1", "class2" ],

                    // Option code. It is not required if the option name is
                    // provided.
                    "code": 6,

                    // Boolean value indicating whether the option data specified
                    // in the "data" field is specified as a string of hexadecimal
                    // digits or in human-readable CSV format.
                    "csv-format": true,

                    // Option data to be stored in the option payload.
                    "data": "192.0.3.1, 192.0.3.2",

                    // Option name. It is not required if the option code is
                    // provided.
                    "name": "domain-name-servers",

                    // Boolean flag indicating whether the given option is never
                    // sent in response. The default value of false indicates
                    // that it is sent when it should be. When true, the option
                    // is not sent despite any other setting, i.e. it is
                    // a final flag.
                    "never-send": false,

                    // Option space. The default is the "dhcp4" option space which
                    // groups top-level DHCPv4 options.
                    "space": "dhcp4"
                }
            ],

            // List of global option definitions, i.e. option formats, that the
            // Kea DHCPv4 server is using.
            "option-def": [
                {
                    // Boolean flag indicating whether the option definition comprises
                    // an array of values of some type, e.g. an array of IPv4 addresses.
                    // The default value of false means that the option does not
                    // comprise an array of values.
                    "array": false,

                    // Option code.
                    "code": 6,

                    // Holds a name of the option space encapsulated by this option.
                    // All options that belong to this option space will be sent
                    // as sub-options of this option. An empty string means that this
                    // option doesn't encapsulate any option.
                    "encapsulate": "",

                    // Option name.
                    "name": "my-option",

                    // Specifies the types of fields within the option if the option
                    // is said to be a "record" (see "type"). In this particular example
                    // this option comprises two fields, 1 byte and 2 bytes long.
                    "record-types": "uint8, uint16",

                    // Name of the option space to which this option belongs.
                    "space": "my-space",

                    // Option type. All possible types are listed in the Kea
                    // Administrator Reference Manual.
                    "type": "record"
                }
            ],

            // Global value for the rebind timer, i.e. the time after which the
            // DHCP client enters the rebind state if it fails to renew the lease.
            "rebind-timer": 40,

            // Global value for the renew timer, i.e. the time after which the
            // DHCP client renews the lease.
            "renew-timer": 30,

            // Global value to store extended information (e.g. relay agent
            // information) with each lease.
            "store-extended-info": true,

            // Statistics keep some samples per observation point.
            // There are two default values: maximum count and maximum age.
            // Setting the maximum count to zero disables it.
            "statistic-default-sample-count": 0,

            // When the maximum count is 0 the maximum age (in seconds) applies.
            "statistic-default-sample-age": 60,

            // Multi-threading parameters.
            "multi-threading": {
                // By default, Kea processes packets on multiple threads if the hardware permits.
                "enable-multi-threading": true,

                // When multi-threading is enabled, Kea will process packets on a
                // number of multiple threads configurable through this option. The
                // value must be a positive integer (0 means auto-detect).
                "thread-pool-size": 0,

                // When multi-threading is enabled, Kea will read packets from the
                // interface and append a working item to the thread pool. This
                // option configures the maximum number of items that can be queued.
                // The value must be a positive integer (0 means unlimited).
                "packet-queue-size": 0
            },

            // Governs how the Kea DHCPv4 server should deal with invalid
            // data received from the client.
            "sanity-checks": {
                // Specifies how the Kea DHCPv4 server should behave when invalid
                // data is read for a lease from the lease file. The following
                // values are supported: "none" (don't attempt to correct the
                // lease information), "warn" (print a warning for subnet-id
                // related inconsistencies), "fix" (correct the subnet id by
                // trying to find the suitable subnet), "fix-del" (similar
                // to "fix" but delete the lease if no suitable subnet found),
                // "del" (delete the lease if the lease has invalid subnet
                // identifier value).
                "lease-checks": "warn",

                // Specifies how Kea DHCPv4 server should behave when invalid
                // extended info is read for a lease from the lease file, or
                // whether to upgrade from the old format. The following values
                // are supported: "none" (don't attempt to correct or upgrade
                // the extended info), "fix" (fix common inconsistencies and
                // upgrade from the old format; this is the default), "strict"
                // (fix inconsistencies with an impact on Leasequery),
                // "pedantic" (enforce full Kea code format).
                "extended-info-checks": "fix"
            },

            // List of shared networks used by the Kea DHCPv4 server. The shared
            // networks group subnets together.
            "shared-networks": [
                {
                    // A flag selecting an IP address allocation strategy for all
                    // subnets in this shared network.
                    "allocator": "random",

                    // Shared-network level authoritative flag.
                    "authoritative": false,

                    // Shared-network level bootfile name.
                    "boot-file-name": "/dev/null",

                    // Restricts this shared network to allow only clients
                    // that belong to at least one class in this list. If omitted
                    // or an empty list is provided, no restriction is applied.
                    "client-classes": [],

                    // Shared-network level value. See description at the global level.
                    "ddns-generated-prefix": "myhost",

                    // Shared-network level value. See description at the global level.
                    "ddns-override-client-update": false,

                    // Shared-network level value. See description at the global level.
                    "ddns-override-no-update": false,

                    // Shared-network level value. See description at the global level.
                    "ddns-qualifying-suffix": "",

                    // Shared-network level value. See description at the global level.
                    "ddns-replace-client-name": "never",

                    // Shared-network level value. See description at the global level.
                    "ddns-send-updates": true,

                    // Shared-network level value. See description at the global level.
                    "ddns-update-on-renew": true,

                    // Shared-network level value. See description at the global level.
                    // This field has been replaced by ddns-conflict-resolution-mode.
                    // Parsing is maintained only for backwards compatibility.
                    // "ddns-use-conflict-resolution": true,

                    // Shared-network level value. See description at the global level.
                    "ddns-conflict-resolution-mode": "check-with-dhcid",

                    // Shared-network level value. See description at the global level.
                    "ddns-ttl-percent": 0.65,

                    // Shared-network level value. See description at the global level.
                    // You cannot specify both ddns-ttl and any of ddns-ttl-percent, ddns-ttl-min, or
                    // ddns-ttl-max. They are mutually exclusive.
                    // "ddns-ttl": 500,

                    // Shared-network level value. See description at the global level.
                    "ddns-ttl-min": 10000,

                    // Shared-network level value. See description at the global level.
                    "ddns-ttl-max": 20000,

                    // Shared-network level value. See description at the global level.
                    "hostname-char-replacement": "x",

                    // Shared-network level value. See description at the global level.
                    "hostname-char-set": "[^A-Za-z0-9.-]",

                    // Specifies that this shared network is selected for
                    // requests received on a particular interface.
                    "interface": "eth0",

                    // Shared-network level flag specifying whether the client
                    // identifier should be used for identifying clients.
                    "match-client-id": true,

                    // Shared network name.
                    "name": "my-secret-network",

                    // Shared-network level specification of the next server
                    // to be sent in 'siaddr'.
                    "next-server": "192.0.2.123",

                    // If greater than zero, it is the lifetime of leases temporarily allocated
                    // on DISCOVER. When zero (the default), leases are not allocated on DISCOVER.
                    "offer-lifetime" : 60,

                    // List of shared network-specific DHCP options.
                    "option-data": [],

                    // List of IPv4 relay addresses for which this shared
                    // network is selected.
                    "relay": {
                        "ip-addresses": []
                    },

                    // Shared-network level rebind timer.
                    "rebind-timer": 41,

                    // Shared-network level renew timer.
                    "renew-timer": 31,

                    // Shared-network level compute T1 and T2 timers.
                    "calculate-tee-times": true,

                    // T1 = valid lifetime * .5.
                    "t1-percent": .5,

                    // T2 = valid lifetime * .75.
                    "t2-percent": .75,

                    // Cache threshold = valid lifetime * .25.
                    "cache-threshold": .25,

                    // Cache maximum: when the client last-transmission time
                    // is close enough, the lease is not renewed and the current
                    // lease is returned as it was "cached".
                    "cache-max-age": 1000,

                    // Adaptive lease time threshold (1.0 is disabled).
                    "adaptive-lease-time-threshold": 0.8,

                    // Specify whether the server should look up global reservations.
                    "reservations-global": false,

                    // Specify whether the server should look up in-subnet reservations.
                    "reservations-in-subnet": true,

                    // Specify whether the server can assume that all reserved addresses
                    // are out-of-pool.
                    // Ignored when reservations-in-subnet is false.
                    // If specified, it is inherited by "subnet4" levels.
                    "reservations-out-of-pool": false,

                    // List of client classes which must be evaluated when this shared
                    // network is selected for client assignments.
                    "evaluate-additional-classes": [ "late" ],

                    // Turn off storage of extended information (e.g. relay agent
                    // information) with each lease for this shared network.
                    "store-extended-info": false,

                    // Shared-network level server hostname set in 'sname' field.
                    "server-hostname": "",

                    // List of IPv4 subnets belonging to this shared network.
                    "subnet4": [
                        {
                            // Interface name matched against inbound interface name.
                            // Used in DHCPv4o6. See RFC 7341.
                            "4o6-interface": "",

                            // Interface ID option value. See RFC 7341.
                            "4o6-interface-id": "",

                            // Prefix matched against source address. See RFC7341.
                            "4o6-subnet": "2001:db8:1:1::/64",

                            // A flag selecting an IP address allocation strategy for
                            // the subnet.
                            "allocator": "iterative",

                            // Subnet-level authoritative flag.
                            "authoritative": false,

                            // Subnet-level bootfile name, set in 'file' field.
                            "boot-file-name": "",

                            // Restricts this subnet to allow only clients
                            // that belong to at least one class in this list. If omitted
                            // or an empty list is provided, no restriction is applied.
                            "client-classes": [],

                            // Subnet-level value. See description at the global level.
                            "ddns-generated-prefix": "myhost",

                            // Subnet-level value. See description at the global level.
                            "ddns-override-client-update": false,

                            // Subnet-level value. See description at the global level.
                            "ddns-override-no-update": false,

                            // Subnet-level value. See description at the global level.
                            "ddns-qualifying-suffix": "",

                            // Subnet-level value. See description at the global level.
                            "ddns-replace-client-name": "never",

                            // Subnet-level value. See description at the global level.
                            "ddns-send-updates": true,

                            // Subnet-level value. See description at the global level.
                            "ddns-update-on-renew": true,

                            // Shared-network level value. See description at the global level.
                            // This field has been replaced by ddns-conflict-resolution-mode.
                            // Parsing is maintained only for backwards compatibility.
                            // "ddns-use-conflict-resolution": true,

                            // Subnet-level value. See description at the global level.
                            "ddns-conflict-resolution-mode": "check-with-dhcid",

                            // Subnet-level value. See description at the global level.
                            // "ddns-ttl-percent": 0.55,

                            // Subnet-level value. See description at the global level.
                            // You cannot specify both ddns-ttl and any of ddns-ttl-percent, ddns-ttl-min, or
                            // ddns-ttl-max. They are mutually exclusive.
                            "ddns-ttl": 500,

                            // Subnet-level value. See description at the global level.
                            // "ddns-ttl-min": 10000,

                            // Subnet-level value. See description at the global level.
                            // "ddns-ttl-max": 20000,

                            // Subnet-level value. See description at the global level.
                            "hostname-char-replacement": "x",

                            // Subnet-level value. See description at the global level.
                            "hostname-char-set": "[^A-Za-z0-9.-]",

                            // Subnet unique identifier.
                            "id": 1,

                            // Specifies that this subnet is selected for requests
                            // received on a particular interface.
                            "interface": "eth0",

                            // Subnet-level flag specifying whether the client identifier
                            // should be used for identifying clients.
                            "match-client-id": true,

                            // Subnet-level specification of the next server to be sent
                            // in 'siaddr'.
                            "next-server": "0.0.0.0",

                            // If greater than zero, it is the lifetime of leases temporarily allocated
                            // on DISCOVER. When zero (the default), leases are not allocated on DISCOVER.
                            "offer-lifetime" : 60,

                            // Turn on storage of extended information (e.g. relay agent
                            // information) with each lease for this subnet.
                            "store-extended-info": true,

                            // Subnet-level list of DHCP options.
                            "option-data": [
                                {
                                    // Boolean flag indicating whether the particular option
                                    // should be always sent or sent only when requested.
                                    "always-send": false,

                                    // An optional list of classes for which this option applies.
                                    // If the the client matches any of the classes in this list the
                                    // option will be applied. If the list is empty or is
                                    // omitted this option will be applied regardless of class
                                    // membership.
                                    "client-classes": [],

                                    // Option code.
                                    "code": 3,

                                    // Boolean flag indicating whether the option value specified
                                    // in "data" is a string of hexadecimal values or human-readable
                                    // CSV value.
                                    "csv-format": true,

                                    // Option data to be included in the option payload.
                                    "data": "192.0.3.1",

                                    // Option name.
                                    "name": "routers",

                                    // Boolean flag indicating whether the given option is never
                                    // sent in response.
                                    "never-send": false,

                                    // Option space. The default value "dhcp4" designates the
                                    // top-level option space.
                                    "space": "dhcp4"
                                }
                            ],

                            // List of IP address pools belonging to the subnet.
                            "pools": [
                                {
                                    // Restricts this pool to allow only clients
                                    // that belong to at least one class in this list. If omitted
                                    // or an empty list is provided, no restriction is applied.
                                    "client-classes": [ "phones_server1" ],

                                    // Pool-level list of DHCP options.
                                    "option-data": [],

                                    // Address range used for client assignments.
                                    "pool": "192.1.0.1 - 192.1.0.200",

                                    // List of client classes which must be evaluated when this pool
                                    // is selected for client assignments.
                                    "evaluate-additional-classes": [ "late" ],

                                    // Pool-level value. See description at the global level.
                                    "ddns-generated-prefix": "mypool",

                                    // Pool-level value. See description at the global level.
                                    "ddns-override-client-update": false,

                                    // Pool-level value. See description at the global level.
                                    "ddns-override-no-update": false,

                                    // Pool-level value. See description at the global level.
                                    "ddns-qualifying-suffix": "pool.example.com.",

                                    // Pool-level value. See description at the global level.
                                    "ddns-replace-client-name": "always",

                                    // Pool-level value. See description at the global level.
                                    "ddns-send-updates": true,

                                    // Pool-level value. See description at the global level.
                                    "ddns-update-on-renew": false,

                                    // Pool-level value. See description at the global level.
                                    "ddns-conflict-resolution-mode": "check-with-dhcid",

                                    // Pool-level value. See description at the global level.
                                    "ddns-ttl-percent": 0.55,

                                    // Pool-level value. See description at the global level.
                                    // You cannot specify both ddns-ttl and any of ddns-ttl-percent,
                                    // ddns-ttl-min, or ddns-ttl-max. They are mutually exclusive.
                                    // "ddns-ttl": 500,

                                    // Pool-level value. See description at the global level.
                                    "ddns-ttl-min": 10000,

                                    // Pool-level value. See description at the global level.
                                    "ddns-ttl-max": 20000,

                                    // Pool-level value. See description at the global level.
                                    "hostname-char-replacement": "x",

                                    // Pool-level value. See description at the global level.
                                    "hostname-char-set": "[^A-Za-z0-9.-]"
                                },
                                {
                                    // Restricts this pool to allow only clients
                                    // that belong to at least one class in this list. If omitted
                                    // or an empty list is provided, no restriction is applied.
                                    "client-classes": [ "phones_server2" ],

                                    // Pool-level list of DHCP options.
                                    "option-data": [],

                                    // Address range used for client assignments.
                                    "pool": "192.3.0.1 - 192.3.0.200",

                                    // List of client classes which must be evaluated when this pool
                                    // is selected for client assignments.
                                    "evaluate-additional-classes": [],

                                    // Pool identifier used to enable statistics for this pool.
                                    // The pool ID does not need to be unique within the subnet
                                    // or across subnets.
                                    // If not unconfigured, it defaults to 0. The statistics
                                    // regarding this pool will be combined with the other statistics
                                    // of all other pools with the same pool ID in this subnet.
                                    "pool-id": 1
                                }
                            ],

                            // Subnet-level value of the rebind timer.
                            "rebind-timer": 40,

                            // List of IPv4 relay addresses for which this subnet is selected.
                            "relay": {
                                "ip-addresses": [
                                    "192.168.56.1"
                                ]
                            },

                            // Subnet-level value of the renew timer.
                            "renew-timer": 30,

                            // Specify whether the server should look up global reservations.
                            "reservations-global": false,

                            // Specify whether the server should look up in-subnet reservations.
                            "reservations-in-subnet": true,

                            // Specify whether the server can assume that all reserved
                            // addresses are out-of-pool.
                            // Ignored when reservations-in-subnet is false.
                            "reservations-out-of-pool": false,

                            // Subnet-level compute T1 and T2 timers.
                            "calculate-tee-times": true,

                            // T1 = valid lifetime * .5.
                            "t1-percent": .5,

                            // T2 = valid lifetime * .75.
                            "t2-percent": .75,

                            // Cache threshold = valid lifetime * .25.
                            "cache-threshold": .25,

                            // Subnet-level cache maximum.
                            "cache-max-age": 1000,

                            // Adaptive lease time threshold (1.0 is disabled).
                            "adaptive-lease-time-threshold": 0.8,

                            // List of static IPv4 reservations assigned to clients belonging
                            // to this subnet. For a detailed example, see reservations.json.
                            "reservations": [
                                {
                                    // Identifier used for client matching. Supported values are
                                    // "hw-address", "client-id", "duid", "circuit-id", "flex-id".
                                    "circuit-id": "01:11:22:33:44:55:66",

                                    // Reserved IP address.
                                    "ip-address": "192.0.2.204",

                                    // Hostname.
                                    "hostname": "foo.example.org",

                                    // Reservation-specific option data.
                                    "option-data": [
                                        {
                                            // Option name.
                                            "name": "vivso-suboptions",

                                            // Option data.
                                            "data": "4491"
                                        }
                                    ]
                                }
                            ],

                            // List of client classes which must be evaluated when this subnet
                            // is selected for client assignments.
                            "evaluate-additional-classes": [ "late" ],

                            // Subnet-level server hostname set in 'sname' field.
                            "server-hostname": "",

                            // Subnet prefix.
                            "subnet": "192.0.0.0/8",

                            // Subnet-level (default) valid lifetime.
                            "valid-lifetime": 6000,

                            // Subnet-level min valid lifetime.
                            "min-valid-lifetime": 4000,

                            // Subnet-level max valid lifetime.
                            "max-valid-lifetime": 8000
                        }
                    ],

                    // Shared-network level (default) valid lifetime.
                    "valid-lifetime": 6001,

                    // Shared-network level min valid lifetime.
                    "min-valid-lifetime": 4001,

                    // Shared-network level max valid lifetime.
                    "max-valid-lifetime": 8001
                }
            ],

            // Global server hostname set in the 'sname' field.
            "server-hostname": "",

            // Stash agent options (aka RAI) to make direct queries to come
            // through a relay.
            "stash-agent-options": false,

            // List of IPv4 subnets which don't belong to any shared network.
            "subnet4": [],

            // Global valid lifetime value.
            "valid-lifetime": 6000,

            // Global min valid lifetime value.
            "min-valid-lifetime": 4000,

            // Global max valid lifetime value.
            "max-valid-lifetime": 8000,

            // Reservations (examples are in other files).
            "reservations": [],

            // Configuration control (currently not used, i.e. this syntax
            // is already defined but the corresponding feature is not implemented).
            "config-control": {
                // Only the configuration databases entry is defined.
                "config-databases": [
                    {
                        // Name of the database to connect to.
                        "name": "config",

                        // Type of database, e.g. "mysql", "postgresql".
                        "type": "mysql"
                    }
                ],
                // Interval between attempts to fetch configuration updates
                // via the configuration backends used.
                "config-fetch-wait-time": 30
            },

            // Server tag.
            "server-tag": "my DHCPv4 server",

            // DHCP queue-control parameters.
            "dhcp-queue-control": {
                // Enable queue is mandatory.
                "enable-queue": true,

                // Queue type is mandatory.
                "queue-type": "kea-ring4",

                // Capacity is optional.
                "capacity": 64
            },

            // Specify whether the server should look up global reservations.
            "reservations-global": false,

            // Specify whether the server should look up in-subnet reservations.
            "reservations-in-subnet": true,

            // Specify whether the server can assume that all reserved addresses
            // are out-of-pool.
            // Ignored when reservations-in-subnet is false.
            // If specified, it is inherited by "shared-networks" and
            // "subnet4" levels.
            "reservations-out-of-pool": false,

            // Global compute T1 and T2 timers.
            "calculate-tee-times": true,

            // T1 = valid lifetime * .5.
            "t1-percent": .5,

            // T2 = valid lifetime * .75.
            "t2-percent": .75,

            // Cache threshold = valid lifetime * .25.
            "cache-threshold": .25,

            // Global cache maximum.
            "cache-max-age": 1000,

            // Adaptive lease time threshold (1.0 is disabled).
            "adaptive-lease-time-threshold": 0.8,

            // String of zero or more characters with which to replace each
            // invalid character in the hostname or Client FQDN. The default
            // value is an empty string, which will cause invalid characters
            // to be omitted rather than replaced.
            "hostname-char-replacement": "x",

            // Regular expression describing the invalid character set in
            // the hostname or Client FQDN.
            "hostname-char-set": "[^A-Za-z0-9.-]",

            // List of loggers used by the servers using this configuration file.
            "loggers": [
                {
                    // Debug level, a value between 0..99. The greater the value
                    // the more detailed the debug log.
                    "debuglevel": 99,

                    // Name of the logger.
                    "name": "kea-dhcp4",

                    // Configures how the log should be output.
                    "output-options": [
                        {
                            // Determines whether the log should be flushed to a file.
                            "flush": true,

                            // Specifies maximum filesize before the file is rotated.
                            "maxsize": 10240000,

                            // Specifies the maximum number of rotated files to be kept.
                            "maxver": 1,

                            // Specifies the logging destination.
                            "output": "stdout",

                            // Specifies log entry content
                            "pattern": "%D{%Y-%m-%d %H:%M:%S.%q} %-5p [%c/%i] %m\n"
                        }
                    ],

                    // Specifies logging severity, i.e. "ERROR", "WARN", "INFO", "DEBUG".
                    "severity": "INFO"
                }
            ],

            // If greater than zero, it is the lifetime of leases temporarily allocated
            // on DISCOVER. When zero (the default), leases are not allocated on DISCOVER.
            "offer-lifetime" : 60,

            // Look at advanced examples for the use of user-contexts.
            "user-context": { }
        }
    }

.. _config-example-kea4-all-keys-json:

------------------
kea4/all-keys.json
------------------

.. code-block::
    :linenos:

    // WARNING: This example configuration is not meant for production use.
    // The Kea DHCPv4 server will refuse this configuration because it contains
    // mutually exclusive configuration parameters.
    //
    // The primary purpose of the example file is to provide a comprehensive
    // list of parameters supported by the Kea DHCPv4 server, along with a brief
    // description of each parameter.
    //
    // This current version should be up to date, i.e. new keywords should be
    // added in this file at the same time as in the parser specification.
    {
        // Kea DHCPv4 server configuration begins here.
        "Dhcp4": {
            // Global flag selecting an IP address allocation strategy for all
            // subnets. Use "random" for a random allocation strategy.
            "allocator": "iterative",

            // Global authoritative flag to handle requests by clients for
            // unknown IP addresses (ignore if disabled, NAK if enabled).
            "authoritative": false,

            // Global bootfile name to be set in the 'file' field.
            "boot-file-name": "/dev/null",

            // Ordered list of client classes used by the DHCPv4 server.
            "client-classes": [
                {
                    // Class-specific bootfile name to be set in the 'file' field.
                    "boot-file-name": "/usr/local/share/kea/bootfile.efi",

                    // Class name.
                    "name": "phones_server1",

                    // Class-specific next server address to use in bootstrap, which
                    // is set in 'siaddr' field.
                    "next-server": "10.2.3.4",

                    // Class-specific DHCPv4 options list.
                    "option-data": [],

                    // Class-specific DHCPv4 option definitions, i.e. custom formats
                    // specified for non-standard options.
                    "option-def": [],

                    // Class-specific optional server hostname, which is set in
                    // 'sname' field.
                    "server-hostname": "",

                    // Class selection expression. The DHCP packet is assigned to this
                    // class when the given expression evaluates to true.
                    "test": "member('HA_server1')",

                    // Class valid lifetime.
                    "valid-lifetime": 6000,

                    // Class min valid lifetime.
                    "min-valid-lifetime": 4000,

                    // Class max valid lifetime.
                    "max-valid-lifetime": 8000,

                    // If greater than zero, it is the lifetime of leases temporarily allocated
                    // on DISCOVER. When zero (the default), leases are not allocated on DISCOVER.
                    "offer-lifetime" : 65
                },
                {
                    // Default value of the class-specific bootfile name. An empty name
                    // means that the bootfile name is unspecified.
                    "boot-file-name": "",

                    // Second class name.
                    "name": "phones_server2",

                    // Default value of the class-specific next server address. The
                    // zero IPv4 address means that it is unspecified.
                    "next-server": "0.0.0.0",

                    // Class-specific DHCPv4 options list.
                    "option-data": [],

                    // Class-specific DHCPv4 option definitions, i.e. custom formats
                    // specified for non-standard options.
                    "option-def": [],

                    // Class-specific optional server hostname, which is set in
                    // 'sname' field.
                    "server-hostname": "",

                    // Class selection expression. The DHCP packet is assigned to this
                    // class when the given expression evaluates to true.
                    "test": "member('HA_server2')"
                },
                {
                    // Third class name.
                    "name": "late",

                    // Boolean flag indicating whether the class expression is only evaluated
                    // when the selected configuration (i.e. pool, subnet, shared-network)
                    // includes this class name in its "evaluate-additional-classes" list. The
                    // default value false means that the class test expression must
                    // always be evaluated.
                    "only-in-additional-list": true,

                    // Class selection expression.
                    "test": "member('ALL')"
                },
                {
                    // Fourth class name.
                    "name": "my-template-class",

                    // Template class flag that holds the expression used to generate the names for all
                    // the spawned subclasses. In this case, the classes are named after the client ID.
                    "template-test": "substring(option[61].hex, 0, all)"
                }
            ],

            // Parameters for triggering behaviors compatible with broken or
            // non-compliant clients, relays, or other agents
            "compatibility": {
                // Ignore DHCP Server Identifier option if set to true.
                // Enabling this will cause Kea to accept any query, even
                // if the address in the option belongs to another server,
                // instead of dropping it. This config option defaults to
                // false, as enabling it breaks RFC compliance.
                "ignore-dhcp-server-identifier": false,

                // Ignore Relay Agent Information Link Selection suboption if set
                // to true. Enabling this will cause Kea to use normal subnet
                // selection logic instead of attempting to use the subnet
                // specified in the suboption. This config option defaults to
                // false, as enabling it breaks RFC compliance.
                "ignore-rai-link-selection": false,

                // Parse options more leniently where fields can be deduced
                // deterministically, even if against RFC or common practice.
                "lenient-option-parsing": true,

                // Boolean flag indicating whether .0 and .255 addresses
                // must be considered as never free in subnets with a prefix length
                // of 24 or less. The default is false, as these addresses are not
                // special; only the first and the last addresses are.
                "exclude-first-last-24": false
            },

            // Command control socket configuration parameters for the Kea DHCPv4 server.
            "control-sockets": [
                {
                    // Control socket type used by the Kea DHCPv4 server.
                    // Must be unix, http or https.
                    "socket-type": "unix",

                   // Location of the UNIX domain socket file the DHCPv4
                   // server uses to receive control commands from the
                   // local server administrator.
                   "socket-name": "kea4-ctrl-socket"
                },
                {
                    // Control socket type used by the Kea DHCPv4 server.
                    // Must be unix, http or https.
                    "socket-type": "https",

                    // Address of the HTTPS socket the Kea DHCPv4 server should
                    // listen for incoming queries.
                    "socket-address": "127.0.0.1",

                    // Port of the HTTPS socket the Kea DHCPv4 server
                    // should listen for incoming queries. If enabling HA
                    // and multi-threading, the 8000 port is used by the
                    // HA hook library http listener. When using HA hook
                    // library with multi-threading to function, make sure
                    // the port used by dedicated listener is different
                    // (e.g. 8001) than the one specified here.  Note the
                    // commands should still be sent to a control socket.
                    // The dedicated listener is specifically for HA
                    // updates only.
                    "socket-port": 8004,

                    // TLS trust anchor (Certificate Authority). This is a
                    // file name or a directory path. Make sense with other
                    // TLS parameters only for the https control socket type.
                    "trust-anchor": "my-ca",

                    // TLS server certificate file name.
                    "cert-file": "my-cert",

                    // TLS server private key file name.
                    "key-file": "my-key",

                    // TLS require client certificates flag. Default is
                    // true and means require client certificates. False
                    // means they are optional.
                    "cert-required": true,

                    // Extra HTTP headers to add in responses.
                    "http-headers":
                    [
                        {
                            // Optional user context.
                            "user-context": { "comment": "HSTS header" },

                            // Required HTTP header name.
                            "name": "Strict-Transport-Security",

                            // Required HTTP header value.
                            "value": "max-age=31536000"
                        }
                    ],

                    // Optional authentication.
                    "authentication": {

                        // Required authentication type. The only
                        // supported value is basic for the basic HTTP
                        // authentication.
                        "type": "basic",

                        // An optional parameter is the basic HTTP
                        // authentication realm.  Its default is
                        // "kea-dhcpv4-server"
                        "realm": "kea-dhcpv4-server",

                        // This optional parameter can be used to specify a common
                        // prefix for files handling client credentials.
                        "directory": "/usr/local/share/kea/kea-creds",

                        // This list specifies the user ids and passwords
                        // to use for basic HTTP authentication. If empty
                        // or not present any client is authorized.
                        "clients": [
                            // This specifies an authorized client.
                            {
                                // The user id must not be empty or
                                // contain the ':' character. It is a
                                // mandatory parameter.
                                "user": "admin",

                                // If password is not specified an empty
                                // password is used.
                                "password": "1234"
                            },

                            // This specifies a hidden client.
                            {
                                // The user id is the content of the
                                // file /usr/local/share/kea/kea-creds/hiddenu.
                                "user-file": "hiddenu",

                                // The password is the content of the
                                // file /usr/local/share/kea/kea-creds/hiddenp.
                                "password-file": "hiddenp"
                            },

                            // This specifies a hidden client using a
                            // secret in a file.
                            {
                                // The secret is the content of the file
                                // /usr/local/share/kea/kea-creds/hiddens which must be in
                                // the <user-id>:<password> format.
                                "password-file": "hiddens"
                            }
                        ]
                    }
                }
            ],

            // Specifies a prefix to be prepended to the generated Client FQDN.
            // It may be specified at the global, shared-network, and subnet levels.
            "ddns-generated-prefix": "myhost",

            // Boolean flag indicating whether the server should ignore DHCP client
            // wishes to update DNS on its own. With that flag set to true,
            // the server will send DNS updates for both forward and
            // reverse DNS data. The default value is false, which indicates
            // that the server will delegate a DNS update to the client when
            // requested. It may be specified at the global, shared-network,
            // and subnet levels.
            "ddns-override-client-update": false,

            // Boolean flag indicating whether the server should override the DHCP
            // client's wish to not update the DNS. With this parameter
            // set to true, the server will send a DNS update even when
            // the client requested no update. It may be specified at the
            // global, shared-network, and subnet levels.
            "ddns-override-no-update": false,

            // Suffix appended to the partial name sent to the DNS. The
            // default value is an empty string, which indicates that no
            // suffix is appended. It may be specified at the global,
            // shared-network, and subnet levels.
            "ddns-qualifying-suffix": "",

            // Enumeration specifying whether the server should honor
            // the hostname or Client FQDN sent by the client or replace
            // this name. The acceptable values are: "never" (use the
            // name the client sent), "always" (replace the name the
            // client sent), "when-present" (replace the name the client
            // sent, but do not generate one when the client didn't send
            // the name), "when-not-present" (generate the name when
            // client didn't send one, otherwise leave the name the
            // client sent). The default value is "never". It may be
            // specified at the global, shared-network, and subnet levels.
            "ddns-replace-client-name": "never",

            // Boolean flag which enables or disables DDNS updating. It
            // defaults to true. It may be specified at the global, shared-
            // network, and subnet levels. It works in conjunction with
            // dhcp-ddns:enable-updates, which must be true to enable connectivity
            // to kea-dhcp-ddns.
            "ddns-send-updates": true,

            // Boolean flag, which when true instructs the server to always
            // update DNS when leases are renewed, even if the DNS information
            // has not changed. The server's default behavior (i.e. flag is false)
            // is to only update DNS if the DNS information has changed. It
            // may be specified at the global, shared-network, and subnet levels.
            "ddns-update-on-renew": true,

            // Boolean flag which is passed to kea-dhcp-ddns with each DDNS
            // update request, to indicate whether DNS update conflict
            // resolution as described in RFC 4703 should be employed for the
            // given update request. The default value for this flag is true.
            // It may be specified at the global, shared-network, and subnet levels.
            // This field has been replaced by ddns-conflict-resolution-mode.
            // Parsing is maintained only for backwards compatibility.
            // "ddns-use-conflict-resolution": true,

            // Enumeration, which is passed to kea-dhcp-ddns with each DDNS
            // update request to indicate the mode used for resolving conflicts
            // while performing DDNS updates. The acceptable values are:
            // check-with-dhcid (this includes adding a DHCID record and checking
            // that record via conflict detection as per RFC 4703,
            // no-check-with-dhcid (this will ignore conflict detection but add
            // a DHCID record when creating/updating an entry),
            // check-exists-with-dhcid (this will check if there is an existing
            // DHCID record but does not verify the value of the record matches
            // the update. This will also update the DHCID record for the entry),
            // no-check-without-dhcid (this ignores conflict detection and will
            // not add a DHCID record when creating/updating a DDNS entry).
            // The default value is "check-with-dhcid". It may be
            // specified at the global, shared-network and subnet levels.
            "ddns-conflict-resolution-mode": "check-with-dhcid",

            // When greater than 0.0, it is the percent of the lease's lifetime
            // to use for the DNS TTL.
            "ddns-ttl-percent": 0.75,

            // When greater than 0 it will be used as the DNS TTL. Specified in seconds.
            // You cannot specify both ddns-ttl and any of ddns-ttl-percent, ddns-ttl-min, or
            // ddns-ttl-max. They are mutually exclusive.
            // "ddns-ttl": 500,

            // When greater than 0 it used as the lower boundary for calculated DNS TTL values.
            // Specified in seconds.
            "ddns-ttl-min": 24000,

            // When greater than 0 it used as the upper boundary for calculated DNS TTL values.
            // Specified in seconds.
            "ddns-ttl-max": 64000,

            // Time in seconds specifying how long a declined lease should be
            // excluded from DHCP assignments. The default value is 86400 (24 hours).
            "decline-probation-period": 86400,

            // Name Change Request forwarding configuration for the Kea DHCPv4 server.
            // NCRs are sent to the Kea D2 module to update DNS upon allocation of
            // DHCP leases.
            "dhcp-ddns": {
                // Boolean flag indicating whether Kea DHCPv4 server should connect to
                // kea-dhcp-ddns. This must be true for NCRs to be created and
                // sent to kea-dhcp-ddns. By default, NCRs are not generated.
                "enable-updates": false,

                // Specifies maximum number of NCRs to queue waiting to be sent
                // to the Kea D2 server.
                "max-queue-size": 1024,

                // Packet format to use when sending NCRs to the Kea D2 server.
                // Currently, only JSON format is supported.
                "ncr-format": "JSON",

                // Socket protocol to use when sending NCRs to D2. Currently,
                // only UDP is supported.
                "ncr-protocol": "UDP",

                // IP address that the Kea DHCPv4 server should use to send
                // NCRs to D2. The default value of zero indicates that Kea
                // should pick a suitable address.
                "sender-ip": "0.0.0.0",

                // Port number that the Kea DHCPv4 server should use to send
                // NCRs to D2. The default value of zero indicates that Kea
                // should pick a suitable port.
                "sender-port": 0,

                // IP address on which D2 listens for NCRs.
                "server-ip": "127.0.0.1",

                // Port number on which D2 listens for NCRs.
                "server-port": 53001
            },

            // Specifies the first of the two consecutive ports of the UDP
            // sockets used for communication between DHCPv6 and DHCPv4
            // servers. See RFC 7341. (defaults to 0 - disabled).
            // If enabled, use e.g. 786.
            "dhcp4o6-port": 0,

            // Boolean flag indicating whether the Kea DHCPv4 server
            // should send back the Client Identifier option in its responses.
            // The default value is true, which indicates that the option
            // must be sent back if the client included it. The false
            // value instructs the server to not send this option for
            // backward compatibility with older DHCP specifications, which
            // stated that Client Identifier must not be sent back.
            "echo-client-id": true,

            // Collection of Kea DHCPv4 server parameters configuring how
            // the server should process expired DHCP leases.
            "expired-leases-processing": {
                // Specifies the number of seconds since the last removal of
                // the expired leases, when the next removal should occur.
                // If both "flush-reclaimed-timer-wait-time" and
                // "hold-reclaimed-time" are not 0, when the client sends a release
                // message the lease is expired instead of being deleted from
                // lease storage.
                "flush-reclaimed-timer-wait-time": 25,

                // Specifies the length of time in seconds to keep expired
                // leases in the lease database (lease affinity).
                // If both "flush-reclaimed-timer-wait-time" and
                // "hold-reclaimed-time" are not 0, when the client sends a release
                // message the lease is expired instead of being deleted from
                // lease storage.
                "hold-reclaimed-time": 3600,

                // Specifies the maximum number of expired leases that can be
                // processed in a single attempt to clean up expired leases
                // from the lease database. If there are more
                // expired leases, they will be processed during the next
                // cleanup attempt.
                "max-reclaim-leases": 100,

                // Specifies the maximum time in milliseconds that a single attempt
                // to clean up expired leases from the lease database may take.
                "max-reclaim-time": 250,

                // Specifies the length of time in seconds since the last attempt
                // to process expired leases before initiating the next attempt.
                "reclaim-timer-wait-time": 10,

                // Specifies the maximum number of expired lease-processing cycles
                // which didn't result in full cleanup of expired leases from the
                // lease database, after which a warning message is issued.
                "unwarned-reclaim-cycles": 5
            },

            // List of hook libraries and their specific configuration parameters
            // to be loaded by Kea DHCPv4 server.
            "hooks-libraries": [
                {
                    // Location of the hook library to be loaded.
                    "library": "libdhcp_lease_cmds.so",

                    // Hook library-specific configuration parameters.
                    "parameters": { }
                },
                {
                    // The MySQL host backend hook library required for host storage.
                    "library": "libdhcp_mysql.so"
                },
                {
                    // The PostgreSQL host backend hook library required for host storage.
                    "library": "libdhcp_pgsql.so"
                }
            ],

            // List of access credentials to external sources of IPv4 reservations,
            "hosts-databases": [
                {
                    // Name of the database to connect to.
                    "name": "keatest",

                    // Host on which the database resides.
                    "host": "localhost",

                    // Database password.
                    "password": "1234",

                    // Port on which the database is available.
                    "port": 3306,

                    // Type of database, e.g. "mysql", "postgresql".
                    "type": "mysql",

                    // Username to be used to access the database.
                    "user": "keatest",

                    // Read-only mode.
                    "readonly": false,

                    // The next entries are for OpenSSL support in MySQL.

                    // Trust anchor aka certificate authority file or directory.
                    "trust-anchor": "my-ca",

                    // Client certificate file name.
                    "cert-file": "my-cert",

                    // Private key file name.
                    "key-file": "my-key",

                    // Cipher list (see the OpenSSL ciphers command manual).
                    "cipher-list": "AES",

                    // Connection reconnect wait time.
                    // This parameter governs how long Kea waits before attempting
                    // to reconnect. Expressed in milliseconds. The default is 0
                    // (disabled) for MySQL and PostgreSQL.
                    "reconnect-wait-time": 3000,

                    // Connection maximum reconnect tries.
                    "max-reconnect-tries": 3,

                    // Action to take when connection recovery fails.
                    // Supported values: stop-retry-exit, serve-retry-exit,
                    // serve-retry-continue
                    "on-fail": "stop-retry-exit",

                    // Flag which indicates if the DB recovery should be attempted
                    // at server startup and on reconfiguration events.
                    "retry-on-startup": false,

                    // Connection connect timeout in seconds.
                    "connect-timeout": 100,

                    // Timeout of database read operations in seconds.
                    "read-timeout": 120,

                    // Timeout of database write operations in seconds.
                    "write-timeout": 180
                },
                {
                    // Name of the database to connect to.
                    "name": "keatest",

                    // Host on which the database resides.
                    "host": "localhost",

                    // Database password.
                    "password": "1234",

                    // Port on which the database is available.
                    "port": 5432,

                    // Type of database, e.g. "mysql", "postgresql".
                    "type": "postgresql",

                    // Username to be used to access the database.
                    "user": "keatest",

                    // TCP user timeout while communicating with the database.
                    // It is specified in seconds.
                    "tcp-user-timeout": 100,

                    // Trust anchor aka certificate authority file or directory.
                    "trust-anchor": "my-ca",

                    // Client certificate file name.
                    "cert-file": "my-cert",

                    // Private key file name.
                    "key-file": "my-key",

                    // SSL mode.
                    "ssl-mode": "verify-ca"
                }
            ],

            // List of host reservation identifier types to be used by the
            // Kea DHCPv4 server to fetch static reservations for
            // DHCP clients. All identifiers are used by default, which
            // means that the server will issue multiple queries to the
            // database to find if there is a reservation for a particular
            // client. If a particular deployment uses only a subset, e.g.
            // one identifier type, this identifier should be only listed
            // here to prevent unnecessary queries to the database.
            "host-reservation-identifiers": [
                "hw-address",
                "duid",
                "circuit-id",
                "client-id",
                "flex-id"
            ],

            // Specifies configuration of interfaces on which the Kea DHCPv4
            // server is listening to the DHCP queries.
            "interfaces-config": {
                // Specifies whether the server should use "udp" sockets or
                // "raw" sockets to listen to DHCP traffic. The "raw"
                // sockets are useful when direct DHCP traffic is being
                // received.
                "dhcp-socket-type": "udp",

                // Specifies a list of interfaces on which the Kea DHCPv4
                // server should listen to DHCP requests.
                "interfaces": [
                    "eth0"
                ],

                // Enumeration which indicates what interface should be used
                // to send DHCP responses to the client. The default value is
                // "same-as-inbound", which indicates that the response should
                // be sent via the interface on which the client's query
                // was received. The "use-routing" value indicates that the
                // Kea server should use the kernel's routing table to find a
                // suitable interface.
                "outbound-interface": "same-as-inbound",

                // Boolean flag indicating whether the available interfaces should
                // be re-detected upon server reconfiguration. The default value
                // is true, which means that the interfaces are always
                // re-detected.
                "re-detect": true,

                // Kea tries to bind the service sockets during initialization, but it may
                // fail due to a port being already opened or a misconfiguration. Kea can
                // suppress these errors and only log them. This flag prevents starting
                // the DHCP server without binding all sockets. If unspecified, it
                // defaults to false.
                "service-sockets-require-all": true,

                // Kea tries to bind the service sockets during initialization. This
                // option specifies how many times binding to interface will be retried.
                // The default value is 0, which means that the operation will not be
                // repeated.
                "service-sockets-max-retries": 5,

                // The time interval in milliseconds to wait before the next attempt to
                // retry opening a service socket.
                "service-sockets-retry-wait-time": 5000
            },

            // Boolean parameter which controls whether an early global host
            // reservations lookup should be performed. This lookup takes place
            // before subnet selection and when a global reservation is found
            // with some client classes, it triggers a second phase classification.
            // It can also be used to drop queries using host reservations as a
            // decision table indexed by reservation identifiers.
            "early-global-reservations-lookup": true,

            // Boolean parameter which controls the DHCP server's behavior with respect
            // to creating host reservations for the same IP address. By default
            // this flag is set to true, in which case the server prevents creation
            // of multiple host reservations for the same IP address. When this
            // parameter is set to false, the server allows for creating multiple
            // reservations for the same IP address within a subnet. This setting
            // is useful in deployments in which a given host may be communicating
            // with a DHCP server over multiple interfaces and, depending on the
            // chosen interface, a different MAC address (or other identifier) will
            // be used to identify the host. Note that some host backends do not
            // support the mode in which multiple reservations for the same IP
            // address are used. If these backends are in use and this setting
            // is attempted, a configuration error will occur. The MySQL and
            // PostgreSQL backends do support this mode.
            "ip-reservations-unique": true,

            // Boolean parameter which controls whether host reservations lookup
            // should be performed before lease lookup. This parameter has effect
            // only when multi-threading is disabled. When multi-threading is
            // enabled, host reservations lookup is always performed first to avoid
            // lease-lookup resource locking.
            "reservations-lookup-first": true,

            // Specifies credentials to access lease database.
            "lease-database": {
                // memfile backend-specific parameter specifying the interval
                // in seconds at which the lease file should be cleaned up (outdated
                // lease entries are removed to prevent the lease file from growing
                // infinitely).
                "lfc-interval": 3600,

                // Maximum number of lease-file read errors allowed before
                // loading the file is abandoned. Defaults to 0 (no limit).
                "max-row-errors": 100,

                // Name of the lease file. In the case of a database it specifies the
                // database name.
                "name": "kea-leases4.csv",

                // memfile-specific parameter indicating whether leases should
                // be saved on persistent storage (disk) or not. The true value
                // is the default and it indicates that leases are stored in
                // persistent storage. This setting must be used in production.
                // The false value should only be used for testing purposes
                // because non-stored leases will be lost upon Kea server restart.
                "persist": true,

                // Lease database backend type, i.e. "memfile", "mysql" or
                // "postgresql".
                "type": "memfile"
            },

            // Boolean value indicating whether the Kea DHCPv4 server should use the client
            // identifier value sent by the client or ignore it. The default value
            // is true, which indicates that the server should use the client identifier
            // and that it takes precedence over the client's MAC address. In deployments
            // where MAC address should take precedence, this value can be set to
            // false, in which case the clients will be identified by MAC address.
            // This is specifically useful when clients don't generate unique
            // identifiers or these identifiers are not stable, etc.
            "match-client-id": false,

            // Global value of the next server address set in 'siaddr' field.
            // The global value may be overridden in lower-level configuration
            // scopes.
            "next-server": "192.0.2.123",

            // Global value which limits the number of client packets (e.g.
            // DHCPREQUESTs) that may be parked while waiting for hook library
            // work to complete, prior to a response (e.g. DHCPACK) being sent
            // back to the client. A typical example is when kea-dhcp4 parks a
            // DHCPREQUEST while it sends the lease update(s) to its HA peer(s).
            // The packet is unparked once the update(s) have been acknowledged.
            // This value limits the number of packets that can be held pending
            // the updates. In times of heavy client traffic, this value can keep
            // kea-dhcp4 from building an insurmountable backlog of updates.
            "parked-packet-limit": 256,

            // List of global DHCP options that the Kea DHCPv4 server assigns to
            // clients.
            "option-data": [
                {
                    // Boolean flag indicating whether the given option is always
                    // sent in response or only when requested. The default
                    // value of false indicates that it is only sent when
                    // requested.
                    "always-send": false,

                    // An optional list of classes for which this option applies.
                    // If the the client matches any of the classes in this list the
                    // option will be applied. If the list is empty or is
                    // omitted this option will be applied regardless of class
                    // membership.
                    "client-classes": [ "class1", "class2" ],

                    // Option code. It is not required if the option name is
                    // provided.
                    "code": 6,

                    // Boolean value indicating whether the option data specified
                    // in the "data" field is specified as a string of hexadecimal
                    // digits or in human-readable CSV format.
                    "csv-format": true,

                    // Option data to be stored in the option payload.
                    "data": "192.0.3.1, 192.0.3.2",

                    // Option name. It is not required if the option code is
                    // provided.
                    "name": "domain-name-servers",

                    // Boolean flag indicating whether the given option is never
                    // sent in response. The default value of false indicates
                    // that it is sent when it should be. When true, the option
                    // is not sent despite any other setting, i.e. it is
                    // a final flag.
                    "never-send": false,

                    // Option space. The default is the "dhcp4" option space which
                    // groups top-level DHCPv4 options.
                    "space": "dhcp4"
                }
            ],

            // List of global option definitions, i.e. option formats, that the
            // Kea DHCPv4 server is using.
            "option-def": [
                {
                    // Boolean flag indicating whether the option definition comprises
                    // an array of values of some type, e.g. an array of IPv4 addresses.
                    // The default value of false means that the option does not
                    // comprise an array of values.
                    "array": false,

                    // Option code.
                    "code": 6,

                    // Holds a name of the option space encapsulated by this option.
                    // All options that belong to this option space will be sent
                    // as sub-options of this option. An empty string means that this
                    // option doesn't encapsulate any option.
                    "encapsulate": "",

                    // Option name.
                    "name": "my-option",

                    // Specifies the types of fields within the option if the option
                    // is said to be a "record" (see "type"). In this particular example
                    // this option comprises two fields, 1 byte and 2 bytes long.
                    "record-types": "uint8, uint16",

                    // Name of the option space to which this option belongs.
                    "space": "my-space",

                    // Option type. All possible types are listed in the Kea
                    // Administrator Reference Manual.
                    "type": "record"
                }
            ],

            // Global value for the rebind timer, i.e. the time after which the
            // DHCP client enters the rebind state if it fails to renew the lease.
            "rebind-timer": 40,

            // Global value for the renew timer, i.e. the time after which the
            // DHCP client renews the lease.
            "renew-timer": 30,

            // Global value to store extended information (e.g. relay agent
            // information) with each lease.
            "store-extended-info": true,

            // Statistics keep some samples per observation point.
            // There are two default values: maximum count and maximum age.
            // Setting the maximum count to zero disables it.
            "statistic-default-sample-count": 0,

            // When the maximum count is 0 the maximum age (in seconds) applies.
            "statistic-default-sample-age": 60,

            // Multi-threading parameters.
            "multi-threading": {
                // By default, Kea processes packets on multiple threads if the hardware permits.
                "enable-multi-threading": true,

                // When multi-threading is enabled, Kea will process packets on a
                // number of multiple threads configurable through this option. The
                // value must be a positive integer (0 means auto-detect).
                "thread-pool-size": 0,

                // When multi-threading is enabled, Kea will read packets from the
                // interface and append a working item to the thread pool. This
                // option configures the maximum number of items that can be queued.
                // The value must be a positive integer (0 means unlimited).
                "packet-queue-size": 0
            },

            // Governs how the Kea DHCPv4 server should deal with invalid
            // data received from the client.
            "sanity-checks": {
                // Specifies how the Kea DHCPv4 server should behave when invalid
                // data is read for a lease from the lease file. The following
                // values are supported: "none" (don't attempt to correct the
                // lease information), "warn" (print a warning for subnet-id
                // related inconsistencies), "fix" (correct the subnet id by
                // trying to find the suitable subnet), "fix-del" (similar
                // to "fix" but delete the lease if no suitable subnet found),
                // "del" (delete the lease if the lease has invalid subnet
                // identifier value).
                "lease-checks": "warn",

                // Specifies how Kea DHCPv4 server should behave when invalid
                // extended info is read for a lease from the lease file, or
                // whether to upgrade from the old format. The following values
                // are supported: "none" (don't attempt to correct or upgrade
                // the extended info), "fix" (fix common inconsistencies and
                // upgrade from the old format; this is the default), "strict"
                // (fix inconsistencies with an impact on Leasequery),
                // "pedantic" (enforce full Kea code format).
                "extended-info-checks": "fix"
            },

            // List of shared networks used by the Kea DHCPv4 server. The shared
            // networks group subnets together.
            "shared-networks": [
                {
                    // A flag selecting an IP address allocation strategy for all
                    // subnets in this shared network.
                    "allocator": "random",

                    // Shared-network level authoritative flag.
                    "authoritative": false,

                    // Shared-network level bootfile name.
                    "boot-file-name": "/dev/null",

                    // Restricts this shared network to allow only clients
                    // that belong to at least one class in this list. If omitted
                    // or an empty list is provided, no restriction is applied.
                    "client-classes": [],

                    // Shared-network level value. See description at the global level.
                    "ddns-generated-prefix": "myhost",

                    // Shared-network level value. See description at the global level.
                    "ddns-override-client-update": false,

                    // Shared-network level value. See description at the global level.
                    "ddns-override-no-update": false,

                    // Shared-network level value. See description at the global level.
                    "ddns-qualifying-suffix": "",

                    // Shared-network level value. See description at the global level.
                    "ddns-replace-client-name": "never",

                    // Shared-network level value. See description at the global level.
                    "ddns-send-updates": true,

                    // Shared-network level value. See description at the global level.
                    "ddns-update-on-renew": true,

                    // Shared-network level value. See description at the global level.
                    // This field has been replaced by ddns-conflict-resolution-mode.
                    // Parsing is maintained only for backwards compatibility.
                    // "ddns-use-conflict-resolution": true,

                    // Shared-network level value. See description at the global level.
                    "ddns-conflict-resolution-mode": "check-with-dhcid",

                    // Shared-network level value. See description at the global level.
                    "ddns-ttl-percent": 0.65,

                    // Shared-network level value. See description at the global level.
                    // You cannot specify both ddns-ttl and any of ddns-ttl-percent, ddns-ttl-min, or
                    // ddns-ttl-max. They are mutually exclusive.
                    // "ddns-ttl": 500,

                    // Shared-network level value. See description at the global level.
                    "ddns-ttl-min": 10000,

                    // Shared-network level value. See description at the global level.
                    "ddns-ttl-max": 20000,

                    // Shared-network level value. See description at the global level.
                    "hostname-char-replacement": "x",

                    // Shared-network level value. See description at the global level.
                    "hostname-char-set": "[^A-Za-z0-9.-]",

                    // Specifies that this shared network is selected for
                    // requests received on a particular interface.
                    "interface": "eth0",

                    // Shared-network level flag specifying whether the client
                    // identifier should be used for identifying clients.
                    "match-client-id": true,

                    // Shared network name.
                    "name": "my-secret-network",

                    // Shared-network level specification of the next server
                    // to be sent in 'siaddr'.
                    "next-server": "192.0.2.123",

                    // If greater than zero, it is the lifetime of leases temporarily allocated
                    // on DISCOVER. When zero (the default), leases are not allocated on DISCOVER.
                    "offer-lifetime" : 60,

                    // List of shared network-specific DHCP options.
                    "option-data": [],

                    // List of IPv4 relay addresses for which this shared
                    // network is selected.
                    "relay": {
                        "ip-addresses": []
                    },

                    // Shared-network level rebind timer.
                    "rebind-timer": 41,

                    // Shared-network level renew timer.
                    "renew-timer": 31,

                    // Shared-network level compute T1 and T2 timers.
                    "calculate-tee-times": true,

                    // T1 = valid lifetime * .5.
                    "t1-percent": .5,

                    // T2 = valid lifetime * .75.
                    "t2-percent": .75,

                    // Cache threshold = valid lifetime * .25.
                    "cache-threshold": .25,

                    // Cache maximum: when the client last-transmission time
                    // is close enough, the lease is not renewed and the current
                    // lease is returned as it was "cached".
                    "cache-max-age": 1000,

                    // Adaptive lease time threshold (1.0 is disabled).
                    "adaptive-lease-time-threshold": 0.8,

                    // Specify whether the server should look up global reservations.
                    "reservations-global": false,

                    // Specify whether the server should look up in-subnet reservations.
                    "reservations-in-subnet": true,

                    // Specify whether the server can assume that all reserved addresses
                    // are out-of-pool.
                    // Ignored when reservations-in-subnet is false.
                    // If specified, it is inherited by "subnet4" levels.
                    "reservations-out-of-pool": false,

                    // List of client classes which must be evaluated when this shared
                    // network is selected for client assignments.
                    "evaluate-additional-classes": [ "late" ],

                    // Turn off storage of extended information (e.g. relay agent
                    // information) with each lease for this shared network.
                    "store-extended-info": false,

                    // Shared-network level server hostname set in 'sname' field.
                    "server-hostname": "",

                    // List of IPv4 subnets belonging to this shared network.
                    "subnet4": [
                        {
                            // Interface name matched against inbound interface name.
                            // Used in DHCPv4o6. See RFC 7341.
                            "4o6-interface": "",

                            // Interface ID option value. See RFC 7341.
                            "4o6-interface-id": "",

                            // Prefix matched against source address. See RFC7341.
                            "4o6-subnet": "2001:db8:1:1::/64",

                            // A flag selecting an IP address allocation strategy for
                            // the subnet.
                            "allocator": "iterative",

                            // Subnet-level authoritative flag.
                            "authoritative": false,

                            // Subnet-level bootfile name, set in 'file' field.
                            "boot-file-name": "",

                            // Restricts this subnet to allow only clients
                            // that belong to at least one class in this list. If omitted
                            // or an empty list is provided, no restriction is applied.
                            "client-classes": [],

                            // Subnet-level value. See description at the global level.
                            "ddns-generated-prefix": "myhost",

                            // Subnet-level value. See description at the global level.
                            "ddns-override-client-update": false,

                            // Subnet-level value. See description at the global level.
                            "ddns-override-no-update": false,

                            // Subnet-level value. See description at the global level.
                            "ddns-qualifying-suffix": "",

                            // Subnet-level value. See description at the global level.
                            "ddns-replace-client-name": "never",

                            // Subnet-level value. See description at the global level.
                            "ddns-send-updates": true,

                            // Subnet-level value. See description at the global level.
                            "ddns-update-on-renew": true,

                            // Shared-network level value. See description at the global level.
                            // This field has been replaced by ddns-conflict-resolution-mode.
                            // Parsing is maintained only for backwards compatibility.
                            // "ddns-use-conflict-resolution": true,

                            // Subnet-level value. See description at the global level.
                            "ddns-conflict-resolution-mode": "check-with-dhcid",

                            // Subnet-level value. See description at the global level.
                            // "ddns-ttl-percent": 0.55,

                            // Subnet-level value. See description at the global level.
                            // You cannot specify both ddns-ttl and any of ddns-ttl-percent, ddns-ttl-min, or
                            // ddns-ttl-max. They are mutually exclusive.
                            "ddns-ttl": 500,

                            // Subnet-level value. See description at the global level.
                            // "ddns-ttl-min": 10000,

                            // Subnet-level value. See description at the global level.
                            // "ddns-ttl-max": 20000,

                            // Subnet-level value. See description at the global level.
                            "hostname-char-replacement": "x",

                            // Subnet-level value. See description at the global level.
                            "hostname-char-set": "[^A-Za-z0-9.-]",

                            // Subnet unique identifier.
                            "id": 1,

                            // Specifies that this subnet is selected for requests
                            // received on a particular interface.
                            "interface": "eth0",

                            // Subnet-level flag specifying whether the client identifier
                            // should be used for identifying clients.
                            "match-client-id": true,

                            // Subnet-level specification of the next server to be sent
                            // in 'siaddr'.
                            "next-server": "0.0.0.0",

                            // If greater than zero, it is the lifetime of leases temporarily allocated
                            // on DISCOVER. When zero (the default), leases are not allocated on DISCOVER.
                            "offer-lifetime" : 60,

                            // Turn on storage of extended information (e.g. relay agent
                            // information) with each lease for this subnet.
                            "store-extended-info": true,

                            // Subnet-level list of DHCP options.
                            "option-data": [
                                {
                                    // Boolean flag indicating whether the particular option
                                    // should be always sent or sent only when requested.
                                    "always-send": false,

                                    // An optional list of classes for which this option applies.
                                    // If the the client matches any of the classes in this list the
                                    // option will be applied. If the list is empty or is
                                    // omitted this option will be applied regardless of class
                                    // membership.
                                    "client-classes": [],

                                    // Option code.
                                    "code": 3,

                                    // Boolean flag indicating whether the option value specified
                                    // in "data" is a string of hexadecimal values or human-readable
                                    // CSV value.
                                    "csv-format": true,

                                    // Option data to be included in the option payload.
                                    "data": "192.0.3.1",

                                    // Option name.
                                    "name": "routers",

                                    // Boolean flag indicating whether the given option is never
                                    // sent in response.
                                    "never-send": false,

                                    // Option space. The default value "dhcp4" designates the
                                    // top-level option space.
                                    "space": "dhcp4"
                                }
                            ],

                            // List of IP address pools belonging to the subnet.
                            "pools": [
                                {
                                    // Restricts this pool to allow only clients
                                    // that belong to at least one class in this list. If omitted
                                    // or an empty list is provided, no restriction is applied.
                                    "client-classes": [ "phones_server1" ],

                                    // Pool-level list of DHCP options.
                                    "option-data": [],

                                    // Address range used for client assignments.
                                    "pool": "192.1.0.1 - 192.1.0.200",

                                    // List of client classes which must be evaluated when this pool
                                    // is selected for client assignments.
                                    "evaluate-additional-classes": [ "late" ],

                                    // Pool-level value. See description at the global level.
                                    "ddns-generated-prefix": "mypool",

                                    // Pool-level value. See description at the global level.
                                    "ddns-override-client-update": false,

                                    // Pool-level value. See description at the global level.
                                    "ddns-override-no-update": false,

                                    // Pool-level value. See description at the global level.
                                    "ddns-qualifying-suffix": "pool.example.com.",

                                    // Pool-level value. See description at the global level.
                                    "ddns-replace-client-name": "always",

                                    // Pool-level value. See description at the global level.
                                    "ddns-send-updates": true,

                                    // Pool-level value. See description at the global level.
                                    "ddns-update-on-renew": false,

                                    // Pool-level value. See description at the global level.
                                    "ddns-conflict-resolution-mode": "check-with-dhcid",

                                    // Pool-level value. See description at the global level.
                                    "ddns-ttl-percent": 0.55,

                                    // Pool-level value. See description at the global level.
                                    // You cannot specify both ddns-ttl and any of ddns-ttl-percent,
                                    // ddns-ttl-min, or ddns-ttl-max. They are mutually exclusive.
                                    // "ddns-ttl": 500,

                                    // Pool-level value. See description at the global level.
                                    "ddns-ttl-min": 10000,

                                    // Pool-level value. See description at the global level.
                                    "ddns-ttl-max": 20000,

                                    // Pool-level value. See description at the global level.
                                    "hostname-char-replacement": "x",

                                    // Pool-level value. See description at the global level.
                                    "hostname-char-set": "[^A-Za-z0-9.-]"
                                },
                                {
                                    // Restricts this pool to allow only clients
                                    // that belong to at least one class in this list. If omitted
                                    // or an empty list is provided, no restriction is applied.
                                    "client-classes": [ "phones_server2" ],

                                    // Pool-level list of DHCP options.
                                    "option-data": [],

                                    // Address range used for client assignments.
                                    "pool": "192.3.0.1 - 192.3.0.200",

                                    // List of client classes which must be evaluated when this pool
                                    // is selected for client assignments.
                                    "evaluate-additional-classes": [],

                                    // Pool identifier used to enable statistics for this pool.
                                    // The pool ID does not need to be unique within the subnet
                                    // or across subnets.
                                    // If not unconfigured, it defaults to 0. The statistics
                                    // regarding this pool will be combined with the other statistics
                                    // of all other pools with the same pool ID in this subnet.
                                    "pool-id": 1
                                }
                            ],

                            // Subnet-level value of the rebind timer.
                            "rebind-timer": 40,

                            // List of IPv4 relay addresses for which this subnet is selected.
                            "relay": {
                                "ip-addresses": [
                                    "192.168.56.1"
                                ]
                            },

                            // Subnet-level value of the renew timer.
                            "renew-timer": 30,

                            // Specify whether the server should look up global reservations.
                            "reservations-global": false,

                            // Specify whether the server should look up in-subnet reservations.
                            "reservations-in-subnet": true,

                            // Specify whether the server can assume that all reserved
                            // addresses are out-of-pool.
                            // Ignored when reservations-in-subnet is false.
                            "reservations-out-of-pool": false,

                            // Subnet-level compute T1 and T2 timers.
                            "calculate-tee-times": true,

                            // T1 = valid lifetime * .5.
                            "t1-percent": .5,

                            // T2 = valid lifetime * .75.
                            "t2-percent": .75,

                            // Cache threshold = valid lifetime * .25.
                            "cache-threshold": .25,

                            // Subnet-level cache maximum.
                            "cache-max-age": 1000,

                            // Adaptive lease time threshold (1.0 is disabled).
                            "adaptive-lease-time-threshold": 0.8,

                            // List of static IPv4 reservations assigned to clients belonging
                            // to this subnet. For a detailed example, see reservations.json.
                            "reservations": [
                                {
                                    // Identifier used for client matching. Supported values are
                                    // "hw-address", "client-id", "duid", "circuit-id", "flex-id".
                                    "circuit-id": "01:11:22:33:44:55:66",

                                    // Reserved IP address.
                                    "ip-address": "192.0.2.204",

                                    // Hostname.
                                    "hostname": "foo.example.org",

                                    // Reservation-specific option data.
                                    "option-data": [
                                        {
                                            // Option name.
                                            "name": "vivso-suboptions",

                                            // Option data.
                                            "data": "4491"
                                        }
                                    ]
                                }
                            ],

                            // List of client classes which must be evaluated when this subnet
                            // is selected for client assignments.
                            "evaluate-additional-classes": [ "late" ],

                            // Subnet-level server hostname set in 'sname' field.
                            "server-hostname": "",

                            // Subnet prefix.
                            "subnet": "192.0.0.0/8",

                            // Subnet-level (default) valid lifetime.
                            "valid-lifetime": 6000,

                            // Subnet-level min valid lifetime.
                            "min-valid-lifetime": 4000,

                            // Subnet-level max valid lifetime.
                            "max-valid-lifetime": 8000
                        }
                    ],

                    // Shared-network level (default) valid lifetime.
                    "valid-lifetime": 6001,

                    // Shared-network level min valid lifetime.
                    "min-valid-lifetime": 4001,

                    // Shared-network level max valid lifetime.
                    "max-valid-lifetime": 8001
                }
            ],

            // Global server hostname set in the 'sname' field.
            "server-hostname": "",

            // Stash agent options (aka RAI) to make direct queries to come
            // through a relay.
            "stash-agent-options": false,

            // List of IPv4 subnets which don't belong to any shared network.
            "subnet4": [],

            // Global valid lifetime value.
            "valid-lifetime": 6000,

            // Global min valid lifetime value.
            "min-valid-lifetime": 4000,

            // Global max valid lifetime value.
            "max-valid-lifetime": 8000,

            // Reservations (examples are in other files).
            "reservations": [],

            // Configuration control (currently not used, i.e. this syntax
            // is already defined but the corresponding feature is not implemented).
            "config-control": {
                // Only the configuration databases entry is defined.
                "config-databases": [
                    {
                        // Name of the database to connect to.
                        "name": "config",

                        // Type of database, e.g. "mysql", "postgresql".
                        "type": "mysql"
                    }
                ],
                // Interval between attempts to fetch configuration updates
                // via the configuration backends used.
                "config-fetch-wait-time": 30
            },

            // Server tag.
            "server-tag": "my DHCPv4 server",

            // DHCP queue-control parameters.
            "dhcp-queue-control": {
                // Enable queue is mandatory.
                "enable-queue": true,

                // Queue type is mandatory.
                "queue-type": "kea-ring4",

                // Capacity is optional.
                "capacity": 64
            },

            // Specify whether the server should look up global reservations.
            "reservations-global": false,

            // Specify whether the server should look up in-subnet reservations.
            "reservations-in-subnet": true,

            // Specify whether the server can assume that all reserved addresses
            // are out-of-pool.
            // Ignored when reservations-in-subnet is false.
            // If specified, it is inherited by "shared-networks" and
            // "subnet4" levels.
            "reservations-out-of-pool": false,

            // Global compute T1 and T2 timers.
            "calculate-tee-times": true,

            // T1 = valid lifetime * .5.
            "t1-percent": .5,

            // T2 = valid lifetime * .75.
            "t2-percent": .75,

            // Cache threshold = valid lifetime * .25.
            "cache-threshold": .25,

            // Global cache maximum.
            "cache-max-age": 1000,

            // Adaptive lease time threshold (1.0 is disabled).
            "adaptive-lease-time-threshold": 0.8,

            // String of zero or more characters with which to replace each
            // invalid character in the hostname or Client FQDN. The default
            // value is an empty string, which will cause invalid characters
            // to be omitted rather than replaced.
            "hostname-char-replacement": "x",

            // Regular expression describing the invalid character set in
            // the hostname or Client FQDN.
            "hostname-char-set": "[^A-Za-z0-9.-]",

            // List of loggers used by the servers using this configuration file.
            "loggers": [
                {
                    // Debug level, a value between 0..99. The greater the value
                    // the more detailed the debug log.
                    "debuglevel": 99,

                    // Name of the logger.
                    "name": "kea-dhcp4",

                    // Configures how the log should be output.
                    "output-options": [
                        {
                            // Determines whether the log should be flushed to a file.
                            "flush": true,

                            // Specifies maximum filesize before the file is rotated.
                            "maxsize": 10240000,

                            // Specifies the maximum number of rotated files to be kept.
                            "maxver": 1,

                            // Specifies the logging destination.
                            "output": "stdout",

                            // Specifies log entry content
                            "pattern": "%D{%Y-%m-%d %H:%M:%S.%q} %-5p [%c/%i] %m\n"
                        }
                    ],

                    // Specifies logging severity, i.e. "ERROR", "WARN", "INFO", "DEBUG".
                    "severity": "INFO"
                }
            ],

            // If greater than zero, it is the lifetime of leases temporarily allocated
            // on DISCOVER. When zero (the default), leases are not allocated on DISCOVER.
            "offer-lifetime" : 60,

            // Look at advanced examples for the use of user-contexts.
            "user-context": { }
        }
    }

.. _config-example-kea4-all-options-json:

---------------------
kea4/all-options.json
---------------------

.. code-block::
    :linenos:

    // This example configuration file for DHCPv4 server in Kea contains:
    //
    // - data for all the standard options
    // - custom option definitions at global level along with some associated
    // option data
    // - custom option data with standardized option spaces other than "dhcp4"
    // - custom option spaces
    // - option embedding examples
    //
    // The reader is strongly encouraged to take a look at the option formats
    // documented in the Kea ARM:
    // https://kea.readthedocs.io/en/latest/arm/dhcp4-srv.html?highlight=list%20of%20standard%20dhcpv4#id2

    {
      "Dhcp4": {
        /*
                          Data for all standard option definitions
        */
        // Option data defined globally
        "option-data": [
          /*
           Code   Len        Time Offset
          +-----+-----+-----+-----+-----+-----+
          |  2  |  4  |  n1 |  n2 |  n3 |  n4 |
          +-----+-----+-----+-----+-----+-----+
          */
          // Type: int32
          {
            "code": 2,
            "data": "-25200",
            "name": "time-offset"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          |  3  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of {IPv4 address}
          {
            "code": 3,
            "data": "192.0.2.2, 192.0.2.3",
            "name": "routers"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          |  4  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of {IPv4 address}
          {
            "code": 4,
            "data": "192.0.2.4, 192.0.2.5",
            "name": "time-servers"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          |  5  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of {IPv4 address}
          {
            "code": 5,
            "data": "192.0.2.6, 192.0.2.7",
            "name": "name-servers"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          |  6  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of {IPv4 address}
          {
            "code": 6,
            "data": "192.0.2.8, 192.0.2.9",
            "name": "domain-name-servers"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          |  7  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of {IPv4 address}
          {
            "code": 7,
            "data": "192.0.2.10, 192.0.2.11",
            "name": "log-servers"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          |  8  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of {IPv4 address}
          {
            "code": 8,
            "data": "192.0.2.12, 192.0.2.13",
            "name": "cookie-servers"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          |  9  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of {IPv4 address}
          {
            "code": 9,
            "data": "192.0.2.14, 192.0.2.15",
            "name": "lpr-servers"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          |  10 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of {IPv4 address}
          {
            "code": 10,
            "data": "192.0.2.16, 192.0.2.17",
            "name": "impress-servers"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          |  11 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of {IPv4 address}
          {
            "code": 11,
            "data": "192.0.2.18, 192.0.2.19",
            "name": "resource-location-servers"
          },

          /*
           Code   Len   File Size
          +-----+-----+-----+-----+
          |  13 |  2  |  l1 |  l2 |
          +-----+-----+-----+-----+
          */
          // Type: uint16
          {
            "code": 13,
            "data": "1024",
            "name": "boot-size"
          },

          /*
           Code   Len      Dump File Pathname
          +-----+-----+-----+-----+-----+-----+---
          |  14 |  n  |  n1 |  n2 |  n3 |  n4 | ...
          +-----+-----+-----+-----+-----+-----+---
          */
          // Type: string
          {
            "code": 14,
            "data": "/etc/crash-dump.img",
            "name": "merit-dump"
          },

          /*
           Code   Len        Domain Name
          +-----+-----+-----+-----+-----+-----+--
          |  15 |  n  |  d1 |  d2 |  d3 |  d4 |  ...
          +-----+-----+-----+-----+-----+-----+--
          */
          // Type: FQDN
          {
            "code": 15,
            "data": "my.example.org",
            "name": "domain-name"
          },

          /*
           Code   Len    Swap Server Address
          +-----+-----+-----+-----+-----+-----+
          |  16 |  n  |  a1 |  a2 |  a3 |  a4 |
          +-----+-----+-----+-----+-----+-----+
          */
          // Type: IPv4 address
          {
            "code": 16,
            "data": "192.0.2.20",
            "name": "swap-server"
          },

          /*
           Code   Len      Root Disk Pathname
          +-----+-----+-----+-----+-----+-----+---
          |  17 |  n  |  n1 |  n2 |  n3 |  n4 | ...
          +-----+-----+-----+-----+-----+-----+---
          */
          // Type: string
          {
            "code": 17,
            "data": "/path/to/root",
            "name": "root-path"
          },

          /*
           Code   Len      Extensions Pathname
          +-----+-----+-----+-----+-----+-----+---
          |  18 |  n  |  n1 |  n2 |  n3 |  n4 | ...
          +-----+-----+-----+-----+-----+-----+---
          */
          // Type: string
          {
            "code": 18,
            "data": "/path/to/extensions",
            "name": "extensions-path"
          },

          /*
           Code   Len  Value
          +-----+-----+-----+
          |  19 |  1  | 0/1 |
          +-----+-----+-----+
          */
          // Type: boolean
          {
            "code": 19,
            "data": "true",
            "name": "ip-forwarding"
          },

          /*
           Code   Len  Value
          +-----+-----+-----+
          |  20 |  1  | 0/1 |
          +-----+-----+-----+
          */
          // Type: boolean
          {
            "code": 20,
            "data": "true",
            "name": "non-local-source-routing"
          },

          /*
           Code   Len         Address 1                  Mask 1
          +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
          |  21 |  n  |  a1 |  a2 |  a3 |  a4 |  m1 |  m2 |  m3 |  m4 |
          +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
                  Address 2                  Mask 2
          +-----+-----+-----+-----+-----+-----+-----+-----+---
          |  a1 |  a2 |  a3 |  a4 |  m1 |  m2 |  m3 |  m4 | ...
          +-----+-----+-----+-----+-----+-----+-----+-----+---
          */
          // Type: array of {IPv4 address}
          {
            "code": 21,
            "data": "10.229.0.128, 255.255.255.128, 10.27.129.0, 255.255.255.0",
            "name": "policy-filter"
          },

          /*
           Code   Len      Size
          +-----+-----+-----+-----+
          |  22 |  2  |  s1 |  s2 |
          +-----+-----+-----+-----+
          */
          // Type: uint16
          {
            "code": 22,
            "data": "2048",
            "name": "max-dgram-reassembly"
          },

          /*
           Code   Len   TTL
          +-----+-----+-----+
          |  23 |  1  | ttl |
          +-----+-----+-----+
          */
          // Type: uint8
          {
            "code": 23,
            "data": "248",
            "name": "default-ip-ttl"
          },

          /*
           Code   Len           Timeout
          +-----+-----+-----+-----+-----+-----+
          |  24 |  4  |  t1 |  t2 |  t3 |  t4 |
          +-----+-----+-----+-----+-----+-----+
          */
          // Type: uint32
          {
            "code": 24,
            "data": "131072",
            "name": "path-mtu-aging-timeout"
          },

          /*
           Code   Len     Size 1      Size 2
          +-----+-----+-----+-----+-----+-----+---
          |  25 |  n  |  s1 |  s2 |  s1 |  s2 | ...
          +-----+-----+-----+-----+-----+-----+---
          */
          // Type: array of {uint16}
          {
            "code": 25,
            "data": "3072, 4096",
            "name": "path-mtu-plateau-table"
          },

          /*
           Code   Len      MTU
          +-----+-----+-----+-----+
          |  26 |  2  |  m1 |  m2 |
          +-----+-----+-----+-----+
          */
          // Type: uint16
          {
            "code": 26,
            "data": "5120",
            "name": "interface-mtu"
          },

          /*
           Code   Len  Value
          +-----+-----+-----+
          |  27 |  1  | 0/1 |
          +-----+-----+-----+
          */
          // Type: boolean
          {
            "code": 27,
            "data": "true",
            "name": "all-subnets-local"
          },

          /*
           Code   Len     Broadcast Address
          +-----+-----+-----+-----+-----+-----+
          |  28 |  4  |  b1 |  b2 |  b3 |  b4 |
          +-----+-----+-----+-----+-----+-----+
          */
          // Type: IPv4 address
          {
            "code": 28,
            "data": "192.0.2.255",
            "name": "broadcast-address"
          },

          /*
           Code   Len  Value
          +-----+-----+-----+
          |  29 |  1  | 0/1 |
          +-----+-----+-----+
          */
          // Type: boolean
          {
            "code": 29,
            "data": "true",
            "name": "perform-mask-discovery"
          },

          /*
           Code   Len  Value
          +-----+-----+-----+
          |  30 |  1  | 0/1 |
          +-----+-----+-----+
          */
          // Type: boolean
          {
            "code": 30,
            "data": "true",
            "name": "mask-supplier"
          },

          /*
           Code   Len  Value
          +-----+-----+-----+
          |  31 |  1  | 0/1 |
          +-----+-----+-----+
          */
          // Type: boolean
          {
            "code": 31,
            "data": "true",
            "name": "router-discovery"
          },

          /*
           Code   Len            Address
          +-----+-----+-----+-----+-----+-----+
          |  32 |  4  |  a1 |  a2 |  a3 |  a4 |
          +-----+-----+-----+-----+-----+-----+
          */
          // Type: IPv4 address
          {
            "code": 32,
            "data": "192.0.2.23",
            "name": "router-solicitation-address"
          },

          /*
           Code   Len         Destination 1           Router 1
          +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
          |  33 |  n  |  d1 |  d2 |  d3 |  d4 |  r1 |  r2 |  r3 |  r4 |
          +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
                  Destination 2           Router 2
          +-----+-----+-----+-----+-----+-----+-----+-----+---
          |  d1 |  d2 |  d3 |  d4 |  r1 |  r2 |  r3 |  r4 | ...
          +-----+-----+-----+-----+-----+-----+-----+-----+---
          */
          // Type: array of {IPv4 address}
          {
            "code": 33,
            "data": "192.0.2.24, 192.0.2.25",
            "name": "static-routes"
          },

          /*
           Code   Len  Value
          +-----+-----+-----+
          |  34 |  1  | 0/1 |
          +-----+-----+-----+
          */
          // Type: boolean
          {
            "code": 34,
            "data": "true",
            "name": "trailer-encapsulation"
          },

          /*
           Code   Len           Time
          +-----+-----+-----+-----+-----+-----+
          |  35 |  4  |  t1 |  t2 |  t3 |  t4 |
          +-----+-----+-----+-----+-----+-----+
          */
          // Type: uint32
          {
            "code": 35,
            "data": "196608",
            "name": "arp-cache-timeout"
          },

          /*
           Code   Len  Value
          +-----+-----+-----+
          |  36 |  1  | 0/1 |
          +-----+-----+-----+
          */
          // Type: boolean
          {
            "code": 36,
            "data": "true",
            "name": "ieee802-3-encapsulation"
          },

          /*
           Code   Len   TTL
          +-----+-----+-----+
          |  37 |  1  |  n  |
          +-----+-----+-----+
          */
          // Type: uint8
          {
            "code": 37,
            "data": "124",
            "name": "default-tcp-ttl"
          },

          /*
           Code   Len           Time
          +-----+-----+-----+-----+-----+-----+
          |  38 |  4  |  t1 |  t2 |  t3 |  t4 |
          +-----+-----+-----+-----+-----+-----+
          */
          // Type: uint32
          {
            "code": 38,
            "data": "262144",
            "name": "tcp-keepalive-interval"
          },

          /*
           Code   Len  Value
          +-----+-----+-----+
          |  39 |  1  | 0/1 |
          +-----+-----+-----+
          */
          // Type: boolean
          {
            "code": 39,
            "data": "true",
            "name": "tcp-keepalive-garbage"
          },

          /*
           Code   Len      NIS Domain Name
          +-----+-----+-----+-----+-----+-----+---
          |  40 |  n  |  n1 |  n2 |  n3 |  n4 | ...
          +-----+-----+-----+-----+-----+-----+---
          */
          // Type: string
          {
            "code": 40,
            "data": "nis.example.org",
            "name": "nis-domain"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          |  41 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of {IPv4 address}
          {
            "code": 41,
            "data": "192.0.2.26, 192.0.2.27",
            "name": "nis-servers"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          |  42 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of {IPv4 address}
          {
            "code": 42,
            "data": "192.0.2.28, 192.0.2.29",
            "name": "ntp-servers"
          },

          /*
           Code   Len   Vendor-specific information
          +-----+-----+-----+-----+---
          |  43 |  n  |  i1 |  i2 | ...
          +-----+-----+-----+-----+---

           Code   Len   Data item        Code   Len   Data item       Code
          +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
          |  T1 |  n  |  d1 |  d2 | ... |  T2 |  n  |  D1 |  D2 | ... | ... |
          +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
          */
          // Type: empty
          {
            "code": 43,
            "name": "vendor-encapsulated-options"
          },

          /*
           Code   Len           Address 1              Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
          |  44 |  n  |  a1 |  a2 |  a3 |  a4 |  b1 |  b2 |  b3 |  b4 | ...
          +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
          */
          // Type: array of {IPv4 address}
          {
            "code": 44,
            "data": "192.0.2.30, 192.0.2.31",
            "name": "netbios-name-servers"
          },

          /*
           Code   Len           Address 1              Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
          |  45 |  n  |  a1 |  a2 |  a3 |  a4 |  b1 |  b2 |  b3 |  b4 | ...
          +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
          */
          // Type: array of {IPv4 address}
          {
            "code": 45,
            "data": "192.0.2.32, 192.0.2.33",
            "name": "netbios-dd-server"
          },

          /*
          Value         Node Type
          -----         ---------
          0x1           B-node
          0x2           P-node
          0x4           M-node
          0x8           H-node

           Code   Len  Node Type
          +-----+-----+-----------+
          |  46 |  1  | see above |
          +-----+-----+-----------+
          */
          // Type: uint8
          {
            "code": 46,
            "data": "0x1",
            "name": "netbios-node-type"
          },

          /*
           Code   Len       NetBIOS Scope
          +-----+-----+-----+-----+-----+-----+----
          |  47 |  n  |  s1 |  s2 |  s3 |  s4 | ...
          +-----+-----+-----+-----+-----+-----+----
          */
          // Type: string
          {
            "code": 47,
            "data": "scope42",
            "name": "netbios-scope"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+---
          |  48 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |   ...
          +-----+-----+-----+-----+-----+-----+-----+-----+---
          */
          // Type: array of {IPv4 address}
          {
            "code": 48,
            "data": "192.0.2.34, 192.0.2.35",
            "name": "font-servers"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+---
          |  49 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |   ...
          +-----+-----+-----+-----+-----+-----+-----+-----+---
          */
          // Type: array of {IPv4 address}
          {
            "code": 49,
            "data": "192.0.2.36, 192.0.2.37",
            "name": "x-display-manager"
          },

          /*
          Value   Meaning
          -----   --------
            1     the 'file' field is used to hold options
            2     the 'sname' field is used to hold options
            3     both fields are used to hold options

           Code   Len  Value
          +-----+-----+-----+
          |  52 |  1  |1/2/3|
          +-----+-----+-----+
          */
          // Type: uint8
          {
            "code": 52,
            "data": "3",
            "name": "dhcp-option-overload"
          },

          /*
           Code   Len            Address
          +-----+-----+-----+-----+-----+-----+
          |  54 |  4  |  a1 |  a2 |  a3 |  a4 |
          +-----+-----+-----+-----+-----+-----+
          */
          // Type: IPv4 address
          {
            "code": 54,
            "data": "192.0.2.39",
            "name": "dhcp-server-identifier"
          },

          /*
           Code   Len     Text
          +-----+-----+-----+-----+---
          |  56 |  n  |  c1 |  c2 | ...
          +-----+-----+-----+-----+---
          */
          // Type: string
          {
            "code": 56,
            "data": "Error: here is a DHCPNAK!",
            "name": "dhcp-message"
          },

          /*
           Code   Len     Length
          +-----+-----+-----+-----+
          |  57 |  2  |  l1 |  l2 |
          +-----+-----+-----+-----+
          */
          // Type: uint16
          {
            "code": 57,
            "data": "1536",
            "name": "dhcp-max-message-size"
          },

          /*
           Code   Len   Vendor class Identifier
          +-----+-----+-----+-----+---
          |  60 |  n  |  i1 |  i2 | ...
          +-----+-----+-----+-----+---
          */
          // Type: string
          {
            "code": 60,
            "data": "ISC",
            "name": "vendor-class-identifier"
          },

          /*
           Code  Len    NetWare/IP Domain Name
          +-----+-----+------+------+------+-----
          |  62 |  n  |  c1  |  c2  |  c3  |  ...
          +-----+-----+------+------+------+-----
          */
          // Type: string
          {
            "code": 62,
            "data": "nwip.example.org",
            "name": "nwip-domain-name"
          },

          /*
           Code   Len  NetWare/IP General Info
          +-----+-----+----+----+
          | 63  | 11  | 2  |  0 |
          +-----+-----+----+----+
                       NWIP_EXIST_IN_OPTIONS_AREA (length 0)

                      +----+----+----+
                      |  5 |  1 |  1 |
                      +----+----+----+
                       NSQ_BROADCAST_SERVER (length 1)
                       value is YES

                      +----+----+------------+
                      |  7 |  4 | IP address |
                      +----+----+------------+
                       NEAREST_NWIP_SERVER (length 4)
                       value is IP address of server
          */
          // Type: binary
          {
            "code": 63,
            "data": "1A BB AD AB BA D0 00 00 00 00 00 00 00 00 CA FE",
            "name": "nwip-suboptions"
          },

          /*
           Code   Len      NIS Client Domain Name
          +-----+-----+-----+-----+-----+-----+---
          |  64 |  n  |  n1 |  n2 |  n3 |  n4 | ...
          +-----+-----+-----+-----+-----+-----+---
          */
          // Type: string
          {
            "code": 64,
            "data": "nisplus.example.org",
            "name": "nisplus-domain-name"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          |  65 |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: IPv4 address
          {
            "code": 65,
            "data": "192.0.2.40",
            "name": "nisplus-servers"
          },

          /*
           Code  Len   TFTP server
          +-----+-----+-----+-----+-----+---
          | 66  |  n  |  c1 |  c2 |  c3 | ...
          +-----+-----+-----+-----+-----+---
          */
          // Type: string
          {
            "code": 66,
            "data": "tftp.example.org",
            "name": "tftp-server-name"
          },

          /*
           Code  Len   Bootfile name
          +-----+-----+-----+-----+-----+---
          | 67  |  n  |  c1 |  c2 |  c3 | ...
          +-----+-----+-----+-----+-----+---
          */
          // Type: string
          {
            "code": 67,
            "data": "boot-file.img",
            "name": "boot-file-name"
          },

          /*
           Code Len    Home Agent Addresses (zero or more)
          +-----+-----+-----+-----+-----+-----+--
          | 68  |  n  | a1  | a2  | a3  | a4  | ...
          +-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of {IPv4 address}
          {
            "code": 68,
            "data": "192.0.2.41, 192.0.2.42",
            "name": "mobile-ip-home-agent"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          | 69  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of {IPv4 address}
          {
            "code": 69,
            "data": "192.0.2.43, 192.0.2.44",
            "name": "smtp-server"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          | 70  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of {IPv4 address}
          {
            "code": 70,
            "data": "192.0.2.45, 192.0.2.46",
            "name": "pop-server"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          | 71  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of {IPv4 address}
          {
            "code": 71,
            "data": "192.0.2.47, 192.0.2.48",
            "name": "nntp-server"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          | 72  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of {IPv4 address}
          {
            "code": 72,
            "data": "192.0.2.49, 192.0.2.50",
            "name": "www-server"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          | 73  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of {IPv4 address}
          {
            "code": 73,
            "data": "192.0.2.51, 192.0.2.52",
            "name": "finger-server"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          | 74  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of {IPv4 address}
          {
            "code": 74,
            "data": "192.0.2.53, 192.0.2.54",
            "name": "irc-server"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          | 75  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of {IPv4 address}
          {
            "code": 75,
            "data": "192.0.2.55, 192.0.2.56",
            "name": "streettalk-server"
          },

          /*
           Code   Len         Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          | 76  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 |  ...
          +-----+-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of {IPv4 address}
          {
            "code": 76,
            "data": "192.0.2.57, 192.0.2.58",
            "name": "streettalk-directory-assistance-server"
          },

          /*
           Code   Len   Value
          +-----+-----+---------------------  . . .  --+
          | 77  |  N  | User Class Data ('Len' octets) |
          +-----+-----+---------------------  . . .  --+
          */
          // Type: binary
          {
            "code": 77,
            "data": "1A BB AD AB BA D0 00 00 00 00 00 00 00 00 CA FE",
            "name": "user-class"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |   Code = 78   |    Length     |   Mandatory   |      a1       |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      a2       |       a3      |       a4      |      ...
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          */
          // Type: boolean, array of {IPv4 address}
          {
            "code": 78,
            "data": "true, 192.0.2.59, 192.0.2.60",
            "name": "slp-directory-agent"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |   Code = 79   |     Length    |   Mandatory   | <Scope List>...
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          */
          // Type: boolean, string
          {
            "code": 79,
            "data": "true, slp-scope",
            "name": "slp-service-scope"
          },

          // Option code 80 is not defined in Kea.
          // Option code 83 is not defined in Kea.
          // Option code 84 is unassigned.

          /*
           Code   Len        Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+--
          | 85  |  n  |  a1 |  a2 | a3  |  a4 |  a1 |  a2 |  a3 |  a4 |  ...
          +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of IPv4 address
          {
            "code": 85,
            "data": "192.0.2.61, 192.0.2.62",
            "name": "nds-servers"
          },

          /*
           Code Len  NDS Tree Name
          +----+----+----+----+----+----+--
          | 86 | n  | c1 | c2 | c3 | c4 |  ...
          +----+----+----+----+----+----+--
          */
          // Type: string
          {
            "code": 86,
            "data": "my-tree",
            "name": "nds-tree-name"
          },

          /*
           Code Len  Initial NDS Context
          +----+----+----+----+----+----+--
          | 87 | n  | c1 | c2 | c3 | c4 |  ...
          +----+----+----+----+----+----+--
          */
          // Type: string
          {
            "code": 87,
            "data": "context",
            "name": "nds-context"
          },

          /*
           Code   Len  FQDN(s) of BCMCS Controller
          +-----+-----+-----+-----+-----+-----+-----+--
          | 88  |  n  |  s1 |  s2 |  s3 |  s4 | s5  |  ...
          +-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: FQDN
          {
            "code": 88,
            "data": "bcms-controller.example.org",
            "name": "bcms-controller-names"
          },

          /*
           Code   Len  Address 1               Address 2
          +-----+-----+-----+-----+-----+-----+-----+--
          | 89  |  n  | a1  | a2  | a3  | a4  | a1  |  ...
          +-----+-----+-----+-----+-----+-----+-----+--
          */
          // Type: array of {IPv4 address}
          {
            "code": 89,
            "data": "192.0.2.63",
            "name": "bcms-controller-address"
          },

          /*
           Code  Len  16-bit Type
          +----+-----+-----+-----+
          | 93 |  n  | n1  | n2  |
          +----+-----+-----+-----+
          */
          // Type: array of uint16
          {
            "code": 93,
            "data": "6144, 7168",
            "name": "client-system"
          },

          /*
           Code  Len  Type Major Minor
          +----+-----+----+-----+-----+
          | 94 |  3  |  t |  M  |  m  |
          +----+-----+----+-----+-----+
          */
          // Type: uint8, uint8, uint8
          {
            "code": 94,
            "data": "0, 1, 0",
            "name": "client-ndi"
          },

          // Option code 95 is unsupported.
          // Option code 96 is unassigned.

          /*
           Code  Len  Type  Machine Identifier
          +----+-----+----+-----+ . . . +-----+
          | 97 |  n  |  t |     | . . . |     |
          +----+-----+----+-----+ . . . +-----+
          */
          // Type: uint8, binary
          {
            "code": 97,
            "data": "0, 1A BB AD AB BA D0 00 00 00 00 00 00 00 00 CA FE",
            "name": "uuid-guid"
          },

          /*
          0                   1                   2                   3
          0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |     Code      |    Length     |   URL list
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

             Code            98

             Length          The length of the data field (i.e., URL list) in
                             bytes.

             URL list        A list of one or more URLs separated by the ASCII
                             space character (0x20).
          */
          // Type: string
          {
            "code": 98,
            "data": "uap1.example.org uap2.example.org",
            "name": "uap-servers"
          },

          /*
          0                   1                   2                   3
          0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          | GEOCONF_CIVIC |       N       |      what     |    country    |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |    code       |        civic address elements                ...
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          Code GEOCONF_CIVIC:  The code for this DHCP option is 99.

          N:  The length of this option is variable.  The minimum length is 3
             octets.

          what:  The 'what' element describes to which location the DHCP entry
             refers.  Currently, three options are defined: the location of the
             DHCP server (a value of 0), the location of the network element
             believed to be closest to the client (a value of 1), or the
             location of the client (a value of 2).  Option (2) SHOULD be used,
             but may not be known.  Options (0) and (1) SHOULD NOT be used
             unless it is known that the DHCP client is in close physical
             proximity to the server or network element.

          country code:  The two-letter ISO 3166 country code in capital ASCII
             letters, e.g., DE or US.  (Civic addresses always contain country
             designations, suggesting the use of a fixed-format field to save
             space.)

          civic address elements:  Zero or more elements comprising the civic
             and/or postal address, with the format described below
             (Section 3.3).
          */
          // Type: binary
          {
            "code": 99,
            "data": "1A BB AD AB BA D0 00 00 00 00 00 00 00 00 CA FE",
            "name": "geoconf-civic"
          },

          /*
           PCode  Len   TZ-POSIX String
          +-----+-----+------------------------------+
          | 100 |  N  | IEEE 1003.1 String           |
          +-----+-----+------------------------------+
          */
          // Type: string
          {
            "code": 100,
            // String options that have a comma in their values need to have
            // it escaped (i.e. each comma is preceded by two backslashes).
            // That's because commas are reserved for separating fields in
            // compound options. At the same time, we need to be conformant
            // with JSON spec, that does not allow "\,". Therefore the
            // slightly uncommon double backslashes notation is needed.
            // The value sent over the wire is:
            // EST5EDT4,M3.2.0/02:00,M11.1.0/02:00
            "data": "EST5EDT4\\,M3.2.0/02:00\\,M11.1.0/02:00",
            "name": "pcode"
          },

          /*
           TCode  Len   TZ-Database String
          +-----+-----+------------------------------+
          | 101 |  N  | Reference to the TZ Database |
          +-----+-----+------------------------------+
          */
          // Type: string
          {
            "code": 101,
            "data": "Europe/Zurich",
            "name": "tcode"
          },

          // Option codes 102-107 are unassigned.

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |     Code      |   Length      |           Value               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |         Value (cont.)         |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          Code:  8-bit identifier of the IPv6-Only Preferred option code as
             assigned by IANA: 108.  The client includes the Code in the
             Parameter Request List in DHCPDISCOVER and DHCPREQUEST messages as
             described in Section 3.2.

          Length:  8-bit unsigned integer.  The length of the option, excluding
             the Code and Length Fields.  The server MUST set the length field
             to 4.  The client MUST ignore the IPv6-Only Preferred option if
             the length field value is not 4.

          Value:  32-bit unsigned integer.  The number of seconds for which the
             client should disable DHCPv4 (V6ONLY_WAIT configuration variable).
             If the server pool is explicitly configured with a V6ONLY_WAIT
             timer, the server MUST set the field to that configured value.
             Otherwise, the server MUST set it to zero.  The client MUST
             process that field as described in Section 3.2.
          */
          // Type: uint32
          {
            "code": 108,
            "data": "3600",
            "name": "v6-only-preferred"
          },

          // Option codes 109-111 are unassigned.

          // Type: array of {IPv4 address}
          {
            "code": 112,
            "data": "192.0.2.63, 192.0.2.64",
            "name": "netinfo-server-address"
          },

          // Type: string
          {
            "code": 113,
            "data": "server1",
            "name": "netinfo-server-tag"
          },

          // Type: string
          {
            "code": 114,
            "data": "https://default.example.org",
            "name": "v4-captive-portal"
          },

          // Option code 115 is unassigned.

          /*
           Code   Len   Value
          +-----+-----+-----+
          | 116 |  1  |  a  |
          +-----+-----+-----+
          */
          // Type: uint8
          {
            "code": 116,
            "data": "1",
            "name": "auto-config"
          },

          /*
               Code            Length      Name Service Search Order in Sequence
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |     117       |     Len       |             ns1               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |             ns2               |             ...               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          */
          // Type: array of {uint16}
          {
            "code": 117,
            "data": "6, 41, 44, 65",
            "name": "name-service-search"
          },

          /*
           Code   Len        IPv4 Address
          +-----+-----+-----+-----+-----+-----+
          | 118 |  4  | A1  | A2  | A3  | A4  |
          +-----+-----+-----+-----+-----+-----+
          */
          // Type: IPv4 address
          {
            "code": 118,
            "data": "192.0.2.65",
            "name": "subnet-selection"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |     119       |     Len       |         Searchstring...
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                     Searchstring...
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          */
          // Type: array of {FQDN}
          {
            "code": 119,
            "data": "example.com, example.org",
            "name": "domain-search"
          },

          // Option code 120 is not defined in Kea.

          /*
            Code Len Destination 1    Router 1
          +-----+---+----+-----+----+----+----+----+----+
          | 121 | n | d1 | ... | dN | r1 | r2 | r3 | r4 |
          +-----+---+----+-----+----+----+----+----+----+

           Destination 2       Router 2
          +----+-----+----+----+----+----+----+
          | d1 | ... | dN | r1 | r2 | r3 | r4 |
          +----+-----+----+----+----+----+----+

          Destination 1...N     Destination descriptors - describe the IP
                                subnet number and subnet mask of a particular
                                destination using a compact encoding. This
                                encoding consists of one octet describing
                                the width of the subnet mask, followed by all
                                the significant octets of the subnet number.

          Router 1...N          The IP address of the router that should
                                be used to reach that destination.
          */
          // Type: internal
          {
            "code": 121,
            // please mind the convenience notation used:
            // subnet1 - router1 IP addr, subnet2 - router2 IP addr, ..., subnetN - routerN IP addr
            "data": "10.229.0.128/25 - 10.229.0.1, 10.198.122.47/32 - 10.198.122.1",
            "name": "classless-static-route"
          },

          // Option codes 122-123 are not defined in Kea.

          /*
                               1 1 1 1 1 1
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |  option-code  |  option-len   |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      enterprise-number1       |
          |                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |   data-len1   |               |
          +-+-+-+-+-+-+-+-+               |
          /      vendor-class-data1       /
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ----
          |      enterprise-number2       |   ^
          |                               |   |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   |
          |   data-len2   |               | optional
          +-+-+-+-+-+-+-+-+               |   |
          /      vendor-class-data2       /   |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   |
          ~            ...                ~   V
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ----

          option-code         OPTION_V-I_VENDOR_CLASS (124)

          option-len          total length of all following option data in
                              octets

          enterprise-numberN  The vendor's 32-bit Enterprise Number as
                              registered with IANA [3]

          data-lenN           Length of vendor-class-data field

          vendor-class-dataN  Details of the hardware configuration of the
                              host on which the client is running, or of
                              industry consortium compliance
          */
          // Type: uint32, binary
          {
            "code": 124,
            "data": "4491, 0f BA AD AB BA D0 00 00 00 00 00 00 00 00 CA FE",
            "name": "vivco-suboptions"
          },

          /*
                               1 1 1 1 1 1
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |  option-code  |  option-len   |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      enterprise-number1       |
          |                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |   data-len1   |               |
          +-+-+-+-+-+-+-+-+ option-data1  |
          /                               /
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ----
          |      enterprise-number2       |   ^
          |                               |   |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   |
          |   data-len2   |               | optional
          +-+-+-+-+-+-+-+-+ option-data2  |   |
          /                               /   |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   |
          ~            ...                ~   V
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ----

          option-code         OPTION_V-I_VENDOR_OPTS (125)

          option-len          total length of all following option data in
                              octets

          enterprise-numberN  The vendor's registered 32-bit Enterprise Number
                              as registered with IANA [3]

          data-lenN           Length of option-data field

          option-dataN        Vendor-specific options, described below
          */
          // Type: uint32
          {
            "code": 125,
            "data": "4491",
            "name": "vivso-suboptions"
          },

          // Option codes 126-127 are unassigned.
          // Option codes 128-135 are not defined in Kea.

          /*
          0                   1
          0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |  option-code  | option-length |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                               |
          +      PAA IPv4 Address         +
          |                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |             ...               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             Figure 1: PAA DHCPv4 option

          option-code:        OPTION_PANA_AGENT (136).

          option-length:      Length of the 'options' field in octets;
                              MUST be a multiple of four (4).

          PAA IPv4 Address:   IPv4 address of a PAA for the client to use.
                              The PAAs are listed in the order of preference
                              for use by the client.
          */
          // Type: array of {IPv4 address}
          {
            "code": 136,
            "data": "192.0.2.66, 192.0.2.67",
            "name": "pana-agent"
          },

          /*
          Code    Len   LoST Server Domain Name
          +-----+-----+-----+-----+-----+-----+-----+----
          | 137 |  n  |  s1 |  s2 |  s3 |  s4 | s5  |  ...
          +-----+-----+-----+-----+-----+-----+-----+----
          */
          // Type: FQDN
          {
            "code": 137,
            "data": "lost.example.org",
            "name": "v4-lost"
          },

          /*
          0                   1
          0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |  option-code  | option-length |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                               |
          +       AC IPv4 Address         +
          |                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |             ...               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code:   OPTION_CAPWAP_AC_V4 (138)

          option-length:   Length of the 'options' field in octets; MUST be a
             multiple of four (4).

          AC IPv4 Address:  IPv4 address of a CAPWAP AC that the WTP may use.
             The ACs are listed in the order of preference for use by the WTP
          */
          // Type: array of {IPv4 address}
          {
            "code": 138,
            "data": "192.0.2.68, 192.0.2.69",
            "name": "capwap-ac-v4"
          },

          // Option codes 139-140 are not defined in Kea.

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      141      |     Len       |         Searchstring...       |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                     Searchstring...                           |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          */
          // Type: array of {FQDN}
          {
            "code": 141,
            "data": "example.com, example.org",
            "name": "sip-ua-cs-domains"
          },

          // Option code 142 is not defined in Kea.

          /*
           0                             1
           0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
          +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
          |   option-code (143)   |     option-length     |
          +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
          .                                               .
          .    bootstrap-server-list (variable length)    .
          .                                               .
          +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

          option-code: OPTION_V4_SZTP_REDIRECT (143)

          option-length: The option length in octets.

          bootstrap-server-list: A list of servers for the
           client to attempt contacting, in order to obtain
           further bootstrapping data. Each URI entry in the
           bootstrap-server-list is structured as follows:

          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-...-+-+-+-+-+-+-+
          |       uri-length              |          URI                  |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-...-+-+-+-+-+-+-+

          uri-length: 2 octets long; specifies the length of the URI data.
          URI: URI of the SZTP bootstrap server.
          */
          // Type: array of {tuple}
          {
            "code": 143,
            "data": "https://sztp1.example.com:8443, https://sztp2.example.com:8444",
            "name": "v4-sztp-redirect"
          },

          // Option codes 144-145 are not defined in Kea.

          // Type: uint8, IPv4 address, IPv4 address, array of {FQDN}
          {
            "code": 146,
            "data": "1, 192.0.2.70, 192.0.2.71, example.com, example.org",
            "name": "rdnss-selection"
          },

          // Option codes 147-158 are not defined in Kea.

          // Type: uint8, PSID
          {
            "code": 159,
            "data": "2, 3/4",
            "name": "v4-portparams"
          },

          // Option codes 160-161 are unassigned.

          /*
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          | OPTION_V4_DNR |     Length    |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          ~      DNR Instance Data #1     ~
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   ---
          .              ...              .    |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ optional
          ~      DNR Instance Data #n     ~    |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   ---

          DNR Instance Data Format:
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |    DNR Instance Data Length   |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |       Service Priority        |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |   ADN Length  |               |
          +-+-+-+-+-+-+-+-+               |
          ~  authentication-domain-name   ~
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |  Addr Length  |               |
          +-+-+-+-+-+-+-+-+               |
          ~        IPv4 Address(es)       ~
          |               +-+-+-+-+-+-+-+-+
          |               |               |
          +-+-+-+-+-+-+-+-+               |
          ~Service Parameters (SvcParams) ~
          |                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          Code:  OPTION_V4_DNR (162).

          Length:  Indicates the length of the enclosed data in octets.

          DNR Instance Data:  Includes the configuration data of an encrypted
             DNS resolver. When several encrypted DNS resolvers are to be included, the "DNR
             Instance Data" field is repeated.

          DNR Instance Data Length:  Length of all following data in octets.
             This field is set to ('ADN Length' + 3) when only an ADN is
             provided for a DNR instance.

          Service Priority:  The priority of this instance compared to other
             DNR instances.  This 16-bit unsigned integer is interpreted
             following the rules specified in Section 2.4.1 of
             [RFC9460].

          ADN Length:  Length of the authentication-domain-name in octets.

          authentication-domain-name (variable length):  The authentication
             domain name of the encrypted DNS resolver.  This field is
             formatted as specified in Section 10 of [RFC9915].

          Addr Length:  Length of included IPv4 addresses in octets.  When
             present, it MUST be a multiple of 4.

          IPv4 Address(es) (variable length):  Indicates one or more IPv4
             addresses to reach the encrypted DNS resolver.  Both private and
             public IPv4 addresses can be included in this field.

          Service Parameters (SvcParams) (variable length):  Specifies a set of
             service parameters that are encoded following the rules in
             Section 2.2 of [RFC9460].
             The length of this field is ('DNR Instance Data Length' - 4 - 'ADN
             Length' - 'Addr Length').

          Note that "Addr Length", "IPv4 Address(es)", and "Service Parameters
          (SvcParams)" fields are not present if the ADN-only mode is used.
          */
          // Type: internal
          {
            // DNR option may be configured using convenient notation. DNR Instances must be delimited with pipe "|" char.
            // For each DNR Instance comma delimited fields must be provided:
            // - service priority (mandatory),
            // - ADN (mandatory),
            // - IP address(es) (optional - if more than one - they must be space-separated)
            // - SvcParams (optional - if more than one - they must be space-separated;
            //   to provide more than one alpn-id separate them with double-backslash escaped comma like in the
            //   example below).
            // Note: whenever pipe "|" char needs to be used not as the delimiter, it must be escaped with
            //       double backslash, like in case of escaped commas in alpn-ids list.
            // Basing on the config, Kea will encode the option according to RFC9463.
            "code": 162,
            "name": "v4-dnr",
            "data": "1, resolver.example., 10.2.3.4 10.0.4.5, alpn=dot\\,doq\\,h2\\,h3 dohpath=/q{?dns} | 2, resolver.example., 10.0.5.6, alpn=dot port=8530 | 3, fooexp.resolver.example."
          },

          // Option codes 163-209 are unassigned.

          /*
          0                   1                   2                   3
          0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |  OPTION_6RD   | option-length |  IPv4MaskLen  |  6rdPrefixLen |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          |                           6rdPrefix                           |
          |                          (16 octets)                          |
          |                                                               |
          |                                                               |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                     6rdBRIPv4Address(es)                      |
          .                                                               .
          .                                                               .
          .                                                               .
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code         OPTION_6RD (212)

          option-length       The length of the DHCP option in octets (22
                              octets with one BR IPv4 address).

          IPv4MaskLen         The number of high-order bits that are identical
                              across all CE IPv4 addresses within a given 6rd
                              domain.  This may be any value between 0 and 32.
                              Any value greater than 32 is invalid.

          6rdPrefixLen        The IPv6 prefix length of the SP's 6rd IPv6
                              prefix in number of bits.  For the purpose of
                              bounds checking by DHCP option processing, the
                              sum of (32 - IPv4MaskLen) + 6rdPrefixLen MUST be
                              less than or equal to 128.

          6rdBRIPv4Address    One or more IPv4 addresses of the 6rd Border
                              Relay(s) for a given 6rd domain.

          6rdPrefix           The service provider's 6rd IPv6 prefix
                              represented as a 16-octet IPv6 address.  The bits
                              in the prefix after the 6rdPrefixlen number of
                              bits are reserved and MUST be initialized to zero
                              by the sender and ignored by the receiver.
          */
          // Type: uint8, uint8, IPv6 address, array of {IPv4 address}
          {
            "code": 212,
            "data": "24, 96, 2001:db8::f001, 192.0.2.72, 192.0.2.73",
            "name": "option-6rd"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |     Code      |   Length      |  Access Network Domain Name   .
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          .            Access Network Domain Name (cont.)                 .
          .                              ...                              .
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code:  OPTION_V4_ACCESS_DOMAIN (213).

          option-length:  The length of the entire access network domain name
             option in octets.

          option-value:  The domain name associated with the access network,
             encoded as described in Section 3.1.
          */
          // Type: FQDN
          {
            "code": 213,
            "data": "example.org",
            "name": "v4-access-domain"
          },

          // Option codes 214-219 are unassigned.
          // Option codes 220-221 are not defined in Kea.
          // Option codes 222-254 are unassigned

          /*
                                     Custom option data
          */
          // See "option-def" below for the definitions.
          {
            "code": 1,
            "name": "my-empty-option",
            "space": "my-fancy-space"
          },
          {
            "code": 224,
            "data": "192.0.2.74, 3/4, 1, example.org, string",
            "name": "my-lengthy-option",
            "space": "my-fancy-space"
          },
          {
            "code": 254,
            "data": "127, 32767, 2147483647, 255, 65535, 4294967295, 192.0.2.75, 3/4, 1, example.org, string",
            "name": "my-fancy-option",
            "space": "my-fancy-space"
          },
          {
            "code": 232,
            "name": "my-encapsulating-option",
            "space": "my-encapsulating-space"
          }
        ],

        /*
                                 Custom option definitions
        */
        // For kea-dhcp4, custom option definitions can be global or in a client
        // class.
        "option-def": [
          // New option space allows for a new set of option codes.
          // An empty option requires no "data" in "option-data". It's
          // presence should be sufficient to trigger custom behavior.
          {
            "array": false,
            "code": 1,
            "encapsulate": "",
            "name": "my-empty-option",
            "record-types": "",
            "space": "my-fancy-space",
            "type": "empty"
          },

          // A custom type has "type" set to "record" and all data types (which need
          // to be more than 1, otherwise you're better off using the type directly)
          // are specified in "record-types". If "string" is part of them, it needs
          // to be last.
          {
            "array": false,
            "code": 224,
            "encapsulate": "",
            "name": "my-lengthy-option",
            "record-types": "ipv4-address, psid, tuple, fqdn, string",
            "space": "my-fancy-space",
            "type": "record"
          },

          // Contains arrays of all types except strings since an array of strings
          // is not a valid option definition.
          {
            "array": true,
            "code": 254,
            "encapsulate": "",
            "name": "my-fancy-option",
            "record-types": "int8, int16, int32, uint8, uint16, uint32, ipv4-address, psid, tuple, fqdn",
            "space": "my-fancy-space",
            "type": "record"
          },

          // A single encapsulating space can be used. An option containing any
          // option from said space will now be unpacked successfully by Kea.
          {
            "array": false,
            "code": 232,
            "encapsulate": "my-fancy-space",
            "name": "my-encapsulating-option",
            "record-types": "",
            "space": "my-encapsulating-space",
            "type": "empty"
          }
        ],

        "subnet4": [
          /*
                                     DOCSIS3 option data
          */
          // Headers are as defined in CL-SP-CANN-DHCP-Reg-I16-200715.
          // "space" is required to be explicitly defined as "docsis3-v4"
          {
            "option-data": [
              /*
               0                   1                   2                   3
               0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              | CL_V4OPTION_ORO|  option-len  | req-opt-code-1| req-opt-code-2|
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |                              ...                              |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

              option-code   CL_V4OPTION_ORO (1).

              option-len    number of requested options.

              req-opt-code-n The option code for an option requested by the client.

              */
              // Type: array of {uint8}
              {
                "code": 1,
                "data": "32, 42",
                "name": "oro",
                "space": "docsis3-v4"
              },

              /*
               0                   1                   2                   3
               0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              | option code |    option-len   | IPv4 address of TFTP server 1 |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |  address of server 1 (cont.)  | IPv4 address of TFTP server 2 |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |  address of server 2 (cont.)  |              ...
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              .               ...             | IPv4 address of TFTP server n |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |  address of server n (cont.)  |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

              option code      CL_VV4OPTION_TFTP_SERVERS (2)

              option len       number of bytes for TFTP server IPv4 addresses (4*n for
                               n servers)
              */
              // Type: array of {IPv4 address}
              {
                "code": 2,
                "data": "192.0.2.76, 192.0.2.77",
                "name": "tftp-servers",
                "space": "docsis3-v4"
              }
            ],
            "id": 1,
            "subnet": "192.0.2.0/24"
          }
        ]
      }
    }

.. _config-example-kea4-backends-json:

------------------
kea4/backends.json
------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv4 server in Kea.
    // It is a basic scenario with one IPv4 subnet configured. It demonstrates
    // how to configure Kea to use various backends to store leases:
    // - memfile
    // - MySQL
    // - PostgreSQL

    { "Dhcp4":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // We need to specify lease type. Exactly one lease-database section
    // should be present. Make sure you uncomment only one.

    // 1. memfile backend. Leases information will be stored in flat CSV file.
    // This is the easiest backend to use as it does not require any extra
    // dependencies or services running.
    //  "lease-database": {
    //      "type": "memfile",
    //      "persist": true,
    //      "lfc-interval": 3600
    //  },

    // 2. MySQL backend. Leases will be stored in MySQL database. Make sure it
    // is up, running and properly initialized. See kea-admin documentation
    // for details on how to initialize the database. The only strictly required
    // parameters are type and name. If other parameters are not specified,
    // Kea will assume the database is available on localhost, that user and
    // password is not necessary to connect and that timeout is 5 seconds.
    // Kea must be compiled with the "-D mysql" option to use this backend.
    //  "lease-database": {
    //      "type": "mysql",
    //      "name": "keatest",
    //      "host": "localhost",
    //      "port": 3306,
    //      "user": "keatest",
    //      "password": "1234",
    //      "reconnect-wait-time": 3000, // expressed in ms
    //      "max-reconnect-tries": 3,
    //      "on-fail": "stop-retry-exit",
    //      "retry-on-startup": false,
    //      "connect-timeout": 3
    //  },
    // Since Kea.2.7.4, the libdhcp_mysql.so hook library must be loaded in order to
    // store leases in the MySQL Lease Database Backend.
    // Specify the lease backend hook library location.
    //  {
    //      // the MySQL lease backend hook library required for lease storage.
    //      "library": "libdhcp_mysql.so"
    //  },

    // 3. PostgreSQL backend. Leases will be stored in PostgreSQL database. Make
    // sure it is up, running and properly initialized. See kea-admin documentation
    // for details on how to initialize the database. The only strictly required
    // parameters are type and name. If other parameters are not specified,
    // Kea will assume the database is available on localhost, that user and
    // password is not necessary to connect and that timeout is 5 seconds.
    // Kea must be compiled with the "-D postgresql" option to use this backend.
    //  "lease-database": {
    //      "type": "postgresql",
    //      "name": "keatest",
    //      "host": "localhost",
    //      "port": 5432,
    //      "user": "keatest",
    //      "password": "1234",
    //      "reconnect-wait-time": 3000, // expressed in ms
    //      "max-reconnect-tries": 3,
    //      "on-fail": "stop-retry-exit",
    //      "retry-on-startup": false,
    //      "connect-timeout": 3
    //  },
    // Since Kea.2.7.4, the libdhcp_pgsql.so hook library must be loaded in order to
    // store leases in the PostgreSQL Lease Database Backend.
    // Specify the lease backend hook library location.
    //  {
    //      // the PostgreSQL lease backend hook library required for lease storage.
    //      "library": "libdhcp_pgsql.so"
    //  },

    // Addresses will be assigned with a lifetime of 4000 seconds.
      "valid-lifetime": 4000,

    // Renew and rebind timers are commented out. This implies that options
    // 58 and 59 will not be sent to the client. In this case it is up to
    // the client to pick the timer values according to RFC2131. Uncomment the
    // timers to send these options to the client.
    //  "renew-timer": 1000,
    //  "rebind-timer": 2000,

    // The following list defines subnets. We have only one subnet
    // here. We tell Kea that it is directly available over local interface.
      "subnet4": [
        {
           "pools": [ { "pool":  "192.0.2.1 - 192.0.2.200" } ],
           "id":1 ,
           "subnet": "192.0.2.0/24",
           "interface": "eth0"
        }
      ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp4",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea4-classify-json:

------------------
kea4/classify.json
------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv4 server in Kea.
    // The purpose of this example is to showcase how clients can be classified.

    { "Dhcp4":

    {

    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
          "interfaces": [ "eth0" ]
      },

    // Let's use the simplest backend: memfile and use some reasonable values
    // for timers. They are of no concern for the classification demonstration.
      "lease-database": { "type": "memfile" },
      "renew-timer": 1000,
      "rebind-timer": 2000,
      "valid-lifetime": 4000,

    // This list defines several classes that incoming packets can be assigned to.
    // One packet can belong to zero or more classes.
      "client-classes": [

    // The first class attempts to match the whole hardware address to a specific
    // value. All incoming packets with that MAC address will get a special
    // value of the option. If there are many hosts that require special
    // treatment, it is much better to use host reservations. However, doing
    // tricks with MAC addresses may prove useful in some cases, e.g.
    // by matching OUI to known values we can detect certain vendors.
      {
          "name": "special_snowflake",
          "test": "pkt4.mac == 0x010203040506",
          "option-data": [{
              "name": "domain-name-servers",
              "data": "127.0.0.1"
          }]
      },

    // Let's classify all incoming DISCOVER (message type 1) to a separate
    // class.
      {
          "name": "discovers",
          "test": "pkt4.msgtype == 1"
      },

    // Clients are supposed to set the transaction-id field to a random value.
    // Clients that send it with 0 are most likely broken. Let's mark them
    // as such.
      {
          "name": "broken",
          "test": "pkt4.transid == 0"
      },

    // Let's pick VoIP phones. Those that send their class identifiers
    // as Aastra, should belong to VoIP class. For a list of all options,
    // see www.iana.org/assignments/bootp-dhcp-parameters/.
    // In this particular class, we want to set specific values
    // of certain DHCPv4 fields. If the incoming packet matches the
    // test, those fields will be set in outgoing responses.
    // The option 43 is defined to encapsulate suboption in the aastra space.
      {
          "name": "VoIP",
          "test": "substring(option[60].hex,0,6) == 'Aastra'",
          "next-server": "192.0.2.254",
          "server-hostname": "hal9000",
          "boot-file-name": "/dev/null",
          "option-def": [ {
              "name": "vendor-encapsulated-options",
              "code": 43,
              "type": "empty",
              "encapsulate": "aastra" } ]
      }

      ],

    // The following list defines subnets. For some subnets we defined
    // a class that is allowed in that subnet. If not specified,
    // everyone is allowed. When a class is specified, only packets belonging
    // to that class are allowed for that subnet.
      "subnet4": [
        // This one is for VoIP devices only.
        {
            "pools": [ { "pool":  "192.0.2.1 - 192.0.2.200" } ],
            "id": 1,
            "subnet": "192.0.2.0/24",
            "client-classes": [ "VoIP" ],
            "interface": "eth0"
        },

        // This one doesn't have any client-class specified, so everyone
        // is allowed in. The normal subnet selection rules still apply,
        // though. There is also a static class reservation for a client
        // using MAC address 1a:1b:1c:1d:1e:1f. This client will always
        // be assigned to this class.
        {
            "pools": [ { "pool":  "192.0.3.1 - 192.0.3.200" } ],
            "id": 2,
            "subnet": "192.0.3.0/24",
            "reservations": [
            {
                "hw-address": "1a:1b:1c:1d:1e:1f",
                "client-classes": [ "VoIP" ]
            } ],
            "interface": "eth0"
        },

        // The following list defines a subnet with pools. For some pools
        // we defined a class that is allowed in that pool. If not specified
        // everyone is allowed. When a class is specified, only packets belonging
        // to that class are allowed for that pool.
        {
            "pools": [
               // This one is for VoIP devices only.
               {
                  "pool":  "192.0.4.1 - 192.0.4.200",
                  "client-classes": [ "VoIP" ]
               },

               // This one doesn't have any client-class specified,
               // so everyone is allowed in.
               {
                   "pool":  "192.0.5.1 - 192.0.5.200"
               } ],

            "subnet": "192.0.4.0/23",
            "id": 3,
            "interface": "eth1"
        }
      ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp4",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea4-classify2-json:

-------------------
kea4/classify2.json
-------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv4 server in Kea.
    // The purpose of this example is to showcase how clients can be classified
    // with advanced features.

    { "Dhcp4":

    {

    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
          "interfaces": [ "eth0" ]
      },

    // Let's use the simplest backend: memfile and use some reasonable values
    // for timers. They are of no concern for the classification demonstration.
      "lease-database": { "type": "memfile" },
      "renew-timer": 1000,
      "rebind-timer": 2000,
      "valid-lifetime": 4000,

    // This list defines several classes that incoming packets can be assigned to.
    // One packet can belong to zero or more classes.
      "client-classes": [

    // This class is included by the second subnet in its 'evaluate-additional-classes'
    // list so 'only-in-additional-list' is enabled. This ensures the class will only
    // be evaluated if the second subnet is selected. The test expression returns true.
    // Note it is not possible to depend on VoIP class because it is not yet
    // defined.
      {
          "name": "second_subnet",
          "only-in-additional-list": true,
          "test": "member('ALL')",
          "option-data": [{
              "name": "domain-name-servers",
              "data": "127.0.0.1"
          }]
      },

    // Let's classify all incoming DISCOVER (message type 1) to a separate
    // class.
      {
          "name": "discovers",
          "test": "pkt4.msgtype == 1"
      },

    // Clients are supposed to set the transaction-id field to a random value.
    // Clients that send it with 0 are most likely broken. Let's mark them
    // as such.
      {
          "name": "broken",
          "test": "pkt4.transid == 0"
      },

    // Let's pick VoIP phones. Those that send their class identifiers
    // as Aastra, should belong to VoIP class. For a list of all options,
    // see www.iana.org/assignments/bootp-dhcp-parameters/.
    // In this particular class, we want to set specific values
    // of certain DHCPv4 fields. If the incoming packet matches the
    // test, those fields will be set in outgoing responses.
    // The option 43 is defined to encapsulate suboption in the aastra space.
      {
          "name": "VoIP",
          "test": "substring(option[60].hex,0,6) == 'Aastra'",
          "next-server": "192.0.2.254",
          "server-hostname": "hal9000",
          "boot-file-name": "/dev/null",
          "option-def": [ {
              "name": "vendor-encapsulated-options",
              "code": 43,
              "type": "empty",
              "encapsulate": "aastra" } ]
      },

    // Both a VoIP phone (by evaluation or host reservation) and has a host
    // reservation.
      {
          "name": "VoIP_host",
          "test": "member('VoIP') and member('KNOWN')",
          "server-hostname": "hal9001"
      }

      ],

    // The following list defines subnets. For some subnets we defined
    // a class that is allowed in that subnet. If not specified,
    // everyone is allowed. When a class is specified, only packets belonging
    // to that class are allowed for that subnet.
      "subnet4": [
        {
    // This one is for VoIP devices only.
            "pools": [ { "pool":  "192.0.2.1 - 192.0.2.200" } ],
            "id": 1,
            "subnet": "192.0.2.0/24",
            "client-classes": [ "VoIP" ],
            "interface": "eth0"
        },
    // This one doesn't have any client-class specified, so everyone
    // is allowed in. The normal subnet selection rules still apply,
    // though. There is also a static class reservation for a client
    // using MAC address 1a:1b:1c:1d:1e:1f. This client will always
    // be assigned to this class.
        {
            "pools": [ { "pool":  "192.0.3.1 - 192.0.3.200" } ],
            "id": 2,
            "subnet": "192.0.3.0/24",
            "reservations": [
            {
                "hw-address": "1a:1b:1c:1d:1e:1f",
                "client-classes": [ "VoIP" ]
            } ],
            "interface": "eth0",
            "evaluate-additional-classes": [ "second_subnet" ]
        },

    // The following list defines a subnet with pools. For some pools
    // we defined a class that is allowed in that pool. If not specified
    // everyone is allowed. When a class is specified, only packets belonging
    // to that class are allowed for that pool.
         {
            "pools": [
               {
    // This one is for VoIP devices only.
                  "pool":  "192.0.4.1 - 192.0.4.200",
                  "client-classes": [ "VoIP" ]
               },
    // This one doesn't have any client-class specified, so everyone
    // is allowed in.
               {
                   "pool":  "192.0.5.1 - 192.0.5.200"
               } ],
               "id": 3,
               "subnet": "192.0.4.0/23",
               "interface": "eth1"
            },
    // This subnet is divided in two pools for unknown and known
    // (i.e. which have a reservation) clients. The built-in KNOWN and
    // UNKNOWN classes are set or not at host reservation lookup (KNOWN if
    // this returns something, UNKNOWN if this finds nothing) and client
    // classes depending on it are evaluated.
    // This happens after subnet selection and before address allocation
    // from pools.
            {
               "pools": [
                    {
                       "pool": "192.0.8.100 - 192.0.8.200",
                       "client-classes": [ "UNKNOWN" ]
                    },
                    {
                       "pool": "192.0.9.100 - 192.0.9.200",
                       "client-classes": [ "KNOWN" ]
                    }
                ],
                "id": 4,
                "subnet": "192.0.8.0/23",
                "reservations": [
                    {  "hw-address": "00:00:00:11:22:33", "hostname": "h1" },
                    {  "hw-address": "00:00:00:44:55:66", "hostname": "h4" },
                    {  "hw-address": "00:00:00:77:88:99", "hostname": "h7" },
                    {  "hw-address": "00:00:00:aa:bb:cc", "hostname": "ha" }
                ]
            }
      ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp4",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea4-comments-json:

------------------
kea4/comments.json
------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv4 server in Kea.
    // It uses embedded (i.e., which will be included in configuration objects
    // and not stripped by at lexical analysis) comments.

    { "Dhcp4":

    {
       // Global scope
       "comment": "A DHCPv4 server",

       // In interface config
       "interfaces-config": {
           "comment": "Use wildcard",
           "interfaces": [ "*" ] },

       // In option definitions
       "option-def": [ {
           "comment": "An option definition",
           "name": "foo",
           "code": 100,
           "type": "ipv4-address",
           "space": "isc"
        } ],

       // In option data
       "option-data": [ {
           "comment": "Set option value",
           "name": "dhcp-message",
           "data": "ABCDEF0105",
           "csv-format": false
        } ],

       // In client classes
       "client-classes": [
           {
              "comment": "match all",
              "name": "all",
              "test": "'' == ''"
           },
           // Of course comments are optional
           {
              "name": "none"
           },
           // A comment and a user-context can be specified
           {
              "comment": "a comment",
              "name": "both",
              "user-context": {
                  "version": 1
              }
           }
       ],

       // In control sockets.
       "control-sockets": [
           {
               "socket-type": "unix",
               "socket-name": "kea4-ctrl-socket",
               "user-context": { "comment": "Indirect comment" }
           },
           {
               "comment": "HTTP control socket",
               "socket-type": "http",
               "socket-address": "::1",
               "socket-port": 8004,

               // In authentication
               "authentication": {
                   "comment": "basic HTTP authentication",
                   "type": "basic",
                   // In basic HTTP authentication clients
                   "clients": [ {
                       "user": "admin",
                       "password": "1234"
                   } ]
               }
           }
       ],

       // In shared networks
       "shared-networks": [ {
           "comment": "A shared network",
           "name": "foo",

           // In subnets
           "subnet4": [
             {
               "comment": "A subnet",
               "subnet": "192.0.1.0/24",
               "id": 100,

               // In pools
               "pools": [
                 {
                    "comment": "A pool",
                    "pool": "192.0.1.1-192.0.1.10"
                 }
               ],

               // In host reservations
               "reservations": [
                 {
                    "comment": "A host reservation",
                    "hw-address": "AA:BB:CC:DD:EE:FF",
                    "hostname": "foo.example.com",

                    // Again in an option data
                    "option-data": [ {
                        "comment": "An option in a reservation",
                        "name": "domain-name",
                        "data": "example.com"
                    } ]
                 }
               ]
             }
           ]
        } ],

       // In dhcp ddns
       "dhcp-ddns": {
           "comment": "No dynamic DNS",
           "enable-updates": false
       },

       // In loggers
       "loggers": [ {
           "comment": "A logger",
           "name": "kea-dhcp4"
       } ]
    }

    }

.. _config-example-kea4-config-backend-json:

------------------------
kea4/config-backend.json
------------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv4 server in Kea.
    // It demonstrates how to enable Kea Configuration Backend using MySQL.
    // It requires that libdhcp_mysql.so library is available and
    // optionally libdhcp_cb_cmds.so hook library.

    { "Dhcp4":

    {
        // Set the server tag for the configuration backend. This instance will
        // be named server1. Every configuration element that is applicable to
        // either "all" or "server1" will be used by this instance.
        "server-tag": "server1",

        // Kea is told to listen on eth0 interface only.
        "interfaces-config": {
            "interfaces": [ "eth0" ]
        },

        // Use memfile lease database backend.
        "lease-database": {
            "type": "memfile",
            "lfc-interval": 3600
        },

        // This parameter controls how the server accesses the configuration
        // database. Currently only two database types are available - "mysql" and
        // "postgresql".
        // Using "mysql" requires that the libdhcp_mysql.so hook library is loaded.
        // If using "postgresql", then loading libdhcp_pgsql.so hook library is
        // required.
        "config-control": {
            // A list of database backends to connect to. Currently, it is limited
            // to a single backend.
            "config-databases": [
                {
                    "type": "mysql",
                    "reconnect-wait-time": 3000, // expressed in ms
                    "max-reconnect-tries": 3,
                    "name": "kea",
                    "user": "kea",
                    "password": "1234",
                    "host": "localhost",
                    "port": 3306
                }
            ],
            // Controls how often the server polls the database for the
            // configuration updates. The setting below implies that it
            // will take up to approx. 20 seconds for the server to
            // discover and fetch configuration changes.
            "config-fetch-wait-time": 20
        },

        // This defines a control socket. If defined, Kea will open a UNIX socket
        // and will listen for incoming commands. See section 17 of the Kea ARM for
        // details.
        "control-socket": {
            "socket-type": "unix",
            "socket-name": "kea4-ctrl-socket"
        },

        // Hooks libraries that enable configuration backend are loaded.
        "hooks-libraries": [
            // The libdhcp_mysql.so is required to use MySQL Configuration
            // Backend.
            {
                "library": "libdhcp_mysql.so"
            }
            // If using PostgreSQL Configuration Backend, the "libdhcp_pgsql.so" is
            // required.
            // {
            //    "library": "libdhcp_pgsql.so"
            // }
            // The libdhcp_cb_cmds.so is optional. It allows for managing the
            // configuration in the database. If this library is not loaded,
            // the configuration can be managed directly using available
            // tools that work directly with the MySQL database.
            // ,{
            //     "library": "libdhcp_cb_cmds.so"
            // }
        ],

        // The following configures logging. It assumes that messages with at
        // least informational level (info, warn, error and fatal) should be
        // logged to stdout. Alternatively, you can specify stderr here, a filename
        // or 'syslog', which will store output messages via syslog.
        "loggers": [
            {
                "name": "kea-dhcp4",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea4-dhcpv4-over-dhcpv6-json:

----------------------------
kea4/dhcpv4-over-dhcpv6.json
----------------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv4 server of
    // DHCPv4-over-DHCPv6 tests in Kea.

    {

    // DHCPv4 conf
    "Dhcp4":
    {
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

      "lease-database": {
          "type": "memfile",
          "name": "kea-leases4.csv",
          "lfc-interval": 3600
      },

      "valid-lifetime": 4000,

      "subnet4": [
       {
            "id": 100,
            "subnet": "10.10.10.0/24",
    // Don't forget the "4o6-" before "interface" here!
            "4o6-interface": "eth0",
            "4o6-subnet": "2001:db8:1:1::/64",
            "pools": [ { "pool": "10.10.10.100 - 10.10.10.199" } ] }
      ],

    // This enables DHCPv4-over-DHCPv6 support
      "dhcp4o6-port": 786,

      "loggers": [
        {
          "name": "kea-dhcp4",
          "output-options": [
              {
                "output": "kea-dhcp4.log"
              }
          ],
          "severity": "DEBUG",
          "debuglevel": 0
        }
      ]
    }

    }

.. _config-example-kea4-global-reservations-json:

-----------------------------
kea4/global-reservations.json
-----------------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv4 server in Kea.
    // It demonstrates how global host reservations can be configured.
    // The global reservations are not associated with any subnet. They
    // are assigned regardless of the subnet to which the DHCP client belongs.
    // Global reservations are assigned to the DHCP clients using the
    // same host identifier types as subnet specific reservations. This file
    // contains multiple examples of host reservations using different
    // identifier types, e.g. MAC address, client identifier etc.
    { "Dhcp4":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // We need to specify the database used to store leases. As of June
    // 2022, three database backends are supported: MySQL, PostgreSQL and
    // the in-memory database, Memfile.  We'll use memfile because it doesn't
    // require any prior set up.
      "lease-database": {
          "type": "memfile",
          "lfc-interval": 3600
      },

    // Addresses will be assigned with a lifetime of 4000 seconds.
      "valid-lifetime": 4000,

    // Renew and rebind timers are commented out. This implies that options
    // 58 and 59 will not be sent to the client. In this case it is up to
    // the client to pick the timer values according to RFC2131. Uncomment the
    // timers to send these options to the client.
    //  "renew-timer": 1000,
    //  "rebind-timer": 2000,

    // Kea supports reservations by several different types of identifiers:
    // hw-address (hardware/MAC address of the client), duid (DUID inserted by the
    // client), client-id (client identifier inserted by the client), circuit-id
    // (circuit identifier inserted by the relay agent) and flex-id (flexible
    // identifier available when flex_id hook library is loaded). When told to do
    // so, Kea can check for all of those identifier types, but it takes a costly
    // database lookup to do so. It is therefore useful from a performance
    // perspective to use only the reservation types that are actually used in a
    // given network.

    // The example below is not optimal from a performance perspective, but it
    // nicely showcases the host reservation capabilities. Please use the minimum
    // set of identifier types used in your network.
      "host-reservation-identifiers": [ "circuit-id", "hw-address", "duid",
                                        "client-id", "flex-id" ],

    // This directive tells Kea that reservations are global. Note that this
    // can also be specified at shared network and/or subnet level.

    // Specify whether the server should look up global reservations.
      "reservations-global": true,

    // Specify whether the server should look up in-subnet reservations.
      "reservations-in-subnet": false,

    // Specify whether the server can assume that all reserved addresses
    // are out-of-pool.
    // Ignored when reservations-in-subnet is false.
    // If specified, it is inherited by "shared-networks" and "subnet4" levels.
      "reservations-out-of-pool": false,

    // Define several global host reservations.
      "reservations": [

    // This is a reservation for a specific hardware/MAC address. It's a very
    // simple reservation: just an address and nothing else.
    // Note it is not recommended but still allowed to reverse addresses at
    // the global scope: as it breaks the link between the reservation and
    // the subnet it can lead to a client localized in another subnet than
    // its address belongs to.
        {
            "hw-address": "1a:1b:1c:1d:1e:1f",
            "ip-address": "192.0.2.201"
        },

    // This is a reservation for a specific client-id. It also shows
    // the this client will get a reserved hostname. A hostname can be defined
    // for any identifier type, not just client-id. Either a hostname or
    // an address is required.
        {
            "client-id": "01:11:22:33:44:55:66",
            "hostname": "special-snowflake"
        },

    // The third reservation is based on DUID. This reservation also
    // defines special option values for this particular client. If
    // the domain-name-servers option would have been defined on a global,
    // subnet or class level, the host specific values take precedence for
    // this particular DHCP client.
        {
            "duid": "01:02:03:04:05",
            "ip-address": "192.0.2.203",
            "option-data": [ {
                "name": "domain-name-servers",
                "data": "10.1.1.202,10.1.1.203"
            } ]
        },

    // The fourth reservation is based on circuit-id. This is an option inserted
    // by the relay agent that forwards the packet from client to the server.
    // In this example the host is also assigned vendor specific options.
        {
            "circuit-id": "01:11:22:33:44:55:66",
            "ip-address": "192.0.2.204",
            "option-data": [
                {
                    "name": "vivso-suboptions",
                    "data": "4491"
                },
                {
                    "name": "tftp-servers",
                    "space": "vendor-4491",
                    "data": "10.1.1.202,10.1.1.203"
                }
            ]
        },

    // This reservation is for a client that needs specific DHCPv4 fields to be
    // set. Three supported fields are next-server, server-hostname and
    // boot-file-name
        {
            "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"
        },

    // This reservation is using flexible identifier. Instead of relying
    // on specific field, sysadmin can define an expression similar to what
    // is used for client classification,
    // e.g. substring(relay[0].option[17],0,6). Then, based on the value of
    // that expression for incoming packet, the reservation is matched.
    // Expression can be specified either as hex or plain text using single
    // quotes.
    // Note: flexible identifier requires flex_id hook library to be
    // loaded to work.
        {
            "flex-id": "'s0mEVaLue'",
            "ip-address": "192.0.2.206"
        }
      ],

      // Define a subnet.
        "subnet4": [
            {
               "pools": [ { "pool":  "192.0.2.1 - 192.0.2.200" } ],
               "id": 1,
               "subnet": "192.0.2.0/24",
               "interface": "eth0"
            }
        ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp4",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea4-ha-load-balancing-server1-mt-with-tls-json:

-----------------------------------------------
kea4/ha-load-balancing-server1-mt-with-tls.json
-----------------------------------------------

.. code-block::
    :linenos:

    // This is an example configuration of the Kea DHCPv4 server. It uses High
    // Availability hook library and Lease Commands hook library to enable
    // High Availability function for the DHCP server. Note that almost exactly
    // the same configuration must be used on the second server (partner).
    // The only difference is that "this-server-name" must be set to "server2"
    // on this other server. Also, the interface configuration and location of TLS
    // specific files depend on the network settings and configuration of the
    // particular machine.
    //
    // The servers using this configuration work in load balancing mode.
    {

    // DHCPv4 configuration starts here.
    "Dhcp4": {
        // Add names of your network interfaces to listen on.
        "interfaces-config": {
            // The DHCPv4 server listens on this interface.
            "interfaces": [ "eth0" ]
        },

        // Multi-threading parameters.
        "multi-threading": {
            // By default, Kea processes packets on multiple threads if the hardware permits.
            "enable-multi-threading": true,

            // When multi-threading is enabled, Kea will process packets on a
            // number of multiple threads configurable through this option.
            "thread-pool-size": 4,

            // When multi-threading is enabled, Kea will read packets from the
            // interface and append a working item to the thread pool. This
            // option configures the maximum number of items that can be queued.
            "packet-queue-size": 64
        },

        // Use Memfile lease database backend to store leases in a CSV file.
        // Depending on how Kea was compiled, it may also support SQL databases
        // (MySQL and/or PostgreSQL). Those database backends require more
        // parameters, like name, host and possibly user and password.
        // There are dedicated examples for each backend. See Section 7.2.2 "Lease
        // Storage" for details.
        "lease-database": {
            // Memfile is the simplest and easiest backend to use. It's an in-memory
            "type": "memfile"
        },

        // Client classes will associate address pools with certain servers taking
        // part in providing High Availability.
        "client-classes": [
            // phones class
            {
                "name": "phones",
                "test": "substring(option[60].hex,0,6) == 'Aastra'"
            },
            // laptops are everything but phones.
            {
                "name": "laptops",
                "test": "not member('phones')"
            },
            // Some phones will be handled by server1. Whether the HA_server1
            // or HA_server2 is assigned for the client is a matter of load
            // balancing performed by the HA hook library.
            {
                "name": "phones_server1",
                "test": "member('phones') and member('HA_server1')"
            },
            // Some phones will be handled by server2.
            {
                "name": "phones_server2",
                "test": "member('phones') and member('HA_server2')"
            },
            // Some laptops will be handled by server1.
            {
                "name": "laptops_server1",
                "test": "member('laptops') and member('HA_server1')"
            },
            // Some laptops will be handled by server2.
            {
                "name": "laptops_server2",
                "test": "member('laptops') and member('HA_server2')"
            }
        ],

        // HA requires two hook libraries to be loaded: libdhcp_lease_cmds.so and
        // libdhcp_ha.so. The former handles incoming lease updates from the HA peers.
        // The latter implements high availability feature for Kea.
        "hooks-libraries": [
            // The lease_cmds library must be loaded because HA makes use of it to
            // deliver lease updates to the server as well as synchronize the
            // lease database after failure.
            {
                "library": "libdhcp_lease_cmds.so",
                "parameters": { }
            },
            {
                // The HA hook library should be loaded.
                "library": "libdhcp_ha.so",
                "parameters": {
                    // High Availability configuration is specified for the HA hook library.
                    // Each server should have the same HA configuration, except for the
                    // "this-server-name" parameter.
                    "high-availability": [ {
                        // This parameter points to this server instance. The respective
                        // HA peers must have this parameter set to their own names.
                        "this-server-name": "server1",
                        // The HA mode is set to load-balancing. In this mode, the active
                        // servers share the traffic (50/50).
                        "mode": "load-balancing",
                        // Heartbeat is to be sent every 10 seconds if no other control
                        // commands are transmitted.
                        "heartbeat-delay": 10000,
                        // Maximum time for partner's response to a heartbeat, after which
                        // failure detection is started. This is specified in milliseconds.
                        "max-response-delay": 60000,
                        // The following parameters control how the server detects the
                        // partner's failure. The ACK delay sets the threshold for the
                        // 'secs' field of the received discovers. This is specified in
                        // milliseconds.
                        "max-ack-delay": 5000,
                        // This specifies the number of clients which send messages to
                        // the partner but appear to not receive any response.
                        "max-unacked-clients": 5,
                        // This specifies the maximum timeout (in milliseconds) for the server
                        // to complete sync. If you have a large deployment (high tens or
                        // hundreds of thausands of clients), you may need to increase it
                        // further. The default value is 60000ms (60 seconds).
                        "sync-timeout": 60000,
                        // To not experience performance degradation when the Kea server is
                        // processing packets on multiple threads, the High Availability module
                        // must have multi-threading enabled.
                        "multi-threading": {
                            // Enable High Availability to benefit from multi-threading. Default: true.
                            "enable-multi-threading": true,
                            // When running in MT mode, the dedicated listener is used to handle
                            // lease updates.
                            "http-dedicated-listener": true,
                            // The number of threads used to handle incoming requests.
                            // A value of 0 instructs the server to use the same number of
                            // threads that the Kea core is using for DHCP multi-threading.
                            "http-listener-threads": 0,
                            // The number of threads used to handle outgoing requests.
                            // A value of 0 instructs the server to use the same number of
                            // threads that the Kea core is using for DHCP multi-threading.
                            "http-client-threads": 0
                        },
                        "peers": [
                            // This is the configuration of this server instance.
                            {
                                "name": "server1",
                                // This specifies the URL of this server instance.
                                "url": "http://192.168.56.33:8005/",
                                // Trust anchor aka certificate authority file or directory.
                                "trust-anchor": "/usr/lib/kea/CA.pem",
                                // Client certificate file name.
                                "cert-file": "/usr/lib/kea/server1_cert.pem",
                                // Private key file name.
                                "key-file": "/usr/lib/kea/server1_key.pem",
                                // Client certificates are required and verified.
                                "require-client-certs": true,
                                // This server is primary. The other one must be
                                // secondary.
                                "role": "primary"
                            },
                            // This is the configuration of the HA peer.
                            {
                                "name": "server2",
                                // Specifies the URL on which the partner's control
                                // channel can be reached.
                                "url": "http://192.168.56.66:8005/",
                                // Trust anchor aka certificate authority file or directory.
                                "trust-anchor": "/usr/lib/kea/CA.pem",
                                // Client certificate file name.
                                "cert-file": "/usr/lib/kea/server2_cert.pem",
                                // Private key file name.
                                "key-file": "/usr/lib/kea/server2_key.pem",
                                // Client certificates are required and verified.
                                "require-client-certs": true,
                                // The partner is secondary. This server is primary.
                                "role": "secondary"
                            }
                        ]
                    } ]
                }
            }
        ],

        // This example contains a single subnet declaration.
        "subnet4": [
            {
                // Subnet id.
                "id": 1,

                // Subnet prefix.
                "subnet": "192.0.3.0/24",

                // Specify four address pools.
                "pools": [
                    {
                        "pool": "192.0.3.100 - 192.0.3.125",
                        "client-classes": [ "phones_server1" ]
                    },
                    {
                        "pool": "192.0.3.126 - 192.0.3.150",
                        "client-classes": [ "laptops_server1" ]
                    },
                    {
                        "pool": "192.0.3.200 - 192.0.3.225",
                        "client-classes": [ "phones_server2" ]
                    },
                    {
                        "pool": "192.0.3.226 - 192.0.3.250",
                        "client-classes": [ "laptops_server2" ]
                    }
                ],

                // These are options that are subnet specific. In most cases,
                // you need to define at least routers option, as without this
                // option your clients will not be able to reach their default
                // gateway and will not have Internet connectivity.
                "option-data": [
                    {
                        // For each IPv4 subnet you most likely need to specify at
                        // least one router.
                        "name": "routers",
                        "data": "192.0.3.1"
                    }
                ],

                // This subnet will be selected for queries coming from the following
                // IP address.
                "relay": { "ip-addresses": [ "192.168.56.1" ] }
            }
        ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout. Alternatively, you can specify stderr here, a filename
    // or 'syslog', which will store output messages via syslog.
        "loggers": [
            {
                // This section affects kea-dhcp4, which is the base logger for DHCPv4
                // component. It tells DHCPv4 server to write all log messages (on
                // severity INFO or more) to a file.
                "name": "kea-dhcp4",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "severity": "INFO",
                "debuglevel": 0
            },
            {
                // This section specifies configuration of the HA hook library-specific
                // logger.
                "name": "kea-dhcp4.ha-hooks",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "severity": "INFO",
                "debuglevel": 99
            }
        ]
    }
    }

.. _config-example-kea4-ha-load-balancing-server2-mt-json:

--------------------------------------
kea4/ha-load-balancing-server2-mt.json
--------------------------------------

.. code-block::
    :linenos:

    // This is an example configuration of the Kea DHCPv4 server. It uses High
    // Availability hook library and Lease Commands hook library to enable
    // High Availability function for the DHCP server. Note that almost exactly
    // the same configuration must be used on the second server (partner).
    // The only difference is that "this-server-name" must be set to "server1"
    // on this other server. Also, the interface configuration depends on the
    // network settings of the particular machine.
    //
    // The servers using this configuration work in load balancing mode.
    {

    // DHCPv4 configuration starts here.
    "Dhcp4": {
        // Add names of your network interfaces to listen on.
        "interfaces-config": {
            // The DHCPv4 server listens on this interface.
            "interfaces": [ "eth0" ]
        },

        // Multi-threading parameters.
        "multi-threading": {
            // By default, Kea processes packets on multiple threads if the hardware permits.
            "enable-multi-threading": true,

            // When multi-threading is enabled, Kea will process packets on a
            // number of multiple threads configurable through this option.
            "thread-pool-size": 4,

            // When multi-threading is enabled, Kea will read packets from the
            // interface and append a working item to the thread pool. This
            // option configures the maximum number of items that can be queued.
            "packet-queue-size": 64
        },

        // Use Memfile lease database backend to store leases in a CSV file.
        // Depending on how Kea was compiled, it may also support SQL databases
        // (MySQL and/or PostgreSQL). Those database backends require more
        // parameters, like name, host and possibly user and password.
        // There are dedicated examples for each backend. See Section 7.2.2 "Lease
        // Storage" for details.
        "lease-database": {
            // Memfile is the simplest and easiest backend to use. It's an in-memory
            "type": "memfile"
        },

        // Client classes will associate address pools with certain servers taking
        // part in providing High Availability.
        "client-classes": [
            // phones class
            {
                "name": "phones",
                "test": "substring(option[60].hex,0,6) == 'Aastra'"
            },
            // laptops are everything but phones.
            {
                "name": "laptops",
                "test": "not member('phones')"
            },
            // Some phones will be handled by server1. Whether the HA_server1
            // or HA_server2 is assigned for the client is a matter of load
            // balancing performed by the HA hook library.
            {
                "name": "phones_server1",
                "test": "member('phones') and member('HA_server1')"
            },
            // Some phones will be handled by server2.
            {
                "name": "phones_server2",
                "test": "member('phones') and member('HA_server2')"
            },
            // Some laptops will be handled by server1.
            {
                "name": "laptops_server1",
                "test": "member('laptops') and member('HA_server1')"
            },
            // Some laptops will be handled by server2.
            {
                "name": "laptops_server2",
                "test": "member('laptops') and member('HA_server2')"
            }
        ],

        // HA requires two hook libraries to be loaded: libdhcp_lease_cmds.so and
        // libdhcp_ha.so. The former handles incoming lease updates from the HA peers.
        // The latter implements high availability feature for Kea.
        "hooks-libraries": [
            // The lease_cmds library must be loaded because HA makes use of it to
            // deliver lease updates to the server as well as synchronize the
            // lease database after failure.
            {
                "library": "libdhcp_lease_cmds.so",
                "parameters": { }
            },
            {
                // The HA hook library should be loaded.
                "library": "libdhcp_ha.so",
                "parameters": {
                    // High Availability configuration is specified for the HA hook library.
                    // Each server should have the same HA configuration, except for the
                    // "this-server-name" parameter.
                    "high-availability": [ {
                        // This parameter points to this server instance. The respective
                        // HA peers must have this parameter set to their own names.
                        "this-server-name": "server2",
                        // The HA mode is set to load-balancing. In this mode, the active
                        // servers share the traffic (50/50).
                        "mode": "load-balancing",
                        // Heartbeat is to be sent every 10 seconds if no other control
                        // commands are transmitted.
                        "heartbeat-delay": 10000,
                        // Maximum time for partner's response to a heartbeat, after which
                        // failure detection is started. This is specified in milliseconds.
                        "max-response-delay": 60000,
                        // The following parameters control how the server detects the
                        // partner's failure. The ACK delay sets the threshold for the
                        // 'secs' field of the received discovers. This is specified in
                        // milliseconds.
                        "max-ack-delay": 5000,
                        // This specifies the number of clients which send messages to
                        // the partner but appear to not receive any response.
                        "max-unacked-clients": 5,
                        // This specifies the maximum timeout (in milliseconds) for the server
                        // to complete sync. If you have a large deployment (high tens or
                        // hundreds of thausands of clients), you may need to increase it
                        // further. The default value is 60000ms (60 seconds).
                        "sync-timeout": 60000,
                        // To not experience performance degradation when the Kea server is
                        // processing packets on multiple threads, the High Availability module
                        // must have multi-threading enabled.
                        "multi-threading": {
                            // Enable High Availability to benefit from multi-threading. Default: true.
                            "enable-multi-threading": true,
                            // When running in MT mode, the dedicated listener is used to handle
                            // lease updates.
                            "http-dedicated-listener": true,
                            // The number of threads used to handle incoming requests.
                            // A value of 0 instructs the server to use the same number of
                            // threads that the Kea core is using for DHCP multi-threading.
                            "http-listener-threads": 0,
                            // The number of threads used to handle outgoing requests.
                            // A value of 0 instructs the server to use the same number of
                            // threads that the Kea core is using for DHCP multi-threading.
                            "http-client-threads": 0
                        },
                        "peers": [
                            // This is the configuration of the HA peer.
                            {
                                "name": "server1",
                                // Specifies the URL on which the partner's control
                                // channel can be reached.
                                "url": "http://192.168.56.33:8005/",
                                // The partner is primary. This server is secondary.
                                "role": "primary"
                            },
                            // This is the configuration of this server instance.
                            {
                                "name": "server2",
                                // This specifies the URL of this server instance.
                                "url": "http://192.168.56.66:8005/",
                                // This server is secondary. The other one must be
                                // primary.
                                "role": "secondary"
                            }
                        ]
                    } ]
                }
            }
        ],

        // This example contains a single subnet declaration.
        "subnet4": [
            {
                // Subnet id.
                "id": 1,

                // Subnet prefix.
                "subnet": "192.0.3.0/24",

                // Specify four address pools.
                "pools": [
                    {
                        "pool": "192.0.3.100 - 192.0.3.125",
                        "client-classes": [ "phones_server1" ]
                    },
                    {
                        "pool": "192.0.3.126 - 192.0.3.150",
                        "client-classes": [ "laptops_server1" ]
                    },
                    {
                        "pool": "192.0.3.200 - 192.0.3.225",
                        "client-classes": [ "phones_server2" ]
                    },
                    {
                        "pool": "192.0.3.226 - 192.0.3.250",
                        "client-classes": [ "laptops_server2" ]
                    }
                ],

                // These are options that are subnet specific. In most cases,
                // you need to define at least routers option, as without this
                // option your clients will not be able to reach their default
                // gateway and will not have Internet connectivity.
                "option-data": [
                    {
                        // For each IPv4 subnet you most likely need to specify at
                        // least one router.
                        "name": "routers",
                        "data": "192.0.3.1"
                    }
                ],

                // This subnet will be selected for queries coming from the following
                // IP address.
                "relay": { "ip-addresses": [ "192.168.56.1" ] }
            }
        ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout. Alternatively, you can specify stderr here, a filename
    // or 'syslog', which will store output messages via syslog.
        "loggers": [
            {
                // This section affects kea-dhcp4, which is the base logger for DHCPv4
                // component. It tells DHCPv4 server to write all log messages (on
                // severity INFO or more) to a file.
                "name": "kea-dhcp4",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "severity": "INFO",
                "debuglevel": 0
            },
            {
                // This section specifies configuration of the HA hook library-specific
                // logger.
                "name": "kea-dhcp4.ha-hooks",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "severity": "INFO",
                "debuglevel": 99
            }
        ]
    }
    }

.. _config-example-kea4-hooks-radius-json:

----------------------
kea4/hooks-radius.json
----------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv4 server in Kea
    // illustrating the configuration of the RADIUS and Host Cache hook libraries.
    //
    // It is not intended to be used as is. It tries to showcase some of the
    // parameters available.
    //
    // To use this configuration file, you need to have both RADIUS and
    // Host Cache hooks.
    //
    // clients get a wine name (option AOP code 250) divided into red and white.
    // Expensive brands have a host entry, i.e. a reserved address.
    //
    // Names
    //
    // brouilly (red)
    // chablis (white)
    // chambertin (red, expensive)
    // chinon (red)
    // chiroubles (red)
    // condrieu (white)
    // cornas (red)
    // corton (red)
    // fleurie (red)
    // givry (red)
    // margaux (red, expensive)
    // meursault (white)
    // montrachet (white, expensive)
    // morgon (red)
    // muscadet (white)
    // petrus (red, expensive)
    // riesling (white)
    // romanee (red, expensive)
    // sylvaner (white)
    // yquem (white, expensive)
    //
    // Address space is 192.0.2.0/24 with 10-99 for reds and 110-199 for whites.
    //
    // Reservations are given here in Kea/JSON style but they must be
    // in the RADIUS server configuration:
    //
    //       {
    //          "flex-id": "'chambertin'",
    //          "ip-address": "192.0.2.10"
    //       },
    //       {
    //          "flex-id": "'margaux'",
    //          "ip-address": "192.0.2.11"
    //       },
    //       {
    //          "flex-id": "'petrus'",
    //          "ip-address": "192.0.2.12"
    //       },
    //       {
    //          "flex-id": "'romanee'",
    //          "ip-address": "192.0.2.13"
    //       },
    //       {
    //          "flex-id": "'montrachet'",
    //          "ip-address": "192.0.2.110"
    //       },
    //       {
    //          "flex-id": "'yquem'",
    //          "ip-address": "192.0.2.111"
    //       }
    //

    {"Dhcp4":

    {
      // Kea is told to listen on specific interfaces only.
      "interfaces-config": {
        // You should probably list your network interfaces here (e.g. "eth1961")
        "interfaces": [ "eth1961" ]
      },

      // Set up the storage for leases.
      "lease-database": {
        "type": "memfile"
      },

      // Note there is hosts-database defined. RADIUS and Host Cache libraries
      // will create them dynamically.

      // RADIUS uses flex-id reservations, so restrict Kea to use flex-id only.
      "host-reservation-identifiers": [ "flex-id" ],

      // Define the AOP option.
      "option-def": [ {
          "name": "AOP",
          "code": 250,
          "type": "string" } ],

      // Define red and white client classes.
      // If they are not defined we can get spurious warnings.
      "client-classes": [
          { "name": "red" },
          { "name": "white" } ],

      // Define a subnet.
      "subnet4": [ {
          // Set the subnet ID (aka RADIUS NAS port).
          "id": 14,
          "subnet": "192.0.2.0/24",
          "interface": "eth1961",
          "pools": [
             {
                // Red pool (10-19 are for reservations)
                "pool": "192.0.2.20-192.0.2.99",
                "client-classes": [ "red" ]
             },
             {
                // White pool (110-119 are for reservations)
                "pool": "192.0.2.120-192.0.2.199",
                "client-classes": [ "white" ]
             }

              // Note there are not pools available to anyone. This is
              // important to note. This means that to get an address, the
              // client needs to belong to red class, to white class or
              // have an address reserved.
          ]
        } ],

      // Set up the hook libraries.
      "hooks-libraries": [
         {
            // Load the flex-id hook library.
            "library": "libdhcp_flex_id.so",

            "parameters": {
                // Take the ID from the AOP option.
                "identifier-expression": "option[250].text",

                // Replace the client ID in queries by the flex-id.
                // Currently required by access code.
                // Required for accounting as it will become the lease ID too.
                "replace-client-id": true
            }
         },
         {
             // Load the host cache hook library. It is needed by the RADIUS
             // library to keep the attributes from authorization to later user
             // for accounting.
             "library": "libdhcp_host_cache.so"
         },
         {
             // Load the RADIUS hook library.
             "library": "libdhcp_radius.so",

             "parameters": {
                 // If do not use RFC 4361
                 // "extract-duid": false,

                 // If have conflicting subnets
                 // "reselect-subnet-pool": true,

                 // Strip the 0 type added by flex-id
                 "client-id-pop0": true,

                 // flex Id is printable (far easier for the RADIUS server config)
                 // Without this it will be in hexadecimal...
                 "client-id-printable": true,

                 // Use the flex-id.
                 "identifier-type4": "flex-id",

                 // Configure an access (aka authentication/authorization) server.
                 "access": {

                     // This starts the list of access servers
                     "servers": [
                         {
                             // These are parameters for the first (and only) access server
                             "name": "127.0.0.1",
                             "port": 1812,
                             "secret": "1234"
                         }
                         // Additional access servers could be specified here
                     ],

                     // This define a list of additional attributes Kea will send to each
                     // access server in Access-Request.
                     "attributes": [
                     {
                         // This attribute is identified by name (must be present in the
                         // dictionary) and has static value (i.e. the same value will be
                         // sent to every server for every packet)
                         "name": "Password",
                         "data": "mysecretpassword"
                     },
                     {
                         // It's also possible to specify an attribute using its type,
                         // rather than a name. 77 is Connect-Info. The value is specified
                         // using hex. Again, this is a static value. It will be sent the
                         // same for every packet and to every server.
                         "type": 77,
                         "raw": "65666a6a71"
                     },
                     {
                         // This example shows how an expression can be used to send dynamic
                         // value. The expression (see Section 13) may take any value from
                         // the incoming packet or even its metadata (e.g. the interface
                         // it was received over from)
                         "name": "Configuration-Token",
                         "expr": "pkt.iface"
                     }
                     ] // End of attributes
                  },

                 // Configure an accounting server.
                 "accounting": {
                     "servers": [ {
                             "name": "127.0.0.1",
                             "port": 1813,
                             "secret": "1234"
                         }
                    ]
                 }
             }
         }
         ]
    }

    }

.. _config-example-kea4-hooks-rbac-json:

--------------------
kea4/hooks-rbac.json
--------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv4 server in Kea using
    // the Role Based Access Control (RBAC) hook library. It uses a basic scenario
    // of one IPv4 subnet configured with the default values for all parameters.

    {"Dhcp4":

    {
    // Kea is told to listen on the eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // Set up the storage for leases.
      "lease-database": {
        "type": "memfile"
      },

      "valid-lifetime": 1800,

    // Define a single subnet.
      "subnet4": [
        {
          "pools": [ { "pool": "192.0.2.1 - 192.0.2.200" } ],
          "id": 1,
          "subnet": "192.0.2.0/24",
          "interface": "eth0"
        }
      ],

    // Control sockets.
      "control-sockets": [
        {
          "socket-type": "https",
          "socket-address": "127.0.0.1",
          "socket-port": 8000,
          "trust-anchor": "my-ca",
          "cert-file": "my-cert",
          "key-file": "my-key",
          "cert-required": true
        }
      ],

    // Add hooks here.
      "hooks-libraries": [
        {
          "library": "libdhcp_rbac.so",
          "parameters": {
              // This section configures the RBAC hook library.
              // Mandatory parameters.
              "assign-role-method": "cert-subject",
              "api-files": "/opt/share/kea/api",
              // Optional parameters.
              "require-tls": true,
              "commands": [
              {
                  "name": "my-command",
                  "access": "read",
                  "hook": "my-hook"
              } ],
              "access-control-lists": [
              {
                  "my-none": { "not": "ALL" }
              },{
                  "another-none": { "and": [ "ALL", "NONE" ] }
              },{
                  "my-read": { "access": "read" }
              } ],
              "roles": [
              {
                  "name": "kea-client",
                  "accept-commands":
                  {
                      "commands": [ "list-commands", "status-get" ]
                  },
                  "reject-commands": "NONE",
                  "other-commands": "reject",
                  "list-match-first": "accept",
                  "response-filters": [ "list-commands" ]
              },{
                  "name": "admin",
                  "accept-commands": "ALL",
                  "reject-commands":
                  {
                      "hook": "cb_cmds"
                  },
                  "list-match-first": "reject"
              } ],
              "default-role":
              {
                  "accept-commands": "NONE",
                  "reject-commands": "ALL"
              },
              "unknown-role":
              {
                  "accept-commands": "READ",
                  "reject-commands": "WRITE"
              }
          }
        }
      ]
    }

    }

.. _config-example-kea4-hooks-json:

---------------
kea4/hooks.json
---------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv4 server in Kea
    // illustrating the configuration of hook libraries.  It uses a basic scenario
    // of one IPv4 subnet configured with the default values for all parameters.

    {"Dhcp4":

    {
    // Kea is told to listen on the eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // Set up the storage for leases.
      "lease-database": {
        "type": "memfile"
      },

      "valid-lifetime": 1800,

    // Define a single subnet.
      "subnet4": [
        {
          "pools": [ { "pool": "192.0.2.1 - 192.0.2.200" } ],
          "id": 1,
          "subnet": "192.0.2.0/24",
          "interface": "eth0"
        }
      ],

    // Set up the hook libraries.  For this example, we assume that two libraries
    // are loaded, called "security" and "charging".  Note that order is important:
    // "security" is specified first so if both libraries supply a hook function
    // for a given hook, the function in "security" will be called before that in
    // "charging".

      "hooks-libraries": [
         {
            "library": "security.so"
         },
         {
             "library": "charging.so",
             "parameters": {
                 "path": "/var/log/kea",
                 "base-name": "kea-forensic6"
             }
         }
      ]
    }

    }

.. _config-example-kea4-leases-expiration-json:

---------------------------
kea4/leases-expiration.json
---------------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv4 server in Kea.
    // It provides parameters controlling processing of expired leases,
    // a.k.a. leases reclamation.

    { "Dhcp4":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // We need to specify the database used to store leases. As of
    // June 2022, three database backends are supported: MySQL,
    // PostgreSQL and the in-memory database, Memfile.
    // We'll use memfile because it doesn't require any prior set up.
    // Note, we're setting the maximum number of row read errors to 100,
    // (defaults to 0, meaning unlimited).
      "lease-database": {
          "type": "memfile",
          "lfc-interval": 3600,
          "max-row-errors": 100
      },

    // The following parameters control processing expired leases. Expired
    // leases will be reclaimed periodically according to the
    // "reclaim-timer-wait-time" parameter. Reclaimed leases will be held in
    // the database for 1800s to facilitate lease affinity. After this
    // period the leases will be removed.  The frequency of removal is
    // controlled by the "flush-reclaimed-timer-wait-time" parameter. The
    // lease reclamation routine will process at most 500 leases or will
    // last for at most 100ms, during a single run. If there are still some
    // unreclaimed leases after 10 attempts, a warning message is issued.
    // If both "flush-reclaimed-timer-wait-time" and "hold-reclaimed-time" are not
    // 0, when the client sends a release message the lease is expired instead of
    // being deleted from lease storage.
      "expired-leases-processing": {
        "reclaim-timer-wait-time": 5,
        "hold-reclaimed-time": 1800,
        "flush-reclaimed-timer-wait-time": 10,
        "max-reclaim-leases": 500,
        "max-reclaim-time": 100,
        "unwarned-reclaim-cycles": 10
      },

    // Addresses will be assigned with a lifetime of 4000 seconds.
      "valid-lifetime": 4000,

    // The following list defines subnets. We have only one subnet
    // here. We tell Kea that it is directly available over local interface.
      "subnet4": [
        {
           "pools": [ { "pool":  "192.0.2.1 - 192.0.2.200" } ],
           "id": 1,
           "subnet": "192.0.2.0/24",
           "interface": "eth0"
        }
      ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp4",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea4-multiple-options-json:

--------------------------
kea4/multiple-options.json
--------------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv4 server in Kea.
    // It demonstrates simple configuration of the options for a subnet.

    { "Dhcp4":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // We need to specify the database used to store leases. As of
    // June 2022, three database backends are supported: MySQL,
    // PostgreSQL and the in-memory database, Memfile.
    // We'll use memfile because it doesn't require any prior set up.
      "lease-database": {
        "type": "memfile"
      },

    // Addresses will be assigned with a lifetime of 4000 seconds.
      "valid-lifetime": 4000,

    // Renew and rebind timers are commented out. This implies that options
    // 58 and 59 will not be sent to the client. In this case it is up to
    // the client to pick the timer values according to RFC2131. Uncomment the
    // timers to send these options to the client.
    //  "renew-timer": 1000,
    //  "rebind-timer": 2000,

    // Defining a subnet. There are some DHCP options returned to the
    // clients connected to this subnet. The first and third options are
    // clients connected to this subnet. The first two options are
    // identified by the name. The third option is identified by the
    // option code.
    // There is an address pool defined within this subnet. Pool
    // specific value for option domain-name-servers is defined
    // for the pool.
      "subnet4": [
        {
           "id": 1,
           "subnet": "192.0.2.0/24",
           "option-data": [
                // When specifying options, you typically need to specify
                // one of (name or code) and data. The full option specification
                // covers name, code, space, csv-format and data.
                // space defaults to "dhcp4" which is usually correct, unless you
                // use encapsulate options. csv-format defaults to "true", so
                // this is also correct, unless you want to specify the whole
                // option value as long hex string. For example, to specify
                // domain-name-servers you could do this:
                // {
                //     "name": "domain-name-servers",
                //     "code": 6,
                //     "csv-format": true,
                //     "space": "dhcp4",
                //     "data": "192.0.2.1, 192.0.2.2"
                // }
                // but it's a lot of writing, so it's easier to do this instead:
             {
                 "name": "domain-name-servers",
                 "data": "192.0.2.1, 192.0.2.2"
             },
                // Note the Kea provides some of the options on its own. In
                // particular:

                // - IP address lease time (option 51) is governed by
                //   valid-lifetime parameter, so you don't need to specify
                //   it as option.
                // - Subnet mask (option 1) is calculated automatically from the
                //   subnet parameter specified for each "subnet4" entry.
                // - renewal-timer (option 58) is calculated from renew-timer
                //   parameter
                // - rebind timer (option 59) is calculated from rebind-timer
                //   parameter

                // For each IPv4 subnet you most likely need to specify at least
                // one router.
             {
                 "name": "routers",
                 "data": "192.0.2.1"
             },

                // Typically people prefer to refer to options by their
                // names, so they don't need to remember the code names.
                // However, some people like to use numerical values. For
                // example, option "domain-name" uses option code 15, so you
                // can reference to it either by
                // "name": "domain-name" or "code": 15.
             {
                 "code": 15,
                 "data": "example.org"
             },
                 // Domain search is also a popular option. It tells the client to
                 // attempt to resolve names within those specified domains. For
                 // example, name "foo" would be attempted to be resolved as
                 // foo.mydomain.example.com and if it fails, then as
                 // foo.example.com

             {
                 "name": "domain-search",
                 "data": "mydomain.example.com, example.com"
             },

               // Options can also be specified using hexadecimal format.
               // This should be avoided if possible, because Kea ability to
               // validate correctness is limited when using hex values.
             {
                 "name": "broadcast-address",
                 "csv-format": false,
                 "data": "ffff8000"
             },

                // String options that have a comma in their values need to have
                // it escaped (i.e. each comma is preceded by two backslashes).
                // That's because commas are reserved for separating fields in
                // compound options. At the same time, we need to be conformant
                // with JSON spec, that does not allow "\,". Therefore the
                // slightly uncommon double backslashes notation is needed.

                // Legal JSON escapes are \ followed by "\/bfnrt character
                // or \u followed by 4 hexa-decimal numbers (currently Kea
                // supports only \u0000 to \u00ff code points).
                // CSV processing translates '\\' into '\' and '\,' into ','
                // only so for instance '\x' is translated into '\x'. But
                // as it works on a JSON string value each of these '\'
                // characters must be doubled on JSON input.
             {
                "name": "boot-file-name",
                "data": "EST5EDT4\\,M3.2.0/02:00\\,M11.1.0/02:00"

             },
                // Options that take integer values can either be specified in
                // dec or hex format. Hex format could be either plain (e.g. abcd)
                // or prefixed with 0x (e.g. 0xabcd).
             {
                "name": "default-ip-ttl",
                "data": "0xf0"
             },
                // At a few exceptions options are added to response only when
                // the client requests them. The always-send flag should be used
                // to enforce a particular option.
             {
                "name": "vendor-class-identifier",
                "data": "isc",
                "always-send": true
             }
           ],

            // Now we define pools. There are two pools here.
            "pools": [ {
                // This is the first pool. Nothing spectacular here, just a range
                // of addresses.
               "pool": "192.0.2.10 - 192.0.2.100"

              }, {
                // This second pool is more interesting. Anyone who gets an
                // address from this pool will also get this specific option
                // value if asks for DNS servers configuration. This value,
                // being more specific, overrides any values that were specified
                // on either global or subnet scope.
                "pool":  "192.0.2.101 - 192.0.2.200",
                "option-data": [
                    {
                        "name": "domain-name-servers",
                        "data": "192.0.2.3, 192.0.2.4"
                    }
              ]
            } ]
        } ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp4",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea4-mysql-reservations-json:

----------------------------
kea4/mysql-reservations.json
----------------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv4 server in Kea.
    // It contains configuration of the MySQL host database backend, used
    // to retrieve reserved addresses, host names, DHCPv4 message fields
    // and DHCP options from MySQL database.
    { "Dhcp4":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]

      },

    // We need to specify the database used to store leases. As of
    // June 2022, three database backends are supported: MySQL,
    // PostgreSQL and the in-memory database, Memfile.
    // We'll use memfile because it doesn't require any prior set up.
      "lease-database": {
          "type": "memfile",
          "lfc-interval": 3600
      },

    // Addresses will be assigned with a lifetime of 4000 seconds.
      "valid-lifetime": 4000,

    // Renew and rebind timers are commented out. This implies that options
    // 58 and 59 will not be sent to the client. In this case it is up to
    // the client to pick the timer values according to RFC2131. Uncomment the
    // timers to send these options to the client.
    //  "renew-timer": 1000,
    //  "rebind-timer": 2000,


    // Kea supports reservations by several different types of
    // identifiers: hw-address (hardware/MAC address of the client), duid
    // (DUID inserted by the client), client-id (client identifier inserted
    // by the client) and circuit-id (circuit identifier inserted by the
    // relay agent). When told to do so, Kea can check for all of those
    // identifier types, but it takes a costly database lookup to do so. It
    // is therefore useful from a performance perspective to use only the
    // reservation types that are actually used in a given network.

    // The example below is not optimal from a performance perspective, but it
    // nicely showcases the host reservation capabilities. Please use the minimum
    // set of identifier types used in your network.
      "host-reservation-identifiers":
        [ "circuit-id", "hw-address", "duid", "client-id" ],

    // Specify connection to the database holding host reservations. The type
    // specifies that the MySQL database is used. user and password are the
    // credentials used to connect to the database. host and name specify
    // location of the host where the database instance is running, and the
    // name of the database to use. The server processing a packet will first
    // check if there are any reservations specified for this client in the
    // reservations list, within the subnet (configuration file). If there are
    // no reservations there, the server will try to retrieve reservations
    // from this database.
      "hosts-database": {
        "type": "mysql",
        "reconnect-wait-time": 3000, // expressed in ms
        "max-reconnect-tries": 3,
        "name": "keatest",
        "user": "keatest",
        "password": "1234",
        "host": "localhost",
        "port": 3306,
        "trust-anchor": "my-ca",
        "cert-file": "my-cert",
        "key-file": "my-key",
        "cipher-list": "AES"
      },
    // Since Kea.2.7.4, the libdhcp_mysql.so hook library must be loaded in order to
    // store host reservations in the MySQL Host Database Backend.
    // Specify the host backend hook library location.
      "hooks-libraries": [
        {
            // the MySQL host backend hook library required for host storage.
            "library": "libdhcp_mysql.so"
        }
      ],

    // Define a subnet with a single pool of dynamic addresses. Addresses from
    // this pool will be assigned to clients which don't have reservations in the
    // database. Subnet identifier is equal to 1. If this subnet is selected for
    // the client, this subnet id will be used to search for the reservations
    // within the database.
      "subnet4": [
        {
           "pools": [ { "pool":  "192.0.2.10 - 192.0.2.200" } ],
           "subnet": "192.0.2.0/24",
           "interface": "eth0",
           "id": 1
        }
      ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp4",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea4-pgsql-reservations-json:

----------------------------
kea4/pgsql-reservations.json
----------------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv4 server in Kea.
    // It contains configuration of the PostgreSQL host database backend, used
    // to retrieve reserved addresses, host names, DHCPv4 message fields
    // and DHCP options from PostgreSQL database.
    { "Dhcp4":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },


    // We need to specify the database used to store leases. As of
    // June 2022, three database backends are supported: MySQL,
    // PostgreSQL and the in-memory database, Memfile.
    // We'll use memfile because it doesn't require any prior set up.
      "lease-database": {
        "type": "memfile"
      },

    // Addresses will be assigned with a lifetime of 4000 seconds.
      "valid-lifetime": 4000,

    // Renew and rebind timers are commented out. This implies that options
    // 58 and 59 will not be sent to the client. In this case it is up to
    // the client to pick the timer values according to RFC2131. Uncomment the
    // timers to send these options to the client.
    //  "renew-timer": 1000,
    //  "rebind-timer": 2000,


    // Kea supports reservations by several different types of
    // identifiers: hw-address (hardware/MAC address of the client), duid
    // (DUID inserted by the client), client-id (client identifier inserted
    // by the client) and circuit-id (circuit identifier inserted by the
    // relay agent). When told to do so, Kea can check for all of those
    // identifier types, but it takes a costly database lookup to do so. It
    // is therefore useful from a performance perspective to use only the
    // reservation types that are actually used in a given network.

    // The example below is not optimal from a performance perspective, but it
    // nicely showcases the host reservation capabilities. Please use the minimum
    // set of identifier types used in your network.
      "host-reservation-identifiers":
        [ "circuit-id", "hw-address", "duid", "client-id" ],

    // Specify connection to the database holding host reservations. The type
    // specifies that the PostgreSQL database is used. user and password are the
    // credentials used to connect to the database. host and name specify
    // location of the host where the database instance is running, and the
    // name of the database to use. The server processing a packet will first
    // check if there are any reservations specified for this client in the
    // reservations list, within the subnet (configuration file). If there are
    // no reservations there, the server will try to retrieve reservations
    // from this database.
    // The database specification can go into one hosts-database entry for
    // backward compatibility or be listed in hosts-databases list.
      "hosts-databases": [
        {
           "type": "postgresql",
           "reconnect-wait-time": 3000, // expressed in ms
           "max-reconnect-tries": 3,
           "name": "keatest",
           "user": "keatest",
           "password": "1234",
           "host": "localhost"
        }
      ],
    // Since Kea.2.7.4, the libdhcp_pgsql.so hook library must be loaded in order to
    // store host reservations in the PostgreSQL Host Database Backend.
    // Specify the host backend hook library location.
      "hooks-libraries": [
        {
            // the PostgreSQL host backend hook library required for host storage.
            "library": "libdhcp_pgsql.so"
        }
      ],

    // Define a subnet with a single pool of dynamic addresses. Addresses from
    // this pool will be assigned to clients which don't have reservations in the
    // database. Subnet identifier is equal to 1. If this subnet is selected for
    // the client, this subnet id will be used to search for the reservations
    // within the database.
      "subnet4": [
        {
           "pools": [ { "pool":  "192.0.2.10 - 192.0.2.200" } ],
           "subnet": "192.0.2.0/24",
           "interface": "eth0",
           "id": 1
        }
      ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp4",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea4-reservations-json:

----------------------
kea4/reservations.json
----------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv4 server in Kea.
    // It contains one subnet in which there are two static address reservations
    // for the clients identified by the MAC addresses.
    { "Dhcp4":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // We need to specify the database used to store leases. As of April
    // 2022, three database backends are supported: MySQL, PostgreSQL, and the
    // in-memory database, Memfile.  We'll use memfile because it doesn't
    // require any prior set up.
      "lease-database": {
          "type": "memfile",
          "lfc-interval": 3600
      },

    // Addresses will be assigned with a lifetime of 4000 seconds.
      "valid-lifetime": 4000,

    // Renew and rebind timers are commented out. This implies that options
    // 58 and 59 will not be sent to the client. In this case it is up to
    // the client to pick the timer values according to RFC2131. Uncomment the
    // timers to send these options to the client.
    //  "renew-timer": 1000,
    //  "rebind-timer": 2000,

    // Kea supports reservations by several different types of identifiers:
    // hw-address (hardware/MAC address of the client), duid (DUID inserted by the
    // client), client-id (client identifier inserted by the client), circuit-id
    // (circuit identifier inserted by the relay agent) and flex-id (flexible
    // identifier available when flex_id hook library is loaded). When told to do
    // so, Kea can check for all of those identifier types, but it takes a costly
    // database lookup to do so. It is therefore useful from a performance
    // perspective to use only the reservation types that are actually used in a
    // given network.

    // The example below is not optimal from a performance perspective, but it
    // nicely showcases the host reservation capabilities. Please use the minimum
    // set of identifier types used in your network.
    "host-reservation-identifiers": [ "circuit-id", "hw-address", "duid",
                                      "client-id", "flex-id" ],

    // Define a subnet with four reservations. Some of the reservations belong
    // to the dynamic pool. Kea is able to handle this case, but it is not
    // recommended from a performance perspective, as Kea would not only need to
    // check if a given address is free, but also whether it is reserved.
    // To avoid this check, one can set "reservations-out-of-pool" to true, beside
    // the "reservations-in-subnet" which should be also set to true. If a subnet
    // does not have reservations at all, the reservation lookup can be skipped
    // altogether by setting "reservations-in-subnet" to false.

    // Note that the second reservation is for an address which is within the
    // range of the pool of the dynamically allocated address. The server will
    // exclude this address from this pool and only assign it to the client which
    // has a reservation for it.
      "subnet4": [
        {
            "pools": [ { "pool":  "192.0.2.1 - 192.0.2.200" } ],
            "id": 1,
            "subnet": "192.0.2.0/24",
            "interface": "eth0",
            // This directive tells Kea that reservations may be made both in-pool
            // and out-of-pool. For improved performance, you may move all reservations
            // out of the dynamic pool and set "reservations-out-of-pool" to true.
            // Kea will then be able to skip querying for host reservations when
            // assigning leases from dynamic pool.

            // Specify whether the server should look up global reservations.
            // Defaults to false.
            "reservations-global": false,

            // Specify whether the server should look up in-subnet reservations.
            // Defaults to true.
            "reservations-in-subnet": true,

            // Specify whether the server can assume that all reserved addresses
            // are out-of-pool. Defaults to false.
            // Ignored when reservations-in-subnet is false.
            // If specified, it is inherited by "shared-networks" and
            // "subnet4" levels.
            "reservations-out-of-pool": false,

            "reservations": [

    // This is a reservation for a specific hardware/MAC address. It's a very
    // simple reservation: just an address and nothing else.
            {
                "hw-address": "1a:1b:1c:1d:1e:1f",
                "ip-address": "192.0.2.201"
            },

    // This is a reservation for a specific client-id. It also shows
    // the this client will get a reserved hostname. A hostname can be defined
    // for any identifier type, not just client-id.
            {
                "client-id": "01:11:22:33:44:55:66",
                "ip-address": "192.0.2.202",
                "hostname": "special-snowflake"
            },

    // The third reservation is based on DUID. This reservation also
    // defines special option values for this particular client. If
    // the domain-name-servers option would have been defined on a global,
    // subnet or class level, the host specific values take preference.
            {
                "duid": "01:02:03:04:05",
                "ip-address": "192.0.2.203",
                "option-data": [ {
                    "name": "domain-name-servers",
                    "data": "10.1.1.202,10.1.1.203"
                } ]
            },

    // The fourth reservation is based on circuit-id. This is an option inserted
    // by the relay agent that forwards the packet from client to the server.
    // In this example the host is also assigned vendor specific options.
            {
                "circuit-id": "01:11:22:33:44:55:66",
                "ip-address": "192.0.2.204",
                "option-data": [
                    {
                        "name": "vivso-suboptions",
                        "data": "4491"
                    },
                    {
                        "name": "tftp-servers",
                        "space": "vendor-4491",
                        "data": "10.1.1.202,10.1.1.203"
                    }
                ]
            },
    // This reservation is for a client that needs specific DHCPv4 fields to be
    // set. Three supported fields are next-server, server-hostname and
    // boot-file-name
            {
                "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"
            },

    // This reservation is using flexible identifier. Instead of relying
    // on specific field, sysadmin can define an expression similar to what
    // is used for client classification,
    // e.g. substring(relay[0].option[17],0,6). Then, based on the value of
    // that expression for incoming packet, the reservation is matched.
    // Expression can be specified either as hex or plain text using single
    // quotes.
    // Note: flexible identifier requires flex_id hook library to be
    // loaded to work.
            {
                "flex-id": "'s0mEVaLue'",
                "ip-address": "192.0.2.206"
            }

          ]
        }
      ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp4",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea4-several-subnets-json:

-------------------------
kea4/several-subnets.json
-------------------------

.. code-block::
    :linenos:

    // This is an example configuration file for DHCPv4 server in Kea.
    // It's a basic scenario with three IPv4 subnets configured. In each
    // subnet, there's a smaller pool of dynamic addresses.

    { "Dhcp4":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // We need to specify the database used to store leases. As of
    // June 2022, three database backends are supported: MySQL,
    // PostgreSQL and the in-memory database, Memfile.
    // We'll use memfile because it doesn't require any prior set up.
      "lease-database": {
        "type": "memfile"
      },

    // Addresses will be assigned with a lifetime of 4000 seconds.
    // The client is told to start renewing after 1000 seconds. If the server
    // does not respond within 2000 seconds of the lease being granted, client
    // is supposed to start REBIND procedure (emergency renewal that allows
    // switching to a different server).
      "valid-lifetime": 4000,
      "renew-timer": 1000,
      "rebind-timer": 2000,

    // RFC6842 says that the server is supposed to echo back client-id option.
    // However, some older clients do not support this and are getting confused
    // when they get their own client-id. Kea can disable RFC6842 support.
      "echo-client-id": false,

    // Some clients don't use stable client identifier, but rather generate them
    // during each boot. This may cause a client that reboots frequently to get
    // multiple leases, which may not be desirable. As such, sometimes admins
    // prefer to tell their DHCPv4 server to ignore client-id value altogether
    // and rely exclusively on MAC address. This is a parameter that is defined
    // globally, but can be overridden on a subnet level.
      "match-client-id": true,

      // By default, Kea ignores requests by clients for unknown IP addresses,
      // because other non-cooperating DHCP servers could reside on the same
      // network (RFC 2131). This parameter is defined globally, but can be
      // overridden on a subnet level
      "authoritative": false,

    // The following list defines subnets. Each subnet consists of at
    // least subnet and pool entries.
      "subnet4": [
      {
          "pools": [ { "pool":  "192.0.2.1 - 192.0.2.200" } ],
          "id": 1,
          "subnet": "192.0.2.0/24"
      },
      {
    // This particular subnet has match-client-id value changed.
          "pools": [ { "pool": "192.0.3.100 - 192.0.3.200" } ],
          "id": 2,
          "subnet": "192.0.3.0/24",
          "match-client-id": false
      },
      {
          "pools": [ { "pool": "192.0.4.1 - 192.0.4.254" } ],
          "id": 3,
          "subnet": "192.0.4.0/24"
      } ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp4",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea4-shared-network-json:

------------------------
kea4/shared-network.json
------------------------

.. code-block::
    :linenos:

    // This is an example configuration file for DHCPv4 server in Kea.
    // It demonstrates an advanced feature called shared network. Typically, for
    // each physical link there is one IPv4 subnet that the server is expected
    // to manage. However, in some cases there is a need to configure more subnets
    // in the same physical location. The most common use case is an existing
    // subnet that grew past its original assumptions and ran out of addresses,
    // so the sysadmin needs to add another subnet on top of existing one.
    {
        "Dhcp4": {

            // As with any other configuration, you need to tell Kea the interface
            // names, so it would listen to incoming traffic.
            "interfaces-config": {
                "interfaces": [ "eth0" ]
            },

            // You also need to tell where to store lease information.
            // memfile is the backend that is easiest to set up.
            "lease-database": {
                "type": "memfile",
                "lfc-interval": 3600
            },

            // The shared networks definition starts here. shared-networks can
            // contain a list of shared networks. There are many parameters
            // that can be specified here, so this example may be overwhelming
            // at first, but the only mandatory parameter for each shared
            // network is name. It must be unique. Typically, each shared
            // network also needs to have at least two subnets to be functional,
            // but if you really want to, you can define a degraded shared
            // network that has 1 or even 0 subnets. This may come in handy
            // when migrating between regular subnets and shared networks
            // or when debugging a problem. It is not recommended to use
            // 1 subnet per shared network, as there is extra processing
            // overhead for shared networks.
            "shared-networks": [
            {
                // Name of the shared network. It may be an arbitrary string
                // and it must be unique among all shared networks.
                "name": "frog",

                // You may specify interface name if the shared network is
                // reachable directly from the server.
                "interface": "eth1",

                // You can specify many parameters that are allowed in subnet scope
                // here. It's useful to put them here if they apply to all subnets
                // in this shared network. It's likely that the most common
                // parameter here will be option values defined with option-data.
                "match-client-id": false,
                "option-data": [ ],
                "rebind-timer": 150,
                "authoritative": true,

                // If all the traffic coming from that shared network is reachable
                // via relay and that relay always use the same IP address, you
                // can specify that relay address here. Since this example shows
                // a shared network reachable directly, we put 0.0.0.0 here.
                // It would be better to skip the relay scope altogether, but
                // it was left here for demonstration purposes.
                "relay": {
                    "ip-addresses": [ "0.0.0.0" ]
                },

                // Timer values can be overridden here.
                "renew-timer": 100,

                // Specify whether the server should look up global reservations.
                "reservations-global": false,

                // Specify whether the server should look up in-subnet reservations.
                "reservations-in-subnet": true,

                // Specify whether the server can assume that all reserved addresses
                // are out-of-pool.
                // Ignored when reservations-in-subnet is false.
                // If specified, it is inherited by "subnet4" levels.
                "reservations-out-of-pool": false,

                // This starts a list of subnets allowed in this shared network.
                // In our example, there are two subnets.
                "subnet4": [
                    {
                        "id": 1,
                        "match-client-id": true,
                        "next-server": "0.0.0.0",
                        "server-hostname": "",
                        "boot-file-name": "",
                        "option-data": [ ],
                        "pools": [ ],
                        "rebind-timer": 20,

                        // You can override the value inherited from shared-network
                        // here if your relay uses different IP addresses for
                        // each subnet.
                        "relay": {
                            "ip-addresses": [ "0.0.0.0" ]
                        },
                        "renew-timer": 10,
                        // Specify whether the server should look up global reservations.
                        "reservations-global": false,
                        // Specify whether the server should look up in-subnet reservations.
                        "reservations-in-subnet": true,
                        // Specify whether the server can assume that all reserved addresses
                        // are out-of-pool.
                        // Ignored when reservations-in-subnet is false.
                        "reservations-out-of-pool": false,
                        "subnet": "10.0.0.0/8",
                        "valid-lifetime": 30
                    },
                    {
                        "id": 2,
                        "match-client-id": true,
                        "next-server": "0.0.0.0",
                        "server-hostname": "",
                        "boot-file-name": "",
                        "option-data": [ ],
                        "pools": [ ],
                        "rebind-timer": 20,
                        "renew-timer": 10,
                        // Specify whether the server should look up global reservations.
                        "reservations-global": false,
                        // Specify whether the server should look up in-subnet reservations.
                        "reservations-in-subnet": true,
                        // Specify whether the server can assume that all reserved addresses
                        // are out-of-pool.
                        // Ignored when reservations-in-subnet is false.
                        "reservations-out-of-pool": false,
                        "subnet": "192.0.2.0/24",
                        "valid-lifetime": 30
                    }
                ],
                "valid-lifetime": 200
            } ], // end of shared-networks

            // It is likely that in your network you'll have a mix of regular,
            // "plain" subnets and shared networks. It is perfectly valid to mix
            // them in the same config file.

            // This is regular subnet. It's not part of any shared-network.
            "subnet4": [
                {
                    "pools": [ { "pool":  "192.0.3.1 - 192.0.3.200" } ],
                    "subnet": "192.0.3.0/24",
                    "interface": "eth0",
                    "id": 3
                }
            ]

        } // end of Dhcp4
    }

.. _config-example-kea4-single-subnet-json:

-----------------------
kea4/single-subnet.json
-----------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv4 server in Kea.
    // It is a basic scenario with one IPv4 subnet configured. The subnet
    // contains a single pool of dynamically allocated addresses.

    { "Dhcp4":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // We need to specify the database used to store leases. As of
    // June 2022, three database backends are supported: MySQL,
    // PostgreSQL and the in-memory database, Memfile.
    // We'll use memfile because it doesn't require any prior set up.
      "lease-database": {
          "type": "memfile",
          "lfc-interval": 3600
      },

    // Addresses will be assigned with a lifetime of 4000 seconds.
      "valid-lifetime": 4000,

    // Renew and rebind timers are commented out. This implies that options
    // 58 and 59 will not be sent to the client. In this case it is up to
    // the client to pick the timer values according to RFC2131. Uncomment the
    // timers to send these options to the client.
    //  "renew-timer": 1000,
    //  "rebind-timer": 2000,

    // The following list defines subnets. We have only one subnet
    // here. We tell Kea that it is directly available over local interface.
      "subnet4": [
        {
           "pools": [ { "pool":  "192.0.2.1 - 192.0.2.200" } ],
           "id": 1,
           "subnet": "192.0.2.0/24",
           "interface": "eth0"
        }
      ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout. Alternatively, you can specify stderr here, a filename
    // or 'syslog', which will store output messages via syslog.
        "loggers": [
            {
                "name": "kea-dhcp4",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea4-vendor-specific-json:

-------------------------
kea4/vendor-specific.json
-------------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv4 server in Kea.
    // The purpose of this example is to showcase how configure
    // Vendor Specific Information (code 43) RFC 2132 section 8.4
    {
        "Dhcp4": {
            "option-def": [
                {
    // Two options that we are planning to include in option 43 as suboptions
    // should be defined on global level
                    "array": false,
                    "code": 2,
                    "name": "vlanid",
    // suboptions should have space configured and it can't start with 'vendor-'
    // otherwise those will be included in 125 option not 43
                    "space": "339",
                    "type": "uint32"
                },
                {
                    "array": false,
                    "code": 3,
                    "name": "dls",
                    "space": "339",
                    "type": "string"
                }
            ],
            "client-classes": [
                {

    // Kea needs classification based on option 60, you can either use name:
    // VENDOR_CLASS_ + option 60 content (test parameter is not required than)
    // or use any name and add "test" parameter accordingly e.g.
    // "test": "substring(option[60].hex,0,9) == 'partial-content-of-option-60'"
                    "name": "VENDOR_CLASS_339",
                    "option-def": [
                        {
    // Vendor-specific option has to be defined on the class level, if we're planning
    // to send a single value, then define its type accordingly. If this option
    // should encapsulate other suboptions, the "space" parameter should be the same
    // as included suboptions and "type" set to empty
                            "code": 43,
    // Using the "encapsulate" direction, Kea is told to include options from
    // the "339" namespace. We have defined several such options earlier.
    // This way, the sub-options are "glued" to this option 43.
                            "encapsulate": "339",
                            "name": "vendor-encapsulated-options",
                            "type": "empty"
                        }
                    ],
                    "option-data": [
                        {
    // vendor-encapsulated-options and defined option on global level should
    // be also configured with proper "data" parameters in "option-data" list.
    // Because Kea will send only option that client ask for, and there is no way
    // to ask for suboptions, parameter "always-send" with value set
    // to true has also be included in all custom suboptions
                            "name": "vendor-encapsulated-options"
                        },
                        {
                            "always-send": true,
                            "data": "123",
                            "name": "vlanid",
                            "space": "339"
                        },
                        {
                            "always-send": true,
                            "data": "sdlp://192.0.2.11:18443",
                            "name": "dls",
                            "space": "339"
                        }
                    ]
                }
            ],
    // Kea is told to listen on eth0 interface only.
            "interfaces-config": {
                "interfaces": ["eth0"]
            },
    // We need to specify the database used to store leases.
            "lease-database": {
                "type": "memfile"
            },
    // The following list defines subnets. We have only one subnet
    // here. We tell Kea that it is directly available over local interface.
            "subnet4": [
                {
                    "interface": "eth0",
                    "pools": [
                        {
                            "pool": "192.0.2.50-192.0.2.50"
                        }
                    ],
                    "subnet": "192.0.2.0/24",
                    "id": 1
                }
            ]
        }
    }

.. _config-example-kea4-vivso-json:

---------------
kea4/vivso.json
---------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv4 server in Kea.
    // The purpose of this example is to showcase how configure
    // Vendor-Identifying Vendor-specific Information option
    // (code 125) RFC 3925


    {
        "Dhcp4": {
    // If we want to send suboptions in option 125 first those have to be defined
    // on global level
            "option-def": [
                {
                    "array": false,
                    "code": 2,
                    "name": "vlanid",
    // In case of suboption of option 125 space has to start with prefix "vendor-"
    // in this case it's "vendor-" + vendor id from option 60 sent by client
    // 339 is Siemens Industry Inc.
                    "space": "vendor-339",
                    "type": "uint32"
                },
                {
                    "array": false,
                    "code": 3,
                    "name": "dls",
                    "space": "vendor-339",
                    "type": "string"
                }
            ],
            "client-classes": [
                {
    // Kea needs classification based on option 60, you can either use name:
    // VENDOR_CLASS_ + option 60 content (test parameter is not required than)
    // or use any name and add "test" parameter accordingly e.g.
    // "test": "substring(option[60].hex,0,9) == 'partial-content-of-option-60'"
                    "name": "VENDOR_CLASS_339",
                    "option-data": [
                        {
    // In "option-data" list we have to configure option 125 with data parameter equal
    // to vendor-id we are expecting, also it will tell Kea which vendor space
    // encapsulate in suboptions.
                            "data": "339",
                            "name": "vivso-suboptions"
                        },
                        {
    // And additionally we have to configure all previously defined suboptions
    // with "space" parameter same as in option-def.
    // Because Kea will send only option that client ask for, and there is no way
    // to ask for suboptions parameter "always-send" with value set
    // to true has also be included in all custom suboptions.
                            "always-send": true,
                            "data": "123",
                            "name": "vlanid",
                            "space": "vendor-339"
                        },
                        {
                            "always-send": true,
                            "data": "sdlp://192.0.2.11:18443",
                            "name": "dls",
                            "space": "vendor-339"
                        }
                    ]
                }
            ],
    // Kea is told to listen on eth0 interface only.
            "interfaces-config": {
                "interfaces": [
                    "eth0"
                ]
            },
    // We need to specify the database used to store leases.
            "lease-database": {
                "type": "memfile"
            },
    // The following list defines subnets. We have only one subnet
    // here. We tell Kea that it is directly available over local interface.
            "subnet4": [
                {
                    "id": 1,
                    "interface": "eth0",
                    "pools": [
                        {
                            "pool": "192.0.2.50-192.0.2.50"
                        }
                    ],
                    "subnet": "192.0.2.0/24"
                }
            ]
        }
    }

.. _config-example-kea4-with-ddns-json:

-------------------
kea4/with-ddns.json
-------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv4 server in Kea.
    // It is a basic scenario with one IPv4 subnet configured and with DDNS
    // enabled.

    { "Dhcp4":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // We need to specify the database used to store leases. As of
    // June 2022, three database backends are supported: MySQL,
    // PostgreSQL and the in-memory database, Memfile.
    // We'll use memfile because it doesn't require any prior set up.
      "lease-database": {
          "type": "memfile",
          "lfc-interval": 3600
      },

    // Addresses will be assigned with a lifetime of 4000 seconds.
      "valid-lifetime": 4000,

    // Renew and rebind timers are commented out. This implies that options
    // 58 and 59 will not be sent to the client. In this case it is up to
    // the client to pick the timer values according to RFC2131. Uncomment the
    // timers to send these options to the client.
    //  "renew-timer": 1000,
    //  "rebind-timer": 2000,

    // The following list defines subnets. We have only one subnet
    // here. We tell Kea that it is directly available over local interface.
      "subnet4": [
        {
           "pools": [ { "pool":  "192.0.2.1 - 192.0.2.200" } ],
           "subnet": "192.0.2.0/24",
           "interface": "eth0",
           "id": 1
        }
      ],

    // Enable connectivity with kea-dhcp-ddns
    // (Required for dynamic DNS updates)
      "dhcp-ddns" : {
            "enable-updates" : true,
            "server-ip" : "192.0.2.0",
            "server-port" : 3432,
            "sender-ip" : "192.0.2.1",
            "sender-port" : 3433,
            "max-queue-size" : 2048,
            "ncr-protocol" : "UDP",
            "ncr-format" : "JSON"
       },

    // Enable DDNS updates and configure DDNS update behavior
      "ddns-send-updates" : true,
      "ddns-override-no-update" : true,
      "ddns-override-client-update" : true,
      "ddns-replace-client-name" : "when-present",
      "ddns-generated-prefix" : "test.prefix",
      "ddns-qualifying-suffix" : "test.suffix.",
      "ddns-update-on-renew" : false,
      "ddns-conflict-resolution-mode": "check-with-dhcid",
      "ddns-ttl-percent" : 0.75,
      "hostname-char-set": "[^A-Za-z0-9.-]",
      "hostname-char-replacement": "x",

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp4",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea6:

====
kea6
====

.. _config-example-kea6-advanced-json:

------------------
kea6/advanced.json
------------------

.. code-block::
    :linenos:

    // This is an example configuration file for DHCPv6 server in Kea.
    // It attempts to showcase some of the more advanced features.
    // Topology wise, it's a basic scenario with one IPv6 subnet configured.
    // It is assumed that one subnet (2001:db8:1::/64) is available directly
    // over eth0 interface.
    //
    // The following features are currently showcased here:
    // 1. Configuration of MAC/hardware address sources in DHCPv6
    // 2. RSOO (Relay supplied options) - Some relays may insert options with the
    //    intention for the server to insert them into client directed messages.
    // 3. Control socket. Kea can open a socket and listen for incoming
    //    commands.

    { "Dhcp6":

    {
        // Kea is told to listen on eth0 network interface only.
        "interfaces-config": {
            "interfaces": [ "eth0" ],

            // This makes interfaces to be re-detected at each (re-)configuration.
            // By default it is true.
            "re-detect": true
        },

        // We need to specify the database used to store leases. As of
        // June 2022, three database backends are supported: MySQL,
        // PostgreSQL and the in-memory database, Memfile.
        // We will use memfile because it doesn't require any prior set up.
        "lease-database": {
            "type": "memfile",
            "lfc-interval": 3600
        },

         "sanity-checks": {
            // This parameter determines what to do when a new lease appears in the
            // system (i.e. either is read from disk during memfile startup or is
            // added via lease commands). There are five modes supported:
            // none - do nothing, accept them as is
            // warn - if subnet-id problems are detected, print a warning, but
            //        otherwise load the lease as is. This is the default value.
            // fix - attempt to fix the lease by finding appropriate subnet-id value.
            //       if there is no suitable subnet, the lease is loaded as is.
            // fix-del - attempt to fix the lease by finding appropriate subnet-id
            //           value. If there is no suitable subnet, the lease is deleted.
            // del - delete leases that have incorrect subnet-id values.
            "lease-checks": "fix-del"
        },

        // Kea 0.9.1 introduced MAC/hardware addresses support in DHCPv6. There is
        // no single reliable method of getting MAC address information in DHCPv6.
        // Kea supports several methods. Depending on your network set up, some
        // methods may be more preferable than others, hence the configuration
        // parameter. 'mac-sources' is a list of methods. Allowed parameters are:
        // any, raw, duid, ipv6-link-local, client-link-addr-option, rfc6939 (which
        // is an alias for client-link-addr-option), remote-id, rfc4649 (which is an
        // alias for remote-id, subscriber-id, rfc4580 (which is an alias for
        // subscriber-id) and docsis.

        // Note that the order matters. Methods are attempted one by one in the
        // order specified until hardware address is obtained. If you don't care
        // which method is used, using 'any' is marginally faster than enumerating
        // them all.

        // If mac-sources are not specified, a default value of 'any' is used.
        "mac-sources": [ "client-link-addr-option", "duid", "ipv6-link-local" ],

        // RFC6422 defines a mechanism called relay-supplied options option. The
        // relay agent may insert certain options that the server will echo back to
        // the client, if certain criteria are met. One condition is that the option
        // must be RSOO-enabled (i.e. allowed to be echoed back). IANA maintains a
        // list of those options here:
        // http://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#options-relay-supplied
        // However, it is possible to allow the server to echo back additional
        // options.  This entry marks options 110, 120 and 130 as RSOO-enabled.
        "relay-supplied-options": [ "110", "120", "130" ],

        // This defines a control socket. If defined, Kea will open a UNIX socket
        // and will listen for incoming commands. See section 15 of the Kea User's
        // Guide for list of supported commands.
        "control-socket": {
            "socket-type": "unix",
            "socket-name": "kea6-ctrl-socket"
        },

        // Addresses will be assigned with preferred and valid lifetimes
        // being 3000 and 4000, respectively. Client is told to start
        // renewing after 1000 seconds. If the server does not respond
        // after 2000 seconds since the lease was granted, client is supposed
        // to start REBIND procedure (emergency renewal that allows switching
        // to a different server).
        "preferred-lifetime": 3000,
        "valid-lifetime": 4000,
        "renew-timer": 1000,
        "rebind-timer": 2000,

        // The following list defines subnets. Each subnet consists of at
        // least subnet and pool entries. Note the user-context being
        // used throughout the definitions. This is something that is not
        // being used by Kea, it's simply parsed and stored in appropriate
        // structures. You can put anything you want in the user-context
        // as long as it is a valid JSON and it starts with a map (i.e.
        // is enclosed by curly brackets).
        // A comment entry is translated into a user-context with a
        // "comment" property so you can include comments inside the
        // configuration itself.
        "subnet6": [
        {
            "pools": [
                {
                    "pool": "2001:db8:1::/80",

                    // This is user context specified for this particular
                    // pool. You can use it to describe the pool in some way.
                    // Just keep in mind that the structure will not be used
                    // by Kea itself. It will be made available to hooks if
                    // they want to use it.
                    "user-context": { "department": "engineering" }
                }],

            // Here's the user-context for the whole subnet.
            "user-context": { "comment": "Floor one, west wing" },
            // Equivalent using smart parser
            // "comment": "Floor one, west wing",

            // This defines PD (prefix delegation) pools. In this case
            // we have only one pool. That consists of /64 prefixes
            // being delegated out of large /48 pool. Each delegated
            // prefix will contain an excluded-prefix option.
            "pd-pools": [
            {
                "prefix": "2001:db8:abcd::",
                "prefix-len": 48,
                "delegated-len": 64,
                "excluded-prefix": "2001:db8:abcd:0:1234::",
                "excluded-prefix-len": 80,

                // Another user-context for this PD pool. Again, you can put
                // anything you want in there as long as it's valid JSON and
                // starts with a map.
                "user-context": {
                    "purpose": "For CPE devices"
                }
            }
            ], // end of pools

            "id": 1,
            "subnet": "2001:db8:1::/64",
            "interface": "eth0",

            // Sometimes the relay may use an odd IPv6 address that's not matching
            // the subnet. This is discouraged, but there are valid cases when it
            // makes sense. One case is when the relay has only link-local address
            // and another is when there is a shared subnet scenario.
            "relay": {
                "ip-addresses": [ "3000::1" ]
            }
        }
        ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp6",
                "output-options": [
                    {
                        "output": "stdout",
                        // Several additional parameters are possible in addition
                        // to the typical output. Flush determines whether logger
                        // flushes output to a file. Maxsize determines maximum
                        // filesize before the file is rotated. maxver
                        // specifies the maximum number of rotated files being
                        // kept.
                        "flush": true,
                        "maxsize": 204800,
                        "maxver": 4,
                        // We use pattern to specify custom log message layout
                        "pattern": "%d{%y.%m.%d %H:%M:%S.%q} %-5p [%c/%i] %m\n"
                    }
                ],
                "debuglevel": 0,
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea6-all-keys-netconf-json:

--------------------------
kea6/all-keys-netconf.json
--------------------------

.. code-block::
    :linenos:

    // WARNING: This example configuration is not meant for production use.
    // The Kea DHCPv6 server will refuse this configuration because it contains
    // mutually exclusive configuration parameters.
    //
    // The primary purpose of the example file is to provide a comprehensive
    // list of parameters supported by the Kea DHCPv6 server along with the brief
    // description of each parameter.
    //
    // This stable version is used for YANG, as we do not want to update code
    // and models each time a keyword is added to the syntax.
    {
        // Kea DHCPv6 server configuration begins here.
        "Dhcp6": {
            // Global flag selecting an IP address allocation strategy for all
            // subnets.
            "allocator": "iterative",

            // Global flag that enables or disables client address registration
            // via ADDR-REG-INFORM packets (see RFC 9686). It defaults to true.
            "allow-address-registration": true,

            // Global flag selecting a delegated prefix allocation strategy
            // for all subnets.
            "pd-allocator": "random",

            // Ordered list of client classes used by the DHCPv6 server.
            "client-classes": [
                {
                    // Class name.
                    "name": "phones_server1",

                    // Class-specific DHCPv6 options list.
                    "option-data": [],

                    // Class selection expression. The DHCP packet is assigned to this
                    // class when the given expression evaluates to true.
                    "test": "member('HA_server1')",

                    // Class valid lifetime.
                    "valid-lifetime": 6000,

                    // Class min valid lifetime.
                    "min-valid-lifetime": 4000,

                    // Class max valid lifetime.
                    "max-valid-lifetime": 8000,

                    // Class preferred lifetime.
                    "preferred-lifetime": 7000,

                    // Class min preferred lifetime.
                    "min-preferred-lifetime": 5000,

                    // Class max preferred lifetime.
                    "max-preferred-lifetime": 9000
                },
                {
                    // Second class name.
                    "name": "phones_server2",

                    // Class-specific DHCPv6 options list.
                    "option-data": [],

                    // Class selection expression. The DHCP packet is assigned to this
                    // class when the given expression evaluates to true.
                    "test": "member('HA_server2')"
                },
                {
                    // Third class name.
                    "name": "late",

                    // Boolean flag indicating whether the class expression is only evaluated
                    // when the class is required, e.g. the selected address pool configuration
                    // includes this class name in its "evaluate-additional-classes" list. The
                    // default value false means that the class test expression must
                    // always be evaluated.
                    "only-in-additional-list": true,

                    // Class selection expression.
                    "test": "member('ALL')"
                },
                {
                    // Fourth class name.
                    "name": "my-template-class",

                    // Template class flag that holds the expression used to generate the names for all
                    // the spawned subclasses. In this case, the classes are named after the client ID.
                    "template-test": "substring(option[1].hex, 0, all)"
                }
            ],

            // Parameters for triggering behaviors compatible with broken or
            // non-compliant clients, relays, or other agents
            "compatibility": {
                // Parse options more leniently where fields can be deduced
                // deterministically, even if against RFC or common practice.
                "lenient-option-parsing": true
            },

            // Command control socket configuration parameters for the Kea DHCPv6 server.
            "control-sockets": [
                {
                    // Control socket type used by the Kea DHCPv6 server.
                    // Must be unix, http or https.
                    "socket-type": "unix",

                   // Location of the UNIX domain socket file the DHCPv6
                   // server uses to receive control commands from the
                   // local server administrator.
                   "socket-name": "kea6-ctrl-socket"
                },
                {
                    // Control socket type used by the Kea DHCPv6 server.
                    // Must be unix, http or https.
                    "socket-type": "https",

                    // Address of the HTTPS socket the Kea DHCPv6 server should
                    // listen for incoming queries.
                    "socket-address": "::1",

                    // Port of the HTTPS socket the Kea DHCPv6 server
                    // should listen for incoming queries. If enabling HA
                    // and multi-threading, the 8000 port is used by the
                    // HA hook library http listener. When using HA hook
                    // library with multi-threading to function, make sure
                    // the port used by dedicated listener is different
                    // (e.g. 8001) than the one specified here.  Note the
                    // commands should still be sent to a control socket.
                    // The dedicated listener is specifically for HA
                    // updates only.
                    "socket-port": 8006,

                    // TLS trust anchor (Certificate Authority). This is a
                    // file name or a directory path. Make sense with other
                    // TLS parameters only for the https control socket type.
                    "trust-anchor": "my-ca",

                    // TLS server certificate file name.
                    "cert-file": "my-cert",

                    // TLS server private key file name.
                    "key-file": "my-key",

                    // TLS require client certificates flag. Default is
                    // true and means require client certificates. False
                    // means they are optional.
                    "cert-required": true,

                    // Extra HTTP headers to add in responses.
                    "http-headers":
                    [
                        {
                            // Optional user context.
                            "user-context": { "comment": "HSTS header" },

                            // Required HTTP header name.
                            "name": "Strict-Transport-Security",

                            // Required HTTP header value.
                            "value": "max-age=31536000"
                        }
                    ],

                    // Optional authentication.
                    "authentication": {

                        // Required authentication type. The only
                        // supported value is basic for the basic HTTP
                        // authentication.
                        "type": "basic",

                        // An optional parameter is the basic HTTP
                        // authentication realm.  Its default is
                        // "kea-dhcpv6-server"
                        "realm": "kea-dhcpv6-server",

                        // This optional parameter can be used to specify a common
                        // prefix for files handling client credentials.
                        "directory": "/usr/local/share/kea/kea-creds",

                        // This list specifies the user ids and passwords
                        // to use for basic HTTP authentication. If empty
                        // or not present any client is authorized.
                        "clients": [
                            // This specifies an authorized client.
                            {
                                // The user id must not be empty or
                                // contain the ':' character. It is a
                                // mandatory parameter.
                                "user": "admin",

                                // If password is not specified an empty
                                // password is used.
                                "password": "1234"
                            },

                            // This specifies a hidden client.
                            {
                                // The user id is the content of the
                                // file /usr/local/share/kea/kea-creds/hiddenu.
                                "user-file": "hiddenu",

                                // The password is the content of the
                                // file /usr/local/share/kea/kea-creds/hiddenp.
                                "password-file": "hiddenp"
                            },

                            // This specifies a hidden client using a
                            // secret in a file.
                            {
                                // The secret is the content of the file
                                // /usr/local/share/kea/kea-creds/hiddens which must be in
                                // the <user-id>:<password> format.
                                "password-file": "hiddens"
                            }
                        ]
                    }
                }
            ],

            // Specifies a prefix to be prepended to the generated Client FQDN.
            // It may be specified at the global, shared-network, and subnet levels.
            "ddns-generated-prefix": "myhost",

            // Boolean flag indicating whether the server should ignore DHCP client
            // wishes to update DNS on its own. With that flag set to true,
            // the server will send DNS updates for both forward and
            // reverse DNS data. The default value is false, which indicates
            // that the server will delegate a DNS update to the client when
            // requested. It may be specified at the global, shared-network,
            // and subnet levels.
            "ddns-override-client-update": false,

            // Boolean flag indicating whether the server should override the DHCP
            // client's wish to not update the DNS. With this parameter
            // set to true, the server will send a DNS update even when
            // the client requested no update. It may be specified at the
            // global, shared-network, and subnet levels.
            "ddns-override-no-update": false,

            // Suffix appended to the partial name sent to the DNS. The
            // default value is an empty string, which indicates that no
            // suffix is appended. It may be specified at the global,
            // shared-network, and subnet levels.
            "ddns-qualifying-suffix": "",

            // Enumeration specifying whether the server should honor
            // the hostname or Client FQDN sent by the client or replace
            // this name. The acceptable values are: "never" (use the
            // name the client sent), "always" (replace the name the
            // client sent), "when-present" (replace the name the client
            // sent, but do not generate one when the client didn't send
            // the name), "when-not-present" (generate the name when
            // client didn't send one, otherwise leave the name the
            // client sent). The default value is "never". It may be
            // specified at the global, shared-network, and subnet levels.
            "ddns-replace-client-name": "never",

            // Boolean flag which enables or disables DDNS updating. It
            // defaults to true. It may be specified at the global, shared-
            // network, and subnet levels. It works in conjunction with
            // dhcp-ddns:enable-updates, which must be true to enable connectivity
            // to kea-dhcp-ddns.
            "ddns-send-updates": true,

            // Boolean flag, which when true instructs the server to always
            // update DNS when leases are renewed, even if the DNS information
            // has not changed. The server's default behavior (i.e. flag is false)
            // is to only update DNS if the DNS information has changed. It
            // may be specified at the global, shared-network, and subnet levels.
            "ddns-update-on-renew": true,

            // Boolean flag which is passed to kea-dhcp-ddns with each DDNS
            // update request, to indicate whether DNS update conflict
            // resolution as described in RFC 4703 should be employed for the
            // given update request. The default value for this flag is true.
            // It may be specified at the global, shared-network, and subnet levels.
            // This field has been replaced by ddns-conflict-resolution-mode.
            // Parsing is maintained only for backwards compatibility.
            // "ddns-use-conflict-resolution": true,

            // Enumeration, which is passed to kea-dhcp-ddns with each DDNS
            // update request to indicate the mode used for resolving conflicts
            // while performing DDNS updates. The acceptable values are:
            // check-with-dhcid (this includes adding a DHCID record and checking
            // that record via conflict detection as per RFC 4703,
            // no-check-with-dhcid (this will ignore conflict detection but add
            // a DHCID record when creating/updating an entry),
            // check-exists-with-dhcid (this will check if there is an existing
            // DHCID record but does not verify the value of the record matches
            // the update. This will also update the DHCID record for the entry),
            // no-check-without-dhcid (this ignores conflict detection and will
            // not add a DHCID record when creating/updating a DDNS entry).
            // The default value is "check-with-dhcid". It may be
            // specified at the global, shared-network and subnet levels.
            "ddns-conflict-resolution-mode": "check-with-dhcid",

            // When greater than 0.0, it is the percent of the lease's lifetime
            // to use for the DNS TTL.
            "ddns-ttl-percent": 0.75,

            // When greater than 0 it will be used as the DNS TTL. Specified in seconds.
            // Cannot specify both ddns-ttl and any of ddns-ttl-percent, ddns-ttl-min or
            // ddns-ttl-max. They are mutually exclusive.
            // "ddns-ttl": 500,

            // When greater than 0 it used as the lower boundary for calculated DNS TTL values.
            // Specified in seconds.
            "ddns-ttl-min": 24000,

            // When greater than 0 it used as the upper boundary for calculated DNS TTL values.
            // Specified in seconds.
            "ddns-ttl-max": 64000,

            // Time in seconds specifying how long a declined lease should be
            // excluded from DHCP assignments. The default value is 24 hours.
            "decline-probation-period": 86400,

            // Name Change Request forwarding configuration for the Kea DHCPv6 server.
            // NCRs are sent to the Kea D2 module to update DNS upon allocation of
            // DHCP leases.
            "dhcp-ddns": {
                // Boolean flag indicating whether Kea DHCPv6 server should connect to
                // kea-dhcp-ddns. This must be true for NCRs to be created and
                // sent to kea-dhcp-ddns. By default, NCRs are not generated.
                "enable-updates": false,

                // Specifies maximum number of NCRs to queue waiting to be sent
                // to the Kea D2 server.
                "max-queue-size": 1024,

                // Packet format to use when sending NCRs to the Kea D2 server.
                // Currently, only JSON format is supported.
                "ncr-format": "JSON",

                // Socket protocol to use when sending NCRs to D2. Currently,
                // only UDP is supported.
                "ncr-protocol": "UDP",

                // IP address that the Kea DHCPv6 server should use to send
                // NCRs to D2. The default value of zero indicates that Kea
                // should pick a suitable address.
                "sender-ip": "::1",

                // Port number that the Kea DHCPv6 server should use to send
                // NCRs to D2. The default value of zero indicates that Kea
                // should pick a suitable port.
                "sender-port": 0,

                // IP address on which D2 listens for NCRs.
                "server-ip": "::1",

                // Port number on which D2 listens for NCRs.
                "server-port": 53001
            },

            // Specifies the first of the two consecutive ports of the UDP
            // sockets used for communication between DHCPv6 and DHCPv4
            // servers. See RFC 7341. (defaults to 0 - disabled).
            // If enabled, use e.g. 786.
            "dhcp4o6-port": 0,

            // Collection of Kea DHCPv6 server parameters configuring how
            // the server should process expired DHCP leases.
            "expired-leases-processing": {
                // Specifies the number of seconds since the last removal of
                // the expired leases, when the next removal should occur.
                // If both "flush-reclaimed-timer-wait-time" and
                // "hold-reclaimed-time" are not 0, when the client sends a release
                // message the lease is expired instead of being deleted from
                // lease storage.
                "flush-reclaimed-timer-wait-time": 25,

                // Specifies the length of time in seconds to keep expired
                // leases in the lease database (lease affinity).
                // If both "flush-reclaimed-timer-wait-time" and
                // "hold-reclaimed-time" are not 0, when the client sends a release
                // message the lease is expired instead of being deleted from
                // lease storage.
                "hold-reclaimed-time": 3600,

                // Specifies the maximum number of expired leases that can be
                // processed in a single attempt to clean up expired leases
                // from the lease database. If there are more
                // expired leases, they will be processed during the next
                // cleanup attempt.
                "max-reclaim-leases": 100,

                // Specifies the maximum time in milliseconds that a single attempt
                // to clean up expired leases from the lease database may take.
                "max-reclaim-time": 250,

                // Specifies the length of time in seconds since the last attempt
                // to process expired leases before initiating the next attempt.
                "reclaim-timer-wait-time": 10,

                // Specifies the maximum number of expired lease-processing cycles
                // which didn't result in full cleanup of expired leases from the
                // lease database, after which a warning message is issued.
                "unwarned-reclaim-cycles": 5
            },

            // List of hook libraries and their specific configuration parameters
            // to be loaded by Kea DHCPv4 server.
            "hooks-libraries": [
                {
                    // Location of the hook library to be loaded.
                    "library": "libdhcp_lease_cmds.so",

                    // Hook library-specific configuration parameters.
                    "parameters": { }
                },
                {
                    // The MySQL host backend hook library required for host storage.
                    "library": "libdhcp_mysql.so"
                },
                {
                    // The PostgreSQL host backend hook library required for host storage.
                    "library": "libdhcp_pgsql.so"
                }
            ],

            // List of access credentials to external sources of IPv6 reservations,
            "hosts-databases": [
                {
                    // Name of the database to connect to.
                    "name": "keatest",

                    // Host on which the database resides.
                    "host": "localhost",

                    // Database password.
                    "password": "1234",

                    // Port on which the database is available.
                    "port": 3306,

                    // Type of database, e.g. "mysql", "postgresql".
                    "type": "mysql",

                    // Username to be used to access the database.
                    "user": "keatest",

                    // Read-only mode.
                    "readonly": false,

                    // The next entries are for OpenSSL support in MySQL.

                    // Trust anchor aka certificate authority file or directory.
                    "trust-anchor": "my-ca",

                    // Client certificate file name.
                    "cert-file": "my-cert",

                    // Private key file name.
                    "key-file": "my-key",

                    // Cipher list (see the OpenSSL ciphers command manual).
                    "cipher-list": "AES",

                    // Connection reconnect wait time.
                    // This parameter governs how long Kea waits before attempting
                    // to reconnect. Expressed in milliseconds. The default is 0
                    // (disabled) for MySQL and PostgreSQL.
                    "reconnect-wait-time": 3000,

                    // Connection maximum reconnect tries.
                    "max-reconnect-tries": 3,

                    // Action to take when connection recovery fails.
                    // Supported values: stop-retry-exit, serve-retry-exit,
                    // serve-retry-continue
                    "on-fail": "stop-retry-exit",

                    // Flag which indicates if the DB recovery should be attempted
                    // at server startup and on reconfiguration events.
                    "retry-on-startup": false,

                    // Connection connect timeout in seconds.
                    "connect-timeout": 100,

                    // Timeout of database read operations in seconds.
                    "read-timeout": 120,

                    // Timeout of database write operations in seconds.
                    "write-timeout": 180
                },
                {
                    // Name of the database to connect to.
                    "name": "keatest",

                    // Host on which the database resides.
                    "host": "localhost",

                    // Database password.
                    "password": "1234",

                    // Port on which the database is available.
                    "port": 5432,

                    // Type of database, e.g. "mysql", "postgresql".
                    "type": "postgresql",

                    // Username to be used to access the database.
                    "user": "keatest",

                    // TCP user timeout while communicating with the database.
                    // It is specified in seconds.
                    "tcp-user-timeout": 100,

                    // Trust anchor aka certificate authority file or directory.
                    "trust-anchor": "my-ca",

                    // Client certificate file name.
                    "cert-file": "my-cert",

                    // Private key file name.
                    "key-file": "my-key",

                    // SSL mode.
                    "ssl-mode": "verify-ca"
                }
            ],

            // List of host reservation identifier types to be used by the
            // Kea DHCPv6 server to fetch static reservations for
            // DHCP clients. All identifiers are used by default, which
            // means that the server will issue multiple queries to the
            // database to find if there is a reservation for a particular
            // client. If a particular deployment uses only a subset, e.g.
            // one identifier type, this identifier should be only listed
            // here to prevent unnecessary queries to the database.
            "host-reservation-identifiers": [
                "hw-address",
                "duid",
                "flex-id"
            ],

            // Specifies configuration of interfaces on which the Kea DHCPv6
            // server is listening to the DHCP queries.
            "interfaces-config": {
                // Specifies a list of interfaces on which the Kea DHCPv6
                // server should listen to DHCP requests.
                "interfaces": [
                    "eth0"
                ],

                // Boolean flag indicating whether the available interfaces should
                // be re-detected upon server reconfiguration. The default value
                // is true, which means that the interfaces are always
                // re-detected.
                "re-detect": true,

                // Kea tries to bind the service sockets during initialization, but it may
                // fail due to a port being already opened or a misconfiguration. Kea can
                // suppress these errors and only log them. This flag prevents starting
                // the DHCP server without binding all sockets. If unspecified, it
                // defaults to false.
                "service-sockets-require-all": true,

                // Kea tries to bind the service sockets during initialization. This
                // option specifies how many times binding to interface will be retried.
                // The default value is 0, which means that the operation will not be
                // repeated.
                "service-sockets-max-retries": 5,

                // The time interval in milliseconds to wait before the next attempt to
                // retry opening a service socket.
                "service-sockets-retry-wait-time": 5000
            },

            // Boolean parameter which controls whether an early global host
            // reservations lookup should be performed. This lookup takes place
            // before subnet selection and when a global reservation is found
            // with some client classes, it triggers a second phase classification.
            // It can also be used to drop queries using host reservations as a
            // decision table indexed by reservation identifiers.
            "early-global-reservations-lookup": true,

            // Boolean parameter which controls the DHCP server's behavior with respect
            // to creating host reservations for the same IP address or delegated
            // prefix. By default this flag is set to true in which case the server
            // prevents creation of multiple host reservations for the same IP address
            // or delegated prefix. When this parameter is set to false, the server
            // allows for creating multiple reservations for the same IP address or
            // delegated prefix within a subnet. This setting is useful in deployments
            // in which a given host may be communicating with a DHCP server over
            // multiple interfaces and depending on the chosen interface different
            // MAC address (or other identifier) will be used to identify the host.
            // Note that some host backends do not support the mode in which multiple
            // reservations for the same IP address or delegated prefix are used.
            // If these backends are in use and this setting is attempted a
            // configuration error will occur. The MySQL and PostgreSQL backends do
            // support this mode.
            "ip-reservations-unique": true,

            // Boolean parameter which controls whether host reservations lookup
            // should be performed before lease lookup. This parameter has effect
            // only when multi-threading is disabled. When multi-threading is
            // enabled, host reservations lookup is always performed first to avoid
            // lease-lookup resource locking.
            "reservations-lookup-first": true,

            // Specifies credentials to access lease database.
            "lease-database": {
                // memfile backend-specific parameter specifying the interval
                // in seconds at which the lease file should be cleaned up (outdated
                // lease entries are removed to prevent the lease file from growing
                // infinitely).
                "lfc-interval": 3600,

                // Maximum number of lease-file read errors allowed before
                // loading the file is abandoned. Defaults to 0 (no limit).
                "max-row-errors": 100,

                // Name of the lease file. In the case of a database it specifies the
                // database name.
                "name": "kea-leases6.csv",

                // memfile-specific parameter indicating whether leases should
                // be saved on persistent storage (disk) or not. The true value
                // is the default and it indicates that leases are stored in
                // persistent storage. This setting must be used in production.
                // The false value should only be used for testing purposes
                // because non-stored leases will be lost upon Kea server restart.
                "persist": true,

                // Lease database backend type, i.e. "memfile", "mysql" or
                // "postgresql".
                "type": "memfile"
            },

            // List of parameters indicating how the client's MAC address can be
            // inferred from the DHCP query. Supported values are listed in the
            // Kea Administrator Reference Manual.
            "mac-sources": [ "duid" ],

            // List of global DHCP options that the Kea DHCPv6 server assigns to
            // clients.
            "option-data": [
                {
                    // Boolean flag indicating whether the given option is always
                    // sent in response or only when requested. The default
                    // value of false indicates that it is only sent when
                    // requested.
                    "always-send": false,

                    // An optional list of classes for which this option applies.
                    // If the the client matches any of the classes in this list the
                    // option will be applied. If the list is empty or is
                    // omitted this option will be applied regardless of class
                    // membership.
                    "client-classes": [ "class1", "class2" ],

                    // Option code. It is not required if the option name is
                    // provided.
                    "code": 23,

                    // Boolean value indicating whether the option data specified
                    // in the "data" field is specified as a string of hexadecimal
                    // digits or in human-readable CSV format.
                    "csv-format": true,

                    // Option data to be stored in the option payload.
                    "data": "2001:db8:2::45, 2001:db8:2::100",

                    // Option name. It is not required if the option code is
                    // provided.
                    "name": "dns-servers",

                    // Boolean flag indicating whether the given option is never
                    // sent in response. The default value of false indicates
                    // that it is sent when it should be. When true, the option
                    // is not sent despite any other setting, i.e. it is
                    // a final flag.
                    "never-send": false,

                    // Option space. The default is the "dhcp6" option space which
                    // groups top-level DHCPv6 options.
                    "space": "dhcp6"
                }
            ],

            // List of global option definitions, i.e. option formats, that the
            // Kea DHCPv6 server is using.
            "option-def": [
                {
                    // Boolean flag indicating whether the option definition comprises
                    // an array of values of some type, e.g. an array of IPv6 addresses.
                    // The default value of false means that the option does not
                    // comprise an array of values.
                    "array": false,

                    // Option code.
                    "code": 6,

                    // Holds a name of the option space encapsulated by this option.
                    // All options that belong to this option space will be sent
                    // as sub-options of this option. An empty string means that this
                    // option doesn't encapsulate any option.
                    "encapsulate": "",

                    // Option name.
                    "name": "my-option",

                    // Specifies the types of fields within the option if the option
                    // is said to be a "record" (see "type"). In this particular example
                    // this option comprises two fields, 1 byte and 2 bytes long.
                    "record-types": "uint8, uint16",

                    // Name of the option space to which this option belongs.
                    "space": "my-space",

                    // Option type. All possible types are listed in the Kea
                    // Administrator Reference Manual.
                    "type": "record"
                }
            ],

            // Global value which limits the number of client packets (e.g.
            // REQUESTs,RENEWs...) that may be parked while waiting for
            // hook library work to complete, prior to a response (e.g. REPLY)
            // being sent back to the client. A typical example is when kea-dhcp6
            // parks a REQUEST while it sends the lease update(s) to its
            // HA peer(s). The packet is unparked once the update(s) have been
            // acknowledged.  This value limits the number of packets that can
            // be held pending the updates. In times of heavy client traffic,
            // this value can keep kea-dhcp6 from building an insurmountable
            // backlog of updates.
            "parked-packet-limit": 256,

            // Global (default) value of the preferred lifetime.
            "preferred-lifetime": 50,

            // Global min value of the preferred lifetime.
            "min-preferred-lifetime": 40,

            // Global max value of the preferred lifetime.
            "max-preferred-lifetime": 60,

            // Global value for the rebind timer, i.e. the time after which the
            // DHCP client enters the rebind state if it fails to renew the lease.
            "rebind-timer": 40,

            // List of relay supplied option codes. See RFC 6422.
            "relay-supplied-options": [ "110", "120", "130" ],

            // Global value for the renew timer, i.e. the time after which the
            // DHCP client renews the lease.
            "renew-timer": 30,

            // Global value to store extended information (e.g. relay agent
            // information) with each lease.
            "store-extended-info": true,

            // Statistics keep some samples per observation point.
            // There are two default values: maximum count and maximum age.
            // Setting the maximum count to zero disables it.
            "statistic-default-sample-count": 0,

            // When the maximum count is 0 the maximum age (in seconds) applies.
            "statistic-default-sample-age": 60,

            // Multi-threading parameters.
            "multi-threading": {
                // By default, Kea processes packets on multiple threads if the hardware permits.
                "enable-multi-threading": true,

                // When multi-threading is enabled, Kea will process packets on a
                // number of multiple threads configurable through this option. The
                // value must be a positive integer (0 means auto-detect).
                "thread-pool-size": 0,

                // When multi-threading is enabled, Kea will read packets from the
                // interface and append a working item to the thread pool. This
                // option configures the maximum number of items that can be queued.
                // The value must be a positive integer (0 means unlimited).
                "packet-queue-size": 0
            },

            // Governs how the Kea DHCPv6 server should deal with invalid
            // data received from the client.
            "sanity-checks": {
                // Specifies how the Kea DHCPv6 server should behave when invalid
                // data is read for a lease from the lease file. The following
                // values are supported: "none" (don't attempt to correct the
                // lease information), "warn" (print a warning for subnet-id
                // related inconsistencies), "fix" (correct the subnet id by
                // trying to find the suitable subnet), "fix-del" (similar
                // to "fix" but delete the lease if no suitable subnet found),
                // "del" (delete the lease if the lease has invalid subnet
                // identifier value).
                "lease-checks": "warn",

                // Specifies how Kea DHCPv4 server should behave when invalid
                // extended info is read for a lease from the lease file, or
                // whether to upgrade from the old format. The following values
                // are supported: "none" (don't attempt to correct or upgrade
                // the extended info), "fix" (fix common inconsistencies and
                // upgrade from the old format; this is the default), "strict"
                // (fix inconsistencies with an impact on Leasequery),
                // "pedantic" (enforce full Kea code format).
                "extended-info-checks": "fix"
            },

            // Custom DUID used by the DHCPv6 server.
            "server-id": {
                // Type of the DUID. Possible values are "LLT", "EN", and "LL".
                "type": "EN",

                // Enterprise id used for "EN" duid.
                "enterprise-id": 2495,

                // Identifier part of the DUID.
                "identifier": "0123456789",

                // Boolean flag indicating whether the DUID should be persisted on
                // disk.
                "persist": false
            },

            // List of shared networks used by the Kea DHCPv6 server. The shared
            // networks group subnets together.
            "shared-networks": [
                {
                    // A flag selecting an IP address allocation strategy for all
                    // subnets in this shared network.
                    "allocator": "random",

                    // A flag selecting a delegated prefix allocation strategy for
                    // all subnets in this shared network.
                    "pd-allocator": "iterative",

                    // Restricts this shared network to allow only clients
                    // that belong to at least one class in this list. If omitted
                    // or an empty list is provided, no restriction is applied.
                    "client-classes": [],

                    // Shared-network level value. See description at the global level.
                    "ddns-generated-prefix": "myhost",

                    // Shared-network level value. See description at the global level.
                    "ddns-override-client-update": false,

                    // Shared-network level value. See description at the global level.
                    "ddns-override-no-update": false,

                    // Shared-network level value. See description at the global level.
                    "ddns-qualifying-suffix": "",

                    // Shared-network level value. See description at the global level.
                    "ddns-replace-client-name": "never",

                    // Shared-network level value. See description at the global level.
                    "ddns-send-updates": true,

                    // Shared-network level value. See description at the global level.
                    "ddns-update-on-renew": true,

                    // Shared-network level value. See description at the global level.
                    // This field has been replaced by ddns-conflict-resolution-mode.
                    // Parsing is maintained only for backwards compatibility.
                    // "ddns-use-conflict-resolution": true,

                    // Shared-network level value. See description at the global level.
                    "ddns-conflict-resolution-mode": "check-with-dhcid",

                    // Shared-network level value. See description at the global level.
                    "ddns-ttl-percent": 0.65,

                    // Shared-network level value. See description at the global level.
                    // Cannot specify both ddns-ttl and any of ddns-ttl-percent, ddns-ttl-min or
                    // ddns-ttl-max. They are mutually exclusive.
                    // "ddns-ttl": 500,

                    // Shared-network level value. See description at the global level.
                    "ddns-ttl-min": 10000,

                    // Shared-network level value. See description at the global level.
                    "ddns-ttl-max": 20000,

                    // Shared-network level value. See description at the global level.
                    "hostname-char-replacement": "x",

                    // Shared-network level value. See description at the global level.
                    "hostname-char-set": "[^A-Za-z0-9.-]",

                    // Specifies that this shared network is selected for
                    // requests received on a particular interface.
                    "interface": "eth0",

                    // Specifies the content of the interface-id option used
                    // by relays to identify the interface on the relay to
                    // which the response is sent.
                    "interface-id": "",

                    // Shared network name.
                    "name": "my-secret-network",

                    // List of shared network-specific DHCP options.
                    "option-data": [],

                    // Shared network-specific (default) preferred lifetime.
                    "preferred-lifetime": 2000,

                    // Shared network-specific min preferred lifetime.
                    "min-preferred-lifetime": 1500,

                    // Shared network-specific ma xpreferred lifetime.
                    "max-preferred-lifetime": 2500,

                    // Boolean flag indicating whether the server can respond to
                    // a Solicit message including a Rapid Commit option with
                    // the Reply message (See DHCPv6 rapid commit).
                    "rapid-commit": false,

                    // List of IPv6 relay addresses for which this shared
                    // network is selected.
                    "relay": {
                        "ip-addresses": []
                    },

                    // Shared-network level rebind timer.
                    "rebind-timer": 41,

                    // Shared-network level renew timer.
                    "renew-timer": 31,

                    // Shared-network level compute T1 and T2 timers.
                    "calculate-tee-times": true,

                    // T1 = valid lifetime * .5.
                    "t1-percent": .5,

                    // T2 = valid lifetime * .75.
                    "t2-percent": .75,

                    // Cache threshold = valid lifetime * .25.
                    "cache-threshold": .25,

                    // Cache maximum: when the client last-transmission time
                    // is close enough, the lease is not renewed and the current
                    // lease is returned as it was "cached".
                    "cache-max-age": 1000,

                    // Adaptive lease time threshold (1.0 is disabled).
                    "adaptive-lease-time-threshold": 0.8,

                    // Specify whether the server should look up global reservations.
                    "reservations-global": false,

                    // Specify whether the server should look up in-subnet reservations.
                    "reservations-in-subnet": true,

                    // Specify whether the server can assume that all reserved addresses
                    // are out-of-pool.
                    // Ignored when reservations-in-subnet is false.
                    // If specified, it is inherited by "subnet6" levels.
                    "reservations-out-of-pool": false,

                    // List of client classes which must be evaluated when this shared
                    // network is selected for client assignments.
                    "evaluate-additional-classes": [ "late" ],

                    // Turn off storage of extended information (e.g. relay agent
                    // information) with each lease for this shared network.
                    "store-extended-info": false,

                    // List of IPv6 subnets belonging to this shared network.
                    "subnet6": [
                        {
                            // A flag selecting an IP address allocation strategy for
                            // the subnet.
                            "allocator": "iterative",

                            // A flag selecting a delegated prefix allocation strategy
                            // for the subnet.
                            "pd-allocator": "iterative",

                            // Restricts this subnet to allow only clients
                            // that belong to at least one class in this list. If omitted
                            // or an empty list is provided, no restriction is applied.
                            "client-classes": [],

                            // Subnet-level value. See description at the global level.
                            "ddns-generated-prefix": "myhost",

                            // Subnet-level value. See description at the global level.
                            "ddns-override-client-update": false,

                            // Subnet-level value. See description at the global level.
                            "ddns-override-no-update": false,

                            // Subnet-level value. See description at the global level.
                            "ddns-qualifying-suffix": "",

                            // Subnet-level value. See description at the global level.
                            "ddns-replace-client-name": "never",

                            // Subnet-level value. See description at the global level.
                            "ddns-send-updates": true,

                            // Subnet-level value. See description at the global level.
                            "ddns-update-on-renew": true,

                            // Subnet-level value. See description at the global level.
                            // This field has been replaced by ddns-conflict-resolution-mode.
                            // Parsing is maintained only for backwards compatibility.
                            // "ddns-use-conflict-resolution": true,

                            // Subnet-level value. See description at the global level.
                            "ddns-conflict-resolution-mode": "check-with-dhcid",

                            // Subnet-level value. See description at the global level.
                            // "ddns-ttl-percent": 0.55,

                            // "ddns-ttl": 0,
                            // Cannot specify both ddns-ttl and any of ddns-ttl-percent, ddns-ttl-min or
                            // ddns-ttl-max. They are mutually exclusive.
                            "ddns-ttl": 500,

                            // Subnet-level value. See description at the global level.
                            // "ddns-ttl-min": 10000,

                            // Subnet-level value. See description at the global level.
                            // "ddns-ttl-max": 20000,

                            // Subnet-level value. See description at the global level.
                            "hostname-char-replacement": "x",

                            // Subnet-level value. See description at the global level.
                            "hostname-char-set": "[^A-Za-z0-9.-]",

                            // Subnet unique identifier.
                            "id": 1,

                            // Specifies that this subnet is selected for requests
                            // received on a particular interface.
                            "interface": "eth0",

                            // Specifies the content of the interface-id option used
                            // by relays to identify the interface on the relay to
                            // which the response is sent.
                            "interface-id": "",

                            // Turn on storage of extended information (e.g. relay agent
                            // information) with each lease for this subnet.
                            "store-extended-info": true,

                            // Subnet-level list of DHCP options.
                            "option-data": [
                                {
                                    // Boolean flag indicating whether the particular option
                                    // should be always sent or sent only when requested.
                                    "always-send": false,

                                    // An optional list of classes for which this option applies.
                                    // If the the client matches any of the classes in this list the
                                    // option will be applied. If the list is empty or is
                                    // omitted this option will be applied regardless of class
                                    // membership.
                                    "client-classes": [],

                                    // Option code.
                                    "code": 7,

                                    // Boolean flag indicating whether the option value specified
                                    // in "data" is a string of hexadecimal values or human-readable
                                    // CSV value.
                                    "csv-format": false,

                                    // Option data to be included in the option payload.
                                    "data": "0xf0",

                                    // Option name.
                                    "name": "preference",

                                    // Boolean flag indicating whether the given option is never
                                    // sent in response.
                                    "never-send": false,

                                    // Option space. The default value "dhcp6" designates the
                                    // top level option space.
                                    "space": "dhcp6"
                                }
                            ],

                            // List of pools from which delegated prefixes are assigned to the
                            // clients.
                            "pd-pools": [
                                {
                                    // Restricts this prefix pool subnet to allow only clients
                                    // that belong to at least one class in this list. If omitted
                                    // or an empty list is provided, no restriction is applied.
                                    "client-classes": [ "phones_server1" ],

                                    // Length of prefixes delegated to clients.
                                    "delegated-len": 64,

                                    // Excluded prefix (address) from client assignments.
                                    "excluded-prefix": "2001:db8:1::",

                                    // Excluded prefix (length) from client assignments.
                                    "excluded-prefix-len": 72,

                                    // Prefix pool level list of DHCP options.
                                    "option-data": [],

                                    // Prefix range (address) used for client assignments.
                                    "prefix": "2001:db8:1::",

                                    // Prefix range (length) used for client assignments.
                                    "prefix-len": 48,

                                    // List of client classes which must be evaluated
                                    // when this prefix pool is selected for client assignments.
                                    "evaluate-additional-classes": [],

                                    // PD-pool identifier used to enable statistics for this pd-pool.
                                    // The pd-pool ID does not need to be unique within the subnet
                                    // or across subnets.
                                    // If not unconfigured, it defaults to 0. The statistics
                                    // regarding this pd-pool will be combined with the other statistics
                                    // of all other pd-pools with the same pd-pool ID in this subnet.
                                    "pool-id": 1
                                },
                                {
                                    // Length of prefixes delegated to clients.
                                    "delegated-len": 64,

                                    // Prefix range (address) used for client assignments.
                                    "prefix": "2001:db8:2::",

                                    // Prefix range (length) used for client assignments.
                                    "prefix-len": 48
                                }
                            ],

                            // List of IP address pools belonging to the subnet.
                            "pools": [
                                {
                                    // Restricts this pool subnet to allow only clients
                                    // that belong to at least one class in this list. If omitted
                                    // or an empty list is provided, no restriction is applied.
                                    "client-classes": [ "phones_server1" ],

                                    // Pool-level list of DHCP options.
                                    "option-data": [],

                                    // Address range used for client assignments.
                                    "pool": "2001:db8:0:1::/64",

                                    // List of client classes which must be evaluated when this pool
                                    // is selected for client assignments.
                                    "evaluate-additional-classes": [ "late" ],

                                    // Pool-level value. See description at the global level.
                                    "ddns-generated-prefix": "mypool",

                                    // Pool-level value. See description at the global level.
                                    "ddns-override-client-update": false,

                                    // Pool-level value. See description at the global level.
                                    "ddns-override-no-update": false,

                                    // Pool-level value. See description at the global level.
                                    "ddns-qualifying-suffix": "pool.example.com.",

                                    // Pool-level value. See description at the global level.
                                    "ddns-replace-client-name": "always",

                                    // Pool-level value. See description at the global level.
                                    "ddns-send-updates": true,

                                    // Pool-level value. See description at the global level.
                                    "ddns-update-on-renew": false,

                                    // Pool-level value. See description at the global level.
                                    "ddns-conflict-resolution-mode": "check-with-dhcid",

                                    // Pool-level value. See description at the global level.
                                    "ddns-ttl-percent": 0.55,

                                    // Pool-level value. See description at the global level.
                                    // You cannot specify both ddns-ttl and any of ddns-ttl-percent,
                                    // ddns-ttl-min, or ddns-ttl-max. They are mutually exclusive.
                                    // "ddns-ttl": 500,

                                    // Pool-level value. See description at the global level.
                                    "ddns-ttl-min": 10000,

                                    // Pool-level value. See description at the global level.
                                    "ddns-ttl-max": 20000,

                                    // Pool-level value. See description at the global level.
                                    "hostname-char-replacement": "x",

                                    // Pool-level value. See description at the global level.
                                    "hostname-char-set": "[^A-Za-z0-9.-]"
                                },
                                {
                                    // Restricts this pool subnet to allow only clients
                                    // that belong to at least one class in this list. If omitted
                                    // or an empty list is provided, no restriction is applied.
                                    "client-classes": [ "phones_server2" ],

                                    // Pool-level list of DHCP options.
                                    "option-data": [],

                                    // Address range used for client assignments.
                                    "pool": "2001:db8:0:3::/64",

                                    // List of client classes which must be evaluated when this pool
                                    // is selected for client assignments.
                                    "evaluate-additional-classes": [],

                                    // Pool identifier used to enable statistics for this pool.
                                    // The pool ID does not need to be unique within the subnet
                                    // or across subnets.
                                    // If not unconfigured, it defaults to 0. The statistics
                                    // regarding this pool will be combined with the other statistics
                                    // of all other pools with the same pool ID in this subnet.
                                    "pool-id": 1
                                }
                            ],

                            // Subnet specific (default) preferred lifetime.
                            "preferred-lifetime": 2000,

                            // Subnet specific min preferred lifetime.
                            "min-preferred-lifetime": 1500,

                            // Subnet specific max referred lifetime.
                            "max-preferred-lifetime": 2500,

                            // Boolean flag indicating whether the server can respond to
                            // a Solicit message including a Rapid Commit option with
                            // the Reply message (See DHCPv6 rapid commit).
                            "rapid-commit": false,

                            // Subnet-level value of the rebind timer.
                            "rebind-timer": 40,

                            // List of IPv6 relay addresses for which this subnet is selected.
                            "relay": {
                                "ip-addresses": [
                                    "2001:db8:0:f::1"
                                ]
                            },

                            // Subnet-level renew timer.
                            "renew-timer": 30,

                            // Specify whether the server should look up global reservations.
                            "reservations-global": false,

                            // Specify whether the server should look up in-subnet reservations.
                            "reservations-in-subnet": true,

                            // Specify whether the server can assume that all reserved
                            // addresses are out-of-pool.
                            // Ignored when reservations-in-subnet is false.
                            "reservations-out-of-pool": false,

                            // Subnet-level compute T1 and T2 timers.
                            "calculate-tee-times": true,

                            // T1 = valid lifetime * .5.
                            "t1-percent": .5,

                            // T2 = valid lifetime * .75.
                            "t2-percent": .75,

                            // Cache threshold = valid lifetime * .25.
                            "cache-threshold": .25,

                            // Subnet-level cache maximum.
                            "cache-max-age": 1000,

                            // Adaptive lease time threshold (1.0 is disabled).
                            "adaptive-lease-time-threshold": 0.8,

                            // List of static IPv6 reservations assigned to clients belonging
                            // to this subnet. For a detailed example, see reservations.json.
                            "reservations": [
                                {
                                    // Identifier used for client matching. Supported values are
                                    // "duid", "hw-address" and "flex-id".
                                    "duid": "01:02:03:04:05:06:07:08:09:0A",

                                    // List of reserved IPv6 addresses.
                                    "ip-addresses": [ "2001:db8:1:cafe::1" ],

                                    // List of reserved IPv6 prefixes.
                                    "prefixes": [ "2001:db8:2:abcd::/64" ],

                                    // List of excluded IPv6 prefixes.
                                    "excluded-prefixes": [ "2001:db8:2:abcd:1::/80" ],

                                    // Reserved hostname.
                                    "hostname": "foo.example.com",

                                    // Reservation-specific option data.
                                    "option-data": [
                                        {
                                            // Option name.
                                            "name": "vendor-opts",

                                            // Option value.
                                            "data": "4491"
                                        }
                                    ]
                                }
                            ],

                            // List of client classes which must be evaluated when this subnet
                            // is selected for client assignments.
                            "evaluate-additional-classes": [ "late" ],

                            // Subnet prefix.
                            "subnet": "2001:db8::/32",

                            // Subnet-level (default) valid lifetime.
                            "valid-lifetime": 6000,

                            // Subnet-level min valid lifetime.
                            "min-valid-lifetime": 4000,

                            // Subnet-level max valid lifetime.
                            "max-valid-lifetime": 8000
                        }
                    ],

                    // Shared-network level (default) valid lifetime.
                    "valid-lifetime": 6001,

                    // Shared-network level min valid lifetime.
                    "min-valid-lifetime": 4001,

                    // Shared-network level max valid lifetime.
                    "max-valid-lifetime": 8001
                }
            ],

            // List of IPv6 subnets which don't belong to any shared network.
            "subnet6": [],

            // Global valid lifetime value.
            "valid-lifetime": 6000,

            // Global min valid lifetime value.
            "min-valid-lifetime": 4000,

            // Global max valid lifetime value.
            "max-valid-lifetime": 8000,

            // Reservations (examples are in other files).
            "reservations": [],

            // Configuration control (currently not used, i.e. this syntax
            // is already defined but the corresponding feature is not implemented).
            "config-control": {
                // Only the configuration databases entry is defined.
                "config-databases": [
                    {
                        // Name of the database to connect to.
                        "name": "config",

                        // Type of database, e.g. "mysql", "postgresql".
                        "type": "mysql"
                    }
                ],
                // Interval between attempts to fetch configuration updates
                // via the configuration backends used.
                "config-fetch-wait-time": 30
            },

            // Server tag.
            "server-tag": "my DHCPv6 server",

            // DHCP queue-control parameters.
            "dhcp-queue-control": {
                // Enable queue is mandatory.
                "enable-queue": true,

                // Queue type is mandatory.
                "queue-type": "kea-ring6",

                // Capacity is optional.
                "capacity": 64
            },

            // Specify whether the server should look up global reservations.
            "reservations-global": false,

            // Specify whether the server should look up in-subnet reservations.
            "reservations-in-subnet": true,

            // Specify whether the server can assume that all reserved addresses
            // are out-of-pool.
            // Ignored when reservations-in-subnet is false.
            // If specified, it is inherited by "shared-networks" and
            // "subnet6" levels.
            "reservations-out-of-pool": false,

            // Global compute T1 and T2 timers.
            "calculate-tee-times": true,

            // T1 = valid lifetime * .5.
            "t1-percent": .5,

            // T2 = valid lifetime * .75.
            "t2-percent": .75,

            // Cache threshold = valid lifetime * .25.
            "cache-threshold": .25,

            // Global cache maximum.
            "cache-max-age": 1000,

            // Adaptive lease time threshold (1.0 is disabled)
            "adaptive-lease-time-threshold": 0.8,

            // String of zero or more characters with which to replace each
            // invalid character in the Client FQDN. The default
            // value is an empty string, which will cause invalid characters
            // to be omitted rather than replaced.
            "hostname-char-replacement": "x",

            // Regular expression describing the invalid character set in
            // the Client FQDN.
            "hostname-char-set": "[^A-Za-z0-9.-]",

            // List of loggers used by the servers using this configuration file.
            "loggers": [
                {
                    // Debug level, a value between 0..99. The greater the value
                    // the more detailed the debug log.
                    "debuglevel": 99,

                    // Name of the logger.
                    "name": "kea-dhcp6",

                    // Configures how the log should be output.
                    "output-options": [
                        {
                            // Determines whether the log should be flushed to a file.
                            "flush": true,

                            // Specifies maximum filesize before the file is rotated.
                            "maxsize": 10240000,

                            // Specifies the maximum number of rotated files to be kept.
                            "maxver": 1,

                            // Specifies the logging destination.
                            "output": "stdout",

                            // Specifies log entry content
                            "pattern": "%D{%Y-%m-%d %H:%M:%S.%q} %-5p [%c/%i] %m\n"
                        }
                    ],

                    // Specifies logging severity, i.e. "ERROR", "WARN", "INFO", "DEBUG".
                    "severity": "INFO"
                }
            ],

            // Look at advanced examples for the use of user-contexts.
            "user-context": { }
        }
    }

.. _config-example-kea6-all-keys-json:

------------------
kea6/all-keys.json
------------------

.. code-block::
    :linenos:

    // WARNING: This example configuration is not meant for production use.
    // The Kea DHCPv6 server will refuse this configuration because it contains
    // mutually exclusive configuration parameters.
    //
    // The primary purpose of the example file is to provide a comprehensive
    // list of parameters supported by the Kea DHCPv6 server along with the brief
    // description of each parameter.
    //
    // This current version should be up to date, i.e. new keywords should be
    // added in this file at the same time as in the parser specification.
    {
        // Kea DHCPv6 server configuration begins here.
        "Dhcp6": {
            // Global flag selecting an IP address allocation strategy for all
            // subnets.
            "allocator": "iterative",

            // Global flag that enables or disables client address registration
            // via ADDR-REG-INFORM packets (see RFC 9686). It defaults to true.
            "allow-address-registration": true,

            // Global flag selecting a delegated prefix allocation strategy
            // for all subnets.
            "pd-allocator": "random",

            // Ordered list of client classes used by the DHCPv6 server.
            "client-classes": [
                {
                    // Class name.
                    "name": "phones_server1",

                    // Class-specific DHCPv6 options list.
                    "option-data": [],

                    // Class selection expression. The DHCP packet is assigned to this
                    // class when the given expression evaluates to true.
                    "test": "member('HA_server1')",

                    // Class valid lifetime.
                    "valid-lifetime": 6000,

                    // Class min valid lifetime.
                    "min-valid-lifetime": 4000,

                    // Class max valid lifetime.
                    "max-valid-lifetime": 8000,

                    // Class preferred lifetime.
                    "preferred-lifetime": 7000,

                    // Class min preferred lifetime.
                    "min-preferred-lifetime": 5000,

                    // Class max preferred lifetime.
                    "max-preferred-lifetime": 9000
                },
                {
                    // Second class name.
                    "name": "phones_server2",

                    // Class-specific DHCPv6 options list.
                    "option-data": [],

                    // Class selection expression. The DHCP packet is assigned to this
                    // class when the given expression evaluates to true.
                    "test": "member('HA_server2')"
                },
                {
                    // Third class name.
                    "name": "late",

                    // Boolean flag indicating whether the class expression is only evaluated
                    // when the class is required, e.g. the selected address pool configuration
                    // includes this class name in its "evaluate-additional-classes" list. The
                    // default value false means that the class test expression must
                    // always be evaluated.
                    "only-in-additional-list": true,

                    // Class selection expression.
                    "test": "member('ALL')"
                },
                {
                    // Fourth class name.
                    "name": "my-template-class",

                    // Template class flag that holds the expression used to generate the names for all
                    // the spawned subclasses. In this case, the classes are named after the client ID.
                    "template-test": "substring(option[1].hex, 0, all)"
                }
            ],

            // Parameters for triggering behaviors compatible with broken or
            // non-compliant clients, relays, or other agents
            "compatibility": {
                // Parse options more leniently where fields can be deduced
                // deterministically, even if against RFC or common practice.
                "lenient-option-parsing": true
            },

            // Command control socket configuration parameters for the Kea DHCPv6 server.
            "control-sockets": [
                {
                    // Control socket type used by the Kea DHCPv6 server.
                    // Must be unix, http or https.
                    "socket-type": "unix",

                   // Location of the UNIX domain socket file the DHCPv6
                   // server uses to receive control commands from the
                   // local server administrator.
                   "socket-name": "kea6-ctrl-socket"
                },
                {
                    // Control socket type used by the Kea DHCPv6 server.
                    // Must be unix, http or https.
                    "socket-type": "https",

                    // Address of the HTTPS socket the Kea DHCPv6 server should
                    // listen for incoming queries.
                    "socket-address": "::1",

                    // Port of the HTTPS socket the Kea DHCPv6 server
                    // should listen for incoming queries. If enabling HA
                    // and multi-threading, the 8000 port is used by the
                    // HA hook library http listener. When using HA hook
                    // library with multi-threading to function, make sure
                    // the port used by dedicated listener is different
                    // (e.g. 8001) than the one specified here.  Note the
                    // commands should still be sent to a control socket.
                    // The dedicated listener is specifically for HA
                    // updates only.
                    "socket-port": 8006,

                    // TLS trust anchor (Certificate Authority). This is a
                    // file name or a directory path. Make sense with other
                    // TLS parameters only for the https control socket type.
                    "trust-anchor": "my-ca",

                    // TLS server certificate file name.
                    "cert-file": "my-cert",

                    // TLS server private key file name.
                    "key-file": "my-key",

                    // TLS require client certificates flag. Default is
                    // true and means require client certificates. False
                    // means they are optional.
                    "cert-required": true,

                    // Extra HTTP headers to add in responses.
                    "http-headers":
                    [
                        {
                            // Optional user context.
                            "user-context": { "comment": "HSTS header" },

                            // Required HTTP header name.
                            "name": "Strict-Transport-Security",

                            // Required HTTP header value.
                            "value": "max-age=31536000"
                        }
                    ],

                    // Optional authentication.
                    "authentication": {

                        // Required authentication type. The only
                        // supported value is basic for the basic HTTP
                        // authentication.
                        "type": "basic",

                        // An optional parameter is the basic HTTP
                        // authentication realm.  Its default is
                        // "kea-dhcpv6-server"
                        "realm": "kea-dhcpv6-server",

                        // This optional parameter can be used to specify a common
                        // prefix for files handling client credentials.
                        "directory": "/usr/local/share/kea/kea-creds",

                        // This list specifies the user ids and passwords
                        // to use for basic HTTP authentication. If empty
                        // or not present any client is authorized.
                        "clients": [
                            // This specifies an authorized client.
                            {
                                // The user id must not be empty or
                                // contain the ':' character. It is a
                                // mandatory parameter.
                                "user": "admin",

                                // If password is not specified an empty
                                // password is used.
                                "password": "1234"
                            },

                            // This specifies a hidden client.
                            {
                                // The user id is the content of the
                                // file /usr/local/share/kea/kea-creds/hiddenu.
                                "user-file": "hiddenu",

                                // The password is the content of the
                                // file /usr/local/share/kea/kea-creds/hiddenp.
                                "password-file": "hiddenp"
                            },

                            // This specifies a hidden client using a
                            // secret in a file.
                            {
                                // The secret is the content of the file
                                // /usr/local/share/kea/kea-creds/hiddens which must be in
                                // the <user-id>:<password> format.
                                "password-file": "hiddens"
                            }
                        ]
                    }
                }
            ],

            // Specifies a prefix to be prepended to the generated Client FQDN.
            // It may be specified at the global, shared-network, and subnet levels.
            "ddns-generated-prefix": "myhost",

            // Boolean flag indicating whether the server should ignore DHCP client
            // wishes to update DNS on its own. With that flag set to true,
            // the server will send DNS updates for both forward and
            // reverse DNS data. The default value is false, which indicates
            // that the server will delegate a DNS update to the client when
            // requested. It may be specified at the global, shared-network,
            // and subnet levels.
            "ddns-override-client-update": false,

            // Boolean flag indicating whether the server should override the DHCP
            // client's wish to not update the DNS. With this parameter
            // set to true, the server will send a DNS update even when
            // the client requested no update. It may be specified at the
            // global, shared-network, and subnet levels.
            "ddns-override-no-update": false,

            // Suffix appended to the partial name sent to the DNS. The
            // default value is an empty string, which indicates that no
            // suffix is appended. It may be specified at the global,
            // shared-network, and subnet levels.
            "ddns-qualifying-suffix": "",

            // Enumeration specifying whether the server should honor
            // the hostname or Client FQDN sent by the client or replace
            // this name. The acceptable values are: "never" (use the
            // name the client sent), "always" (replace the name the
            // client sent), "when-present" (replace the name the client
            // sent, but do not generate one when the client didn't send
            // the name), "when-not-present" (generate the name when
            // client didn't send one, otherwise leave the name the
            // client sent). The default value is "never". It may be
            // specified at the global, shared-network, and subnet levels.
            "ddns-replace-client-name": "never",

            // Boolean flag which enables or disables DDNS updating. It
            // defaults to true. It may be specified at the global, shared-
            // network, and subnet levels. It works in conjunction with
            // dhcp-ddns:enable-updates, which must be true to enable connectivity
            // to kea-dhcp-ddns.
            "ddns-send-updates": true,

            // Boolean flag, which when true instructs the server to always
            // update DNS when leases are renewed, even if the DNS information
            // has not changed. The server's default behavior (i.e. flag is false)
            // is to only update DNS if the DNS information has changed. It
            // may be specified at the global, shared-network, and subnet levels.
            "ddns-update-on-renew": true,

            // Boolean flag which is passed to kea-dhcp-ddns with each DDNS
            // update request, to indicate whether DNS update conflict
            // resolution as described in RFC 4703 should be employed for the
            // given update request. The default value for this flag is true.
            // It may be specified at the global, shared-network, and subnet levels.
            // This field has been replaced by ddns-conflict-resolution-mode.
            // Parsing is maintained only for backwards compatibility.
            // "ddns-use-conflict-resolution": true,

            // Enumeration, which is passed to kea-dhcp-ddns with each DDNS
            // update request to indicate the mode used for resolving conflicts
            // while performing DDNS updates. The acceptable values are:
            // check-with-dhcid (this includes adding a DHCID record and checking
            // that record via conflict detection as per RFC 4703,
            // no-check-with-dhcid (this will ignore conflict detection but add
            // a DHCID record when creating/updating an entry),
            // check-exists-with-dhcid (this will check if there is an existing
            // DHCID record but does not verify the value of the record matches
            // the update. This will also update the DHCID record for the entry),
            // no-check-without-dhcid (this ignores conflict detection and will
            // not add a DHCID record when creating/updating a DDNS entry).
            // The default value is "check-with-dhcid". It may be
            // specified at the global, shared-network and subnet levels.
            "ddns-conflict-resolution-mode": "check-with-dhcid",

            // When greater than 0.0, it is the percent of the lease's lifetime
            // to use for the DNS TTL.
            "ddns-ttl-percent": 0.75,

            // When greater than 0 it will be used as the DNS TTL. Specified in seconds.
            // Cannot specify both ddns-ttl and any of ddns-ttl-percent, ddns-ttl-min or
            // ddns-ttl-max. They are mutually exclusive.
            // "ddns-ttl": 500,

            // When greater than 0 it used as the lower boundary for calculated DNS TTL values.
            // Specified in seconds.
            "ddns-ttl-min": 24000,

            // When greater than 0 it used as the upper boundary for calculated DNS TTL values.
            // Specified in seconds.
            "ddns-ttl-max": 64000,

            // Time in seconds specifying how long a declined lease should be
            // excluded from DHCP assignments. The default value is 24 hours.
            "decline-probation-period": 86400,

            // Name Change Request forwarding configuration for the Kea DHCPv6 server.
            // NCRs are sent to the Kea D2 module to update DNS upon allocation of
            // DHCP leases.
            "dhcp-ddns": {
                // Boolean flag indicating whether Kea DHCPv6 server should connect to
                // kea-dhcp-ddns. This must be true for NCRs to be created and
                // sent to kea-dhcp-ddns. By default, NCRs are not generated.
                "enable-updates": false,

                // Specifies maximum number of NCRs to queue waiting to be sent
                // to the Kea D2 server.
                "max-queue-size": 1024,

                // Packet format to use when sending NCRs to the Kea D2 server.
                // Currently, only JSON format is supported.
                "ncr-format": "JSON",

                // Socket protocol to use when sending NCRs to D2. Currently,
                // only UDP is supported.
                "ncr-protocol": "UDP",

                // IP address that the Kea DHCPv6 server should use to send
                // NCRs to D2. The default value of zero indicates that Kea
                // should pick a suitable address.
                "sender-ip": "::1",

                // Port number that the Kea DHCPv6 server should use to send
                // NCRs to D2. The default value of zero indicates that Kea
                // should pick a suitable port.
                "sender-port": 0,

                // IP address on which D2 listens for NCRs.
                "server-ip": "::1",

                // Port number on which D2 listens for NCRs.
                "server-port": 53001
            },

            // Specifies the first of the two consecutive ports of the UDP
            // sockets used for communication between DHCPv6 and DHCPv4
            // servers. See RFC 7341. (defaults to 0 - disabled).
            // If enabled, use e.g. 786.
            "dhcp4o6-port": 0,

            // Collection of Kea DHCPv6 server parameters configuring how
            // the server should process expired DHCP leases.
            "expired-leases-processing": {
                // Specifies the number of seconds since the last removal of
                // the expired leases, when the next removal should occur.
                // If both "flush-reclaimed-timer-wait-time" and
                // "hold-reclaimed-time" are not 0, when the client sends a release
                // message the lease is expired instead of being deleted from
                // lease storage.
                "flush-reclaimed-timer-wait-time": 25,

                // Specifies the length of time in seconds to keep expired
                // leases in the lease database (lease affinity).
                // If both "flush-reclaimed-timer-wait-time" and
                // "hold-reclaimed-time" are not 0, when the client sends a release
                // message the lease is expired instead of being deleted from
                // lease storage.
                "hold-reclaimed-time": 3600,

                // Specifies the maximum number of expired leases that can be
                // processed in a single attempt to clean up expired leases
                // from the lease database. If there are more
                // expired leases, they will be processed during the next
                // cleanup attempt.
                "max-reclaim-leases": 100,

                // Specifies the maximum time in milliseconds that a single attempt
                // to clean up expired leases from the lease database may take.
                "max-reclaim-time": 250,

                // Specifies the length of time in seconds since the last attempt
                // to process expired leases before initiating the next attempt.
                "reclaim-timer-wait-time": 10,

                // Specifies the maximum number of expired lease-processing cycles
                // which didn't result in full cleanup of expired leases from the
                // lease database, after which a warning message is issued.
                "unwarned-reclaim-cycles": 5
            },

            // List of hook libraries and their specific configuration parameters
            // to be loaded by Kea DHCPv4 server.
            "hooks-libraries": [
                {
                    // Location of the hook library to be loaded.
                    "library": "libdhcp_lease_cmds.so",

                    // Hook library-specific configuration parameters.
                    "parameters": { }
                },
                {
                    // The MySQL host backend hook library required for host storage.
                    "library": "libdhcp_mysql.so"
                },
                {
                    // The PostgreSQL host backend hook library required for host storage.
                    "library": "libdhcp_pgsql.so"
                }
            ],

            // List of access credentials to external sources of IPv6 reservations,
            "hosts-databases": [
                {
                    // Name of the database to connect to.
                    "name": "keatest",

                    // Host on which the database resides.
                    "host": "localhost",

                    // Database password.
                    "password": "1234",

                    // Port on which the database is available.
                    "port": 3306,

                    // Type of database, e.g. "mysql", "postgresql".
                    "type": "mysql",

                    // Username to be used to access the database.
                    "user": "keatest",

                    // Read-only mode.
                    "readonly": false,

                    // The next entries are for OpenSSL support in MySQL.

                    // Trust anchor aka certificate authority file or directory.
                    "trust-anchor": "my-ca",

                    // Client certificate file name.
                    "cert-file": "my-cert",

                    // Private key file name.
                    "key-file": "my-key",

                    // Cipher list (see the OpenSSL ciphers command manual).
                    "cipher-list": "AES",

                    // Connection reconnect wait time.
                    // This parameter governs how long Kea waits before attempting
                    // to reconnect. Expressed in milliseconds. The default is 0
                    // (disabled) for MySQL and PostgreSQL.
                    "reconnect-wait-time": 3000,

                    // Connection maximum reconnect tries.
                    "max-reconnect-tries": 3,

                    // Action to take when connection recovery fails.
                    // Supported values: stop-retry-exit, serve-retry-exit,
                    // serve-retry-continue
                    "on-fail": "stop-retry-exit",

                    // Flag which indicates if the DB recovery should be attempted
                    // at server startup and on reconfiguration events.
                    "retry-on-startup": false,

                    // Connection connect timeout in seconds.
                    "connect-timeout": 100,

                    // Timeout of database read operations in seconds.
                    "read-timeout": 120,

                    // Timeout of database write operations in seconds.
                    "write-timeout": 180
                },
                {
                    // Name of the database to connect to.
                    "name": "keatest",

                    // Host on which the database resides.
                    "host": "localhost",

                    // Database password.
                    "password": "1234",

                    // Port on which the database is available.
                    "port": 5432,

                    // Type of database, e.g. "mysql", "postgresql".
                    "type": "postgresql",

                    // Username to be used to access the database.
                    "user": "keatest",

                    // TCP user timeout while communicating with the database.
                    // It is specified in seconds.
                    "tcp-user-timeout": 100,

                    // Trust anchor aka certificate authority file or directory.
                    "trust-anchor": "my-ca",

                    // Client certificate file name.
                    "cert-file": "my-cert",

                    // Private key file name.
                    "key-file": "my-key",

                    // SSL mode.
                    "ssl-mode": "verify-ca"
                }
            ],

            // List of host reservation identifier types to be used by the
            // Kea DHCPv6 server to fetch static reservations for
            // DHCP clients. All identifiers are used by default, which
            // means that the server will issue multiple queries to the
            // database to find if there is a reservation for a particular
            // client. If a particular deployment uses only a subset, e.g.
            // one identifier type, this identifier should be only listed
            // here to prevent unnecessary queries to the database.
            "host-reservation-identifiers": [
                "hw-address",
                "duid",
                "flex-id"
            ],

            // Specifies configuration of interfaces on which the Kea DHCPv6
            // server is listening to the DHCP queries.
            "interfaces-config": {
                // Specifies a list of interfaces on which the Kea DHCPv6
                // server should listen to DHCP requests.
                "interfaces": [
                    "eth0"
                ],

                // Boolean flag indicating whether the available interfaces should
                // be re-detected upon server reconfiguration. The default value
                // is true, which means that the interfaces are always
                // re-detected.
                "re-detect": true,

                // Kea tries to bind the service sockets during initialization, but it may
                // fail due to a port being already opened or a misconfiguration. Kea can
                // suppress these errors and only log them. This flag prevents starting
                // the DHCP server without binding all sockets. If unspecified, it
                // defaults to false.
                "service-sockets-require-all": true,

                // Kea tries to bind the service sockets during initialization. This
                // option specifies how many times binding to interface will be retried.
                // The default value is 0, which means that the operation will not be
                // repeated.
                "service-sockets-max-retries": 5,

                // The time interval in milliseconds to wait before the next attempt to
                // retry opening a service socket.
                "service-sockets-retry-wait-time": 5000
            },

            // Boolean parameter which controls whether an early global host
            // reservations lookup should be performed. This lookup takes place
            // before subnet selection and when a global reservation is found
            // with some client classes, it triggers a second phase classification.
            // It can also be used to drop queries using host reservations as a
            // decision table indexed by reservation identifiers.
            "early-global-reservations-lookup": true,

            // Boolean parameter which controls the DHCP server's behavior with respect
            // to creating host reservations for the same IP address or delegated
            // prefix. By default this flag is set to true in which case the server
            // prevents creation of multiple host reservations for the same IP address
            // or delegated prefix. When this parameter is set to false, the server
            // allows for creating multiple reservations for the same IP address or
            // delegated prefix within a subnet. This setting is useful in deployments
            // in which a given host may be communicating with a DHCP server over
            // multiple interfaces and depending on the chosen interface different
            // MAC address (or other identifier) will be used to identify the host.
            // Note that some host backends do not support the mode in which multiple
            // reservations for the same IP address or delegated prefix are used.
            // If these backends are in use and this setting is attempted a
            // configuration error will occur. The MySQL and PostgreSQL backends do
            // support this mode.
            "ip-reservations-unique": true,

            // Boolean parameter which controls whether host reservations lookup
            // should be performed before lease lookup. This parameter has effect
            // only when multi-threading is disabled. When multi-threading is
            // enabled, host reservations lookup is always performed first to avoid
            // lease-lookup resource locking.
            "reservations-lookup-first": true,

            // Specifies credentials to access lease database.
            "lease-database": {
                // memfile backend-specific parameter specifying the interval
                // in seconds at which the lease file should be cleaned up (outdated
                // lease entries are removed to prevent the lease file from growing
                // infinitely).
                "lfc-interval": 3600,

                // Maximum number of lease-file read errors allowed before
                // loading the file is abandoned. Defaults to 0 (no limit).
                "max-row-errors": 100,

                // Name of the lease file. In the case of a database it specifies the
                // database name.
                "name": "kea-leases6.csv",

                // memfile-specific parameter indicating whether leases should
                // be saved on persistent storage (disk) or not. The true value
                // is the default and it indicates that leases are stored in
                // persistent storage. This setting must be used in production.
                // The false value should only be used for testing purposes
                // because non-stored leases will be lost upon Kea server restart.
                "persist": true,

                // Lease database backend type, i.e. "memfile", "mysql" or
                // "postgresql".
                "type": "memfile"
            },

            // List of parameters indicating how the client's MAC address can be
            // inferred from the DHCP query. Supported values are listed in the
            // Kea Administrator Reference Manual.
            "mac-sources": [ "duid" ],

            // List of global DHCP options that the Kea DHCPv6 server assigns to
            // clients.
            "option-data": [
                {
                    // Boolean flag indicating whether the given option is always
                    // sent in response or only when requested. The default
                    // value of false indicates that it is only sent when
                    // requested.
                    "always-send": false,

                    // An optional list of classes for which this option applies.
                    // If the the client matches any of the classes in this list the
                    // option will be applied. If the list is empty or is
                    // omitted this option will be applied regardless of class
                    // membership.
                    "client-classes": [ "class1", "class2" ],

                    // Option code. It is not required if the option name is
                    // provided.
                    "code": 23,

                    // Boolean value indicating whether the option data specified
                    // in the "data" field is specified as a string of hexadecimal
                    // digits or in human-readable CSV format.
                    "csv-format": true,

                    // Option data to be stored in the option payload.
                    "data": "2001:db8:2::45, 2001:db8:2::100",

                    // Option name. It is not required if the option code is
                    // provided.
                    "name": "dns-servers",

                    // Boolean flag indicating whether the given option is never
                    // sent in response. The default value of false indicates
                    // that it is sent when it should be. When true, the option
                    // is not sent despite any other setting, i.e. it is
                    // a final flag.
                    "never-send": false,

                    // Option space. The default is the "dhcp6" option space which
                    // groups top-level DHCPv6 options.
                    "space": "dhcp6"
                }
            ],

            // List of global option definitions, i.e. option formats, that the
            // Kea DHCPv6 server is using.
            "option-def": [
                {
                    // Boolean flag indicating whether the option definition comprises
                    // an array of values of some type, e.g. an array of IPv6 addresses.
                    // The default value of false means that the option does not
                    // comprise an array of values.
                    "array": false,

                    // Option code.
                    "code": 6,

                    // Holds a name of the option space encapsulated by this option.
                    // All options that belong to this option space will be sent
                    // as sub-options of this option. An empty string means that this
                    // option doesn't encapsulate any option.
                    "encapsulate": "",

                    // Option name.
                    "name": "my-option",

                    // Specifies the types of fields within the option if the option
                    // is said to be a "record" (see "type"). In this particular example
                    // this option comprises two fields, 1 byte and 2 bytes long.
                    "record-types": "uint8, uint16",

                    // Name of the option space to which this option belongs.
                    "space": "my-space",

                    // Option type. All possible types are listed in the Kea
                    // Administrator Reference Manual.
                    "type": "record"
                }
            ],

            // Global value which limits the number of client packets (e.g.
            // REQUESTs,RENEWs...) that may be parked while waiting for
            // hook library work to complete, prior to a response (e.g. REPLY)
            // being sent back to the client. A typical example is when kea-dhcp6
            // parks a REQUEST while it sends the lease update(s) to its
            // HA peer(s). The packet is unparked once the update(s) have been
            // acknowledged.  This value limits the number of packets that can
            // be held pending the updates. In times of heavy client traffic,
            // this value can keep kea-dhcp6 from building an insurmountable
            // backlog of updates.
            "parked-packet-limit": 256,

            // Global (default) value of the preferred lifetime.
            "preferred-lifetime": 50,

            // Global min value of the preferred lifetime.
            "min-preferred-lifetime": 40,

            // Global max value of the preferred lifetime.
            "max-preferred-lifetime": 60,

            // Global value for the rebind timer, i.e. the time after which the
            // DHCP client enters the rebind state if it fails to renew the lease.
            "rebind-timer": 40,

            // List of relay supplied option codes. See RFC 6422.
            "relay-supplied-options": [ "110", "120", "130" ],

            // Global value for the renew timer, i.e. the time after which the
            // DHCP client renews the lease.
            "renew-timer": 30,

            // Global value to store extended information (e.g. relay agent
            // information) with each lease.
            "store-extended-info": true,

            // Statistics keep some samples per observation point.
            // There are two default values: maximum count and maximum age.
            // Setting the maximum count to zero disables it.
            "statistic-default-sample-count": 0,

            // When the maximum count is 0 the maximum age (in seconds) applies.
            "statistic-default-sample-age": 60,

            // Multi-threading parameters.
            "multi-threading": {
                // By default, Kea processes packets on multiple threads if the hardware permits.
                "enable-multi-threading": true,

                // When multi-threading is enabled, Kea will process packets on a
                // number of multiple threads configurable through this option. The
                // value must be a positive integer (0 means auto-detect).
                "thread-pool-size": 0,

                // When multi-threading is enabled, Kea will read packets from the
                // interface and append a working item to the thread pool. This
                // option configures the maximum number of items that can be queued.
                // The value must be a positive integer (0 means unlimited).
                "packet-queue-size": 0
            },

            // Governs how the Kea DHCPv6 server should deal with invalid
            // data received from the client.
            "sanity-checks": {
                // Specifies how the Kea DHCPv6 server should behave when invalid
                // data is read for a lease from the lease file. The following
                // values are supported: "none" (don't attempt to correct the
                // lease information), "warn" (print a warning for subnet-id
                // related inconsistencies), "fix" (correct the subnet id by
                // trying to find the suitable subnet), "fix-del" (similar
                // to "fix" but delete the lease if no suitable subnet found),
                // "del" (delete the lease if the lease has invalid subnet
                // identifier value).
                "lease-checks": "warn",

                // Specifies how Kea DHCPv4 server should behave when invalid
                // extended info is read for a lease from the lease file, or
                // whether to upgrade from the old format. The following values
                // are supported: "none" (don't attempt to correct or upgrade
                // the extended info), "fix" (fix common inconsistencies and
                // upgrade from the old format; this is the default), "strict"
                // (fix inconsistencies with an impact on Leasequery),
                // "pedantic" (enforce full Kea code format).
                "extended-info-checks": "fix"
            },

            // Custom DUID used by the DHCPv6 server.
            "server-id": {
                // Type of the DUID. Possible values are "LLT", "EN", and "LL".
                "type": "EN",

                // Enterprise id used for "EN" duid.
                "enterprise-id": 2495,

                // Identifier part of the DUID.
                "identifier": "0123456789",

                // Boolean flag indicating whether the DUID should be persisted on
                // disk.
                "persist": false
            },

            // List of shared networks used by the Kea DHCPv6 server. The shared
            // networks group subnets together.
            "shared-networks": [
                {
                    // A flag selecting an IP address allocation strategy for all
                    // subnets in this shared network.
                    "allocator": "random",

                    // A flag selecting a delegated prefix allocation strategy for
                    // all subnets in this shared network.
                    "pd-allocator": "iterative",

                    // Restricts this shared network to allow only clients
                    // that belong to at least one class in this list. If omitted
                    // or an empty list is provided, no restriction is applied.
                    "client-classes": [],

                    // Shared-network level value. See description at the global level.
                    "ddns-generated-prefix": "myhost",

                    // Shared-network level value. See description at the global level.
                    "ddns-override-client-update": false,

                    // Shared-network level value. See description at the global level.
                    "ddns-override-no-update": false,

                    // Shared-network level value. See description at the global level.
                    "ddns-qualifying-suffix": "",

                    // Shared-network level value. See description at the global level.
                    "ddns-replace-client-name": "never",

                    // Shared-network level value. See description at the global level.
                    "ddns-send-updates": true,

                    // Shared-network level value. See description at the global level.
                    "ddns-update-on-renew": true,

                    // Shared-network level value. See description at the global level.
                    // This field has been replaced by ddns-conflict-resolution-mode.
                    // Parsing is maintained only for backwards compatibility.
                    // "ddns-use-conflict-resolution": true,

                    // Shared-network level value. See description at the global level.
                    "ddns-conflict-resolution-mode": "check-with-dhcid",

                    // Shared-network level value. See description at the global level.
                    "ddns-ttl-percent": 0.65,

                    // Shared-network level value. See description at the global level.
                    // Cannot specify both ddns-ttl and any of ddns-ttl-percent, ddns-ttl-min or
                    // ddns-ttl-max. They are mutually exclusive.
                    // "ddns-ttl": 500,

                    // Shared-network level value. See description at the global level.
                    "ddns-ttl-min": 10000,

                    // Shared-network level value. See description at the global level.
                    "ddns-ttl-max": 20000,

                    // Shared-network level value. See description at the global level.
                    "hostname-char-replacement": "x",

                    // Shared-network level value. See description at the global level.
                    "hostname-char-set": "[^A-Za-z0-9.-]",

                    // Specifies that this shared network is selected for
                    // requests received on a particular interface.
                    "interface": "eth0",

                    // Specifies the content of the interface-id option used
                    // by relays to identify the interface on the relay to
                    // which the response is sent.
                    "interface-id": "",

                    // Shared network name.
                    "name": "my-secret-network",

                    // List of shared network-specific DHCP options.
                    "option-data": [],

                    // Shared network-specific (default) preferred lifetime.
                    "preferred-lifetime": 2000,

                    // Shared network-specific min preferred lifetime.
                    "min-preferred-lifetime": 1500,

                    // Shared network-specific ma xpreferred lifetime.
                    "max-preferred-lifetime": 2500,

                    // Boolean flag indicating whether the server can respond to
                    // a Solicit message including a Rapid Commit option with
                    // the Reply message (See DHCPv6 rapid commit).
                    "rapid-commit": false,

                    // List of IPv6 relay addresses for which this shared
                    // network is selected.
                    "relay": {
                        "ip-addresses": []
                    },

                    // Shared-network level rebind timer.
                    "rebind-timer": 41,

                    // Shared-network level renew timer.
                    "renew-timer": 31,

                    // Shared-network level compute T1 and T2 timers.
                    "calculate-tee-times": true,

                    // T1 = valid lifetime * .5.
                    "t1-percent": .5,

                    // T2 = valid lifetime * .75.
                    "t2-percent": .75,

                    // Cache threshold = valid lifetime * .25.
                    "cache-threshold": .25,

                    // Cache maximum: when the client last-transmission time
                    // is close enough, the lease is not renewed and the current
                    // lease is returned as it was "cached".
                    "cache-max-age": 1000,

                    // Adaptive lease time threshold (1.0 is disabled).
                    "adaptive-lease-time-threshold": 0.8,

                    // Specify whether the server should look up global reservations.
                    "reservations-global": false,

                    // Specify whether the server should look up in-subnet reservations.
                    "reservations-in-subnet": true,

                    // Specify whether the server can assume that all reserved addresses
                    // are out-of-pool.
                    // Ignored when reservations-in-subnet is false.
                    // If specified, it is inherited by "subnet6" levels.
                    "reservations-out-of-pool": false,

                    // List of client classes which must be evaluated when this shared
                    // network is selected for client assignments.
                    "evaluate-additional-classes": [ "late" ],

                    // Turn off storage of extended information (e.g. relay agent
                    // information) with each lease for this shared network.
                    "store-extended-info": false,

                    // List of IPv6 subnets belonging to this shared network.
                    "subnet6": [
                        {
                            // A flag selecting an IP address allocation strategy for
                            // the subnet.
                            "allocator": "iterative",

                            // A flag selecting a delegated prefix allocation strategy
                            // for the subnet.
                            "pd-allocator": "iterative",

                            // Restricts this subnet to allow only clients
                            // that belong to at least one class in this list. If omitted
                            // or an empty list is provided, no restriction is applied.
                            "client-classes": [],

                            // Subnet-level value. See description at the global level.
                            "ddns-generated-prefix": "myhost",

                            // Subnet-level value. See description at the global level.
                            "ddns-override-client-update": false,

                            // Subnet-level value. See description at the global level.
                            "ddns-override-no-update": false,

                            // Subnet-level value. See description at the global level.
                            "ddns-qualifying-suffix": "",

                            // Subnet-level value. See description at the global level.
                            "ddns-replace-client-name": "never",

                            // Subnet-level value. See description at the global level.
                            "ddns-send-updates": true,

                            // Subnet-level value. See description at the global level.
                            "ddns-update-on-renew": true,

                            // Subnet-level value. See description at the global level.
                            // This field has been replaced by ddns-conflict-resolution-mode.
                            // Parsing is maintained only for backwards compatibility.
                            // "ddns-use-conflict-resolution": true,

                            // Subnet-level value. See description at the global level.
                            "ddns-conflict-resolution-mode": "check-with-dhcid",

                            // Subnet-level value. See description at the global level.
                            // "ddns-ttl-percent": 0.55,

                            // "ddns-ttl": 0,
                            // Cannot specify both ddns-ttl and any of ddns-ttl-percent, ddns-ttl-min or
                            // ddns-ttl-max. They are mutually exclusive.
                            "ddns-ttl": 500,

                            // Subnet-level value. See description at the global level.
                            // "ddns-ttl-min": 10000,

                            // Subnet-level value. See description at the global level.
                            // "ddns-ttl-max": 20000,

                            // Subnet-level value. See description at the global level.
                            "hostname-char-replacement": "x",

                            // Subnet-level value. See description at the global level.
                            "hostname-char-set": "[^A-Za-z0-9.-]",

                            // Subnet unique identifier.
                            "id": 1,

                            // Specifies that this subnet is selected for requests
                            // received on a particular interface.
                            "interface": "eth0",

                            // Specifies the content of the interface-id option used
                            // by relays to identify the interface on the relay to
                            // which the response is sent.
                            "interface-id": "",

                            // Turn on storage of extended information (e.g. relay agent
                            // information) with each lease for this subnet.
                            "store-extended-info": true,

                            // Subnet-level list of DHCP options.
                            "option-data": [
                                {
                                    // Boolean flag indicating whether the particular option
                                    // should be always sent or sent only when requested.
                                    "always-send": false,

                                    // An optional list of classes for which this option applies.
                                    // If the the client matches any of the classes in this list the
                                    // option will be applied. If the list is empty or is
                                    // omitted this option will be applied regardless of class
                                    // membership.
                                    "client-classes": [],

                                    // Option code.
                                    "code": 7,

                                    // Boolean flag indicating whether the option value specified
                                    // in "data" is a string of hexadecimal values or human-readable
                                    // CSV value.
                                    "csv-format": false,

                                    // Option data to be included in the option payload.
                                    "data": "0xf0",

                                    // Option name.
                                    "name": "preference",

                                    // Boolean flag indicating whether the given option is never
                                    // sent in response.
                                    "never-send": false,

                                    // Option space. The default value "dhcp6" designates the
                                    // top level option space.
                                    "space": "dhcp6"
                                }
                            ],

                            // List of pools from which delegated prefixes are assigned to the
                            // clients.
                            "pd-pools": [
                                {
                                    // Restricts this prefix pool subnet to allow only clients
                                    // that belong to at least one class in this list. If omitted
                                    // or an empty list is provided, no restriction is applied.
                                    "client-classes": [ "phones_server1" ],

                                    // Length of prefixes delegated to clients.
                                    "delegated-len": 64,

                                    // Excluded prefix (address) from client assignments.
                                    "excluded-prefix": "2001:db8:1::",

                                    // Excluded prefix (length) from client assignments.
                                    "excluded-prefix-len": 72,

                                    // Prefix pool level list of DHCP options.
                                    "option-data": [],

                                    // Prefix range (address) used for client assignments.
                                    "prefix": "2001:db8:1::",

                                    // Prefix range (length) used for client assignments.
                                    "prefix-len": 48,

                                    // List of client classes which must be evaluated
                                    // when this prefix pool is selected for client assignments.
                                    "evaluate-additional-classes": [],

                                    // PD-pool identifier used to enable statistics for this pd-pool.
                                    // The pd-pool ID does not need to be unique within the subnet
                                    // or across subnets.
                                    // If not unconfigured, it defaults to 0. The statistics
                                    // regarding this pd-pool will be combined with the other statistics
                                    // of all other pd-pools with the same pd-pool ID in this subnet.
                                    "pool-id": 1
                                },
                                {
                                    // Length of prefixes delegated to clients.
                                    "delegated-len": 64,

                                    // Prefix range (address) used for client assignments.
                                    "prefix": "2001:db8:2::",

                                    // Prefix range (length) used for client assignments.
                                    "prefix-len": 48
                                }
                            ],

                            // List of IP address pools belonging to the subnet.
                            "pools": [
                                {
                                    // Restricts this pool subnet to allow only clients
                                    // that belong to at least one class in this list. If omitted
                                    // or an empty list is provided, no restriction is applied.
                                    "client-classes": [ "phones_server1" ],

                                    // Pool-level list of DHCP options.
                                    "option-data": [],

                                    // Address range used for client assignments.
                                    "pool": "2001:db8:0:1::/64",

                                    // List of client classes which must be evaluated when this pool
                                    // is selected for client assignments.
                                    "evaluate-additional-classes": [ "late" ],

                                    // Pool-level value. See description at the global level.
                                    "ddns-generated-prefix": "mypool",

                                    // Pool-level value. See description at the global level.
                                    "ddns-override-client-update": false,

                                    // Pool-level value. See description at the global level.
                                    "ddns-override-no-update": false,

                                    // Pool-level value. See description at the global level.
                                    "ddns-qualifying-suffix": "pool.example.com.",

                                    // Pool-level value. See description at the global level.
                                    "ddns-replace-client-name": "always",

                                    // Pool-level value. See description at the global level.
                                    "ddns-send-updates": true,

                                    // Pool-level value. See description at the global level.
                                    "ddns-update-on-renew": false,

                                    // Pool-level value. See description at the global level.
                                    "ddns-conflict-resolution-mode": "check-with-dhcid",

                                    // Pool-level value. See description at the global level.
                                    "ddns-ttl-percent": 0.55,

                                    // Pool-level value. See description at the global level.
                                    // You cannot specify both ddns-ttl and any of ddns-ttl-percent,
                                    // ddns-ttl-min, or ddns-ttl-max. They are mutually exclusive.
                                    // "ddns-ttl": 500,

                                    // Pool-level value. See description at the global level.
                                    "ddns-ttl-min": 10000,

                                    // Pool-level value. See description at the global level.
                                    "ddns-ttl-max": 20000,

                                    // Pool-level value. See description at the global level.
                                    "hostname-char-replacement": "x",

                                    // Pool-level value. See description at the global level.
                                    "hostname-char-set": "[^A-Za-z0-9.-]"
                                },
                                {
                                    // Restricts this pool subnet to allow only clients
                                    // that belong to at least one class in this list. If omitted
                                    // or an empty list is provided, no restriction is applied.
                                    "client-classes": [ "phones_server2" ],

                                    // Pool-level list of DHCP options.
                                    "option-data": [],

                                    // Address range used for client assignments.
                                    "pool": "2001:db8:0:3::/64",

                                    // List of client classes which must be evaluated when this pool
                                    // is selected for client assignments.
                                    "evaluate-additional-classes": [],

                                    // Pool identifier used to enable statistics for this pool.
                                    // The pool ID does not need to be unique within the subnet
                                    // or across subnets.
                                    // If not unconfigured, it defaults to 0. The statistics
                                    // regarding this pool will be combined with the other statistics
                                    // of all other pools with the same pool ID in this subnet.
                                    "pool-id": 1
                                }
                            ],

                            // Subnet specific (default) preferred lifetime.
                            "preferred-lifetime": 2000,

                            // Subnet specific min preferred lifetime.
                            "min-preferred-lifetime": 1500,

                            // Subnet specific max referred lifetime.
                            "max-preferred-lifetime": 2500,

                            // Boolean flag indicating whether the server can respond to
                            // a Solicit message including a Rapid Commit option with
                            // the Reply message (See DHCPv6 rapid commit).
                            "rapid-commit": false,

                            // Subnet-level value of the rebind timer.
                            "rebind-timer": 40,

                            // List of IPv6 relay addresses for which this subnet is selected.
                            "relay": {
                                "ip-addresses": [
                                    "2001:db8:0:f::1"
                                ]
                            },

                            // Subnet-level renew timer.
                            "renew-timer": 30,

                            // Specify whether the server should look up global reservations.
                            "reservations-global": false,

                            // Specify whether the server should look up in-subnet reservations.
                            "reservations-in-subnet": true,

                            // Specify whether the server can assume that all reserved
                            // addresses are out-of-pool.
                            // Ignored when reservations-in-subnet is false.
                            "reservations-out-of-pool": false,

                            // Subnet-level compute T1 and T2 timers.
                            "calculate-tee-times": true,

                            // T1 = valid lifetime * .5.
                            "t1-percent": .5,

                            // T2 = valid lifetime * .75.
                            "t2-percent": .75,

                            // Cache threshold = valid lifetime * .25.
                            "cache-threshold": .25,

                            // Subnet-level cache maximum.
                            "cache-max-age": 1000,

                            // Adaptive lease time threshold (1.0 is disabled).
                            "adaptive-lease-time-threshold": 0.8,

                            // List of static IPv6 reservations assigned to clients belonging
                            // to this subnet. For a detailed example, see reservations.json.
                            "reservations": [
                                {
                                    // Identifier used for client matching. Supported values are
                                    // "duid", "hw-address" and "flex-id".
                                    "duid": "01:02:03:04:05:06:07:08:09:0A",

                                    // List of reserved IPv6 addresses.
                                    "ip-addresses": [ "2001:db8:1:cafe::1" ],

                                    // List of reserved IPv6 prefixes.
                                    "prefixes": [ "2001:db8:2:abcd::/64" ],

                                    // List of excluded IPv6 prefixes.
                                    "excluded-prefixes": [ "2001:db8:2:abcd:1::/80" ],

                                    // Reserved hostname.
                                    "hostname": "foo.example.com",

                                    // Reservation-specific option data.
                                    "option-data": [
                                        {
                                            // Option name.
                                            "name": "vendor-opts",

                                            // Option value.
                                            "data": "4491"
                                        }
                                    ]
                                }
                            ],

                            // List of client classes which must be evaluated when this subnet
                            // is selected for client assignments.
                            "evaluate-additional-classes": [ "late" ],

                            // Subnet prefix.
                            "subnet": "2001:db8::/32",

                            // Subnet-level (default) valid lifetime.
                            "valid-lifetime": 6000,

                            // Subnet-level min valid lifetime.
                            "min-valid-lifetime": 4000,

                            // Subnet-level max valid lifetime.
                            "max-valid-lifetime": 8000
                        }
                    ],

                    // Shared-network level (default) valid lifetime.
                    "valid-lifetime": 6001,

                    // Shared-network level min valid lifetime.
                    "min-valid-lifetime": 4001,

                    // Shared-network level max valid lifetime.
                    "max-valid-lifetime": 8001
                }
            ],

            // List of IPv6 subnets which don't belong to any shared network.
            "subnet6": [],

            // Global valid lifetime value.
            "valid-lifetime": 6000,

            // Global min valid lifetime value.
            "min-valid-lifetime": 4000,

            // Global max valid lifetime value.
            "max-valid-lifetime": 8000,

            // Reservations (examples are in other files).
            "reservations": [],

            // Configuration control (currently not used, i.e. this syntax
            // is already defined but the corresponding feature is not implemented).
            "config-control": {
                // Only the configuration databases entry is defined.
                "config-databases": [
                    {
                        // Name of the database to connect to.
                        "name": "config",

                        // Type of database, e.g. "mysql", "postgresql".
                        "type": "mysql"
                    }
                ],
                // Interval between attempts to fetch configuration updates
                // via the configuration backends used.
                "config-fetch-wait-time": 30
            },

            // Server tag.
            "server-tag": "my DHCPv6 server",

            // DHCP queue-control parameters.
            "dhcp-queue-control": {
                // Enable queue is mandatory.
                "enable-queue": true,

                // Queue type is mandatory.
                "queue-type": "kea-ring6",

                // Capacity is optional.
                "capacity": 64
            },

            // Specify whether the server should look up global reservations.
            "reservations-global": false,

            // Specify whether the server should look up in-subnet reservations.
            "reservations-in-subnet": true,

            // Specify whether the server can assume that all reserved addresses
            // are out-of-pool.
            // Ignored when reservations-in-subnet is false.
            // If specified, it is inherited by "shared-networks" and
            // "subnet6" levels.
            "reservations-out-of-pool": false,

            // Global compute T1 and T2 timers.
            "calculate-tee-times": true,

            // T1 = valid lifetime * .5.
            "t1-percent": .5,

            // T2 = valid lifetime * .75.
            "t2-percent": .75,

            // Cache threshold = valid lifetime * .25.
            "cache-threshold": .25,

            // Global cache maximum.
            "cache-max-age": 1000,

            // Adaptive lease time threshold (1.0 is disabled)
            "adaptive-lease-time-threshold": 0.8,

            // String of zero or more characters with which to replace each
            // invalid character in the Client FQDN. The default
            // value is an empty string, which will cause invalid characters
            // to be omitted rather than replaced.
            "hostname-char-replacement": "x",

            // Regular expression describing the invalid character set in
            // the Client FQDN.
            "hostname-char-set": "[^A-Za-z0-9.-]",

            // List of loggers used by the servers using this configuration file.
            "loggers": [
                {
                    // Debug level, a value between 0..99. The greater the value
                    // the more detailed the debug log.
                    "debuglevel": 99,

                    // Name of the logger.
                    "name": "kea-dhcp6",

                    // Configures how the log should be output.
                    "output-options": [
                        {
                            // Determines whether the log should be flushed to a file.
                            "flush": true,

                            // Specifies maximum filesize before the file is rotated.
                            "maxsize": 10240000,

                            // Specifies the maximum number of rotated files to be kept.
                            "maxver": 1,

                            // Specifies the logging destination.
                            "output": "stdout",

                            // Specifies log entry content
                            "pattern": "%D{%Y-%m-%d %H:%M:%S.%q} %-5p [%c/%i] %m\n"
                        }
                    ],

                    // Specifies logging severity, i.e. "ERROR", "WARN", "INFO", "DEBUG".
                    "severity": "INFO"
                }
            ],

            // Look at advanced examples for the use of user-contexts.
            "user-context": { }
        }
    }

.. _config-example-kea6-all-options-json:

---------------------
kea6/all-options.json
---------------------

.. code-block::
    :linenos:

    // This example configuration file for DHCPv6 server in Kea contains:
    //
    // - data for all the standard options
    // - custom option definitions at global level along with some associated
    // option data
    // - custom option data with standardized option spaces other than "dhcp6"
    // - custom option spaces
    // - option embedding examples
    // - DOCSIS3 option data
    //
    // The reader is strongly encouraged to take a look at the option formats
    // documented in the Kea ARM:
    // https://kea.readthedocs.io/en/latest/arm/dhcp6-srv.html?highlight=option%20definitions#dhcp6-std-options-list
    //
    // Other options require special logic which is not yet implemented. They are
    // marked with:
    // "Note: special logic not implemented"

    {
      "Dhcp6": {
        /*
                          Data for all standard option definitions
        */
        // Option data defined globally
        "option-data": [
          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |       OPTION_PREFERENCE       |          option-len           |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |  pref-value   |
          +-+-+-+-+-+-+-+-+

          option-code   OPTION_PREFERENCE (7).

          option-len    1.

          pref-value    The preference value for the server in this message.
          */
          // Type: uint8
          {
            "code": 7,
            "data": "0xf0",
            "name": "preference"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |          OPTION_UNICAST       |        option-len             |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          |                       server-address                          |
          |                                                               |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code     OPTION_UNICAST (12).

          option-len      16.

          server-address  The IP address to which the client should send
                          messages delivered using unicast.

          ***NOTE***: this option was deprecated by RFC9915.
          */
          // Type: IPv6 address
          {
            "code": 12,
            "data": "2001:db8::2",
            "name": "unicast"
          },

          /*
          0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      OPTION_VENDOR_OPTS       |           option-len          |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                       enterprise-number                       |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          .                                                               .
          .                          option-data                          .
          .                                                               .
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code          OPTION_VENDOR_OPTS (17)

          option-len           4 + length of option-data field

          enterprise-number    The vendor's registered Enterprise Number as
                               registered with IANA [6].

          option-data          An opaque object of option-len octets,
                               interpreted by vendor-specific code on the
                               clients and servers
          */
          // Type: uint32
          // The vendor options are not standardized and are specific to each
          // vendor. The vendors are identified with the enterprise number,
          // sometimes also called vendor-id or enterprise-id. For example,
          // CableLabs that specified DOCSIS options, use 4491. Some vendors
          // have their own mechanisms. For example, DOCSIS vendor sub-option 1
          // is an equivalent of ORO for normal DHCPv6 options. Usually there
          // are several vendor sub-options defined within. See the ARM section:
          // https://kea.readthedocs.io/en/latest/arm/dhcp6-srv.html#dhcpv6-vendor-specific-options

          {
            "code": 17,
            "data": "4294967295",
            "name": "vendor-opts"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |     OPTION_RECONF_ACCEPT      |               0               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code   OPTION_RECONF_ACCEPT (20).

          option-len    0.
          */
          // Type: empty
          {
            "code": 20,
            "name": "reconf-accept"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      OPTION_SIP_SERVER_D      |         option-length         |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                 SIP Server Domain Name List                   |
          |                              ...                              |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          SIP Server Domain Name List: The domain names of the SIP outbound
          proxy servers for the client to use.  The domain names are encoded
          as specified in Section 8 ("Representation and use of domain
          names") of the DHCPv6 specification [1].
          */
          // Type: array of {FQDN}
          {
            "code": 21,
            "data": "sip1.server.net, sip2.server.net",
            "name": "sip-server-dns"
          },

          /*
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      OPTION_SIP_SERVER_A      |           option-len          |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          |                   SIP server (IP address)                     |
          |                                                               |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          |                   SIP server (IP address)                     |
          |                                                               |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                              ...                              |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code: OPTION_SIP_SERVER_A (22)

          option-length: Length of the 'options' field in octets; must be a
          multiple of 16.

          SIP server: IPv6 address of a SIP server for the client to use.
                      The servers are listed in the order of preference for
                      use by the client.
          */
          // Type: array of {IPv6 address}
          {
            "code": 22,
            "data": "2001:db8::3, 2001:db8::4",
            "name": "sip-server-addr"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      OPTION_DNS_SERVERS       |         option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          |            DNS-recursive-name-server (IPv6 address)           |
          |                                                               |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          |            DNS-recursive-name-server (IPv6 address)           |
          |                                                               |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                              ...                              |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code:               OPTION_DNS_SERVERS (23)

          option-len:                Length of the list of DNS recursive name
                                     servers in octets; must be a multiple of
                                     16

          DNS-recursive-name-server: IPv6 address of DNS recursive name server
          */
          // Type: array of {IPv6 address}
          {
            "code": 23,
            "data": "2001:db8::5, 2001:db8::6",
            "name": "dns-servers"
          },


          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      OPTION_DOMAIN_LIST       |         option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                          searchlist                           |
          |                              ...                              |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code:  OPTION_DOMAIN_LIST (24)

          option-len:   Length of the 'searchlist' field in octets

          searchlist:   The specification of the list of domain names in the
                        Domain Search List
          */
          // Type: array of {FQDN}
          {
            "code": 24,
            "data": "example.com, example.org",
            "name": "domain-search"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      OPTION_NIS_SERVERS       |         option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          |                   NIS server (IPv6 address)                   |
          |                                                               |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          |                   NIS server (IPv6 address)                   |
          |                                                               |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                              ...                              |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code:  OPTION_NIS_SERVERS (27)

          option-len:   Length of the 'NIS server' fields in octets; It must be
                        a multiple of 16

          NIS server:   IPv6 address of NIS server
          */
          // Type: array of {IPv6 address}
          {
            "code": 27,
            "data": "2001:db8::7, 2001:db8::8",
            "name": "nis-servers"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      OPTION_NISP_SERVERS      |         option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          |                   NIS+ server (IPv6 address)                  |
          |                                                               |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          |                   NIS+ server (IPv6 address)                  |
          |                                                               |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                              ...                              |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code: OPTION_NISP_SERVERS (28)

          option-len:  Length of the 'NIS+ server' fields in octets; It must be
                       a multiple of 16

          NIS+ server: IPv6 address of NIS+ server
          */
          // Type: array of {IPv6 address}
          {
            "code": 28,
            "data": "2001:db8::9, 2001:db8::10",
            "name": "nisp-servers"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |    OPTION_NIS_DOMAIN_NAME     |         option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                       nis-domain-name                         |
          |                              ...                              |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code:      OPTION_NIS_DOMAIN_NAME (29)

          option-len:       Length of the 'nis-domain-name' field in octets

          nis-domain-name:  NIS Domain name for client
          */
          // Type: array of {FQDN}
          {
            "code": 29,
            "data": "nis1.example.org, nis2.example.org",
            "name": "nis-domain-name"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |    OPTION_NISP_DOMAIN_NAME    |         option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                       nisp-domain-name                        |
          |                              ...                              |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code:      OPTION_NISP_DOMAIN_NAME (30)

          option-len:       Length of the 'nisp-domain-name' field in octets

          nisp-domain-name: NIS+ Domain name for client
          */
          // Type: array of {FQDN}
          {
            "code": 30,
            "data": "nisp1.example.org, nisp2.example.org",
            "name": "nisp-domain-name"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      OPTION_SNTP_SERVERS       |        option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          |                  SNTP server (IPv6 address)                   |
          |                                                               |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          |                  SNTP server (IPv6 address)                   |
          |                                                               |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                              ...                              |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code: OPTION_SNTP_SERVERS (31)

          option-len:  Length of the 'SNTP server' fields, in octets;
                       it must be a multiple of 16

          SNTP server: IPv6 address of SNTP server
          */
          // Type: array of {IPv6 address}
          {
            "code": 31,
            "data": "2001:db8::11, 2001:db8::12",
            "name": "sntp-servers"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |OPTION_INFORMATION_REFRESH_TIME|         option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                   information-refresh-time                    |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code                OPTION_INFORMATION_REFRESH_TIME (32).

          option-len                 4.

          information-refresh-time   Time duration relative to the current
                                     time, expressed in units of seconds.  A
                                     4-octet field containing an unsigned
                                     integer.
          */
          // Type: uint32
          {
            "code": 32,
            "data": "3600",
            "name": "information-refresh-time"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      OPTION_BCMCS_SERVER_D    |         option-length         |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |          BCMCS Control Server Domain Name List                |
          |                              ...                              |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code: OPTION_BCMCS_SERVER_D (33).

          option-length: Length of the 'BCMCS Control Server Domain Name List'
          field in octets; variable.

          BCMCS Control Server Domain Name List: Identical format as in Section
          4.1 (except the Code and Len fields).
          */
          // Type: array of {FQDN}
          {
            "code": 33,
            "data": "bcmcs1.example.org, bcmcs2.example.org",
            "name": "bcmcs-server-dns"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      OPTION_BCMCS_SERVER_A    |         option-length         |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          |    BCMCS Control server-1 address (IPv6 address)              |
          |                                                               |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          |    BCMCS Control server-2 address (IPv6 address)              |
          |                                                               |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                              ...                              |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code: OPTION_BCMCS_SERVER_A (34).

          option-length: Length of the 'BCMCS Control Server IPv6 address'
          field in octets; variable.
          */
          // Type: array of {IPv6 address}
          {
            "code": 34,
            "data": "2001:db8::13, 2001:db8::14",
            "name": "bcmcs-server-addr"
          },

          // Option code 35 is unassigned.

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      OPTION_GEOCONF_CIVIC     |           option-len          |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      what     |        country code           |               .
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               .
          .                     civic address elements                    .
          .                              ...                              .
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code:  OPTION_GEOCONF_CIVIC (36)

          option-len:  Length of the Countrycode, 'what' and civic address
             elements in octets.

          what:  The 'what' element describes to which location the DHCP entry
             refers.  Currently, three options are defined: the location of the
             DHCP server (a value of 0), the location of the network element
             believed to be closest to the client (a value of 1), or the
             location of the client (a value of 2).  Option (2) SHOULD be used,
             but may not be known.  Options (0) and (1) SHOULD NOT be used
             unless it is known that the DHCP client is in close physical
             proximity to the server or network element.

          country code:  The two-letter ISO 3166 country code in capital ASCII
             letters, e.g., DE or US.  (Civic addresses always contain country
             designations, suggesting the use of a fixed-format field to save
             space.)

          civic address elements:  Zero or more elements comprising the civic
             and/or postal address, with the format described below
             (Section 3.3).
          */
          // Type: uint8, uint16, array of {binary}
          {
            "code": 36,
            // 0x5553 is "US" in UTF-8
            "data": "0, 0x5553, 15 9D, A3 FF",
            "name": "geoconf-civic"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |       OPTION_REMOTE_ID        |         option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                       enterprise-number                       |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          .                                                               .
          .                           remote-id                           .
          .                                                               .
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code        OPTION_REMOTE_ID (37)

          option-len         4 + the length, in octets, of the remote-id
                             field.  The minimum option-len is 5 octets.

          enterprise-number  The vendor's registered Enterprise Number as
                             registered with IANA [5].

          remote-id          The opaque value for the remote-id.
          */
          // Type: uint32, binary
          {
            "code": 37,
            "data": "4294967295, 1A BB AD AB BA D0 00 00 00 00 00 00 00 00 CA FE",
            "name": "remote-id"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |          OPTION_FQDN          |         option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |   flags       |                                               |
          +-+-+-+-+-+-+-+-+                                               |
          .                                                               .
          .                          domain-name                          .
          .                                                               .
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code      OPTION_CLIENT_FQDN (39)

          option-len       1 + length of domain name

          flags            flag bits used between client and server to
                           negotiate who performs which updates

          domain-name      the partial or fully qualified domain name
                           (with length option-len - 1)
          */
          // Type: uint8, FQDN
          {
            "code": 39,
            "data": "224, client.example.org",
            "name": "client-fqdn"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |       option-code             |       option-length           |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          +                                                               +
          |                                                               |
          +                         PAA IPv6 Address                      +
          |                                                               |
          +                                                               +
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                          ....                                 |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code:        OPTION_PANA_AGENT (40).

          option-length:      Length of the 'options' field in octets;
                              MUST be a multiple of sixteen (16).

          PAA IPv6 Address:   IPv6 address of a PAA for the client to use.
                              The PAAs are listed in the order of preference
                              for use by the client.
          */
          // Type: array of {IPv6 address}
          {
            "code": 40,
            "data": "2001:db8::15, 2001:db8::16",
            "name": "pana-agent"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |  OPTION_NEW_POSIX_TIMEZONE    |         option-length         |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                      TZ POSIX String                          |
          |                              ...                              |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code: OPTION_NEW_POSIX_TIMEZONE(41)

          option-length: the number of octets of the TZ POSIX String Index
          described below.
          */
          // Type: string
          {
            "code": 41,
            // String options that have a comma in their values need to have
            // it escaped (i.e. each comma is preceded by two backslashes).
            // That's because commas are reserved for separating fields in
            // compound options. At the same time, we need to be conformant
            // with JSON spec, that does not allow "\,". Therefore the
            // slightly uncommon double backslashes notation is needed.
            // The value sent over the wire is:
            // EST5EDT4,M3.2.0/02:00,M11.1.0/02:00
            "data": "EST5EDT4\\,M3.2.0/02:00\\,M11.1.0/02:00",
            "name": "new-posix-timezone"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |  OPTION_NEW_TZDB_TIMEZONE    |          option-length         |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                          TZ Name                              |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code: OPTION_NEW_TZDB_TIMEZONE(42)

          option-length: the number of octets of the TZ Database String Index
          described below.
          */
          // Type: string
          {
            "code": 42,
            "data": "Europe/Zurich",
            "name": "new-tzdb-timezone"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |           OPTION_ERO          |           option-len          |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |    requested-option-code-1    |    requested-option-code-2    |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                              ...                              |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code              OPTION_ERO (43).
          option-len               2 * number of requested options.
          requested-option-code-n  The option code for an option requested by
                                   the relay agent.
          */
          // Type: array of {uint16}
          {
            "code": 43,
            "data": "16, 32, 42",
            "name": "ero"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |        OPTION_LQ_QUERY        |         option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |   query-type  |                                               |
          +-+-+-+-+-+-+-+-+                                               |
          |                                                               |
          |                         link-address                          |
          |                                                               |
          |               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |               |                                               .
          +-+-+-+-+-+-+-+-+                                               .
          .                         query-options                         .
          .                                                               .
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code      OPTION_LQ_QUERY (44)

          option-len       17 + length of query-options field.

          link-address     A global address that will be used by the
                           server to identify the link to which the
                           query applies, or 0::0 if unspecified.

          query-type       The query requested (see below).

          query-options    The options related to the query.
          */
          // Note: special logic not implemented
          // Type: uint8, IPv6 address
          {
            "code": 44,
            "data": "1, 2001:db8::17",
            "name": "lq-query"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |       OPTION_CLIENT_DATA      |         option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          .                                                               .
          .                        client-options                         .
          .                                                               .
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code      OPTION_CLIENT_DATA (45)

          option-len       Length, in octets, of the encapsulated client-
                           options field.

          client-options   The options associated with this client.
          */
          // Note: special logic not implemented
          // Type: empty
          {
            "code": 45,
            "name": "client-data"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |        OPTION_CLT_TIME        |         option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                 client-last-transaction-time                  |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code      OPTION_CLT_TIME (46)

          option-len       4

          client-last-transaction-time
                           The number of seconds since the server last
                           communicated with the client (on that link).
          */
          // Note: special logic not implemented
          // Type: uint32
          {
            "code": 46,
            "data": "600",
            "name": "clt-time"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |     OPTION_LQ_RELAY_DATA      |         option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          |                  peer-address (IPv6 address)                  |
          |                                                               |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          |                       DHCP-relay-message                      |
          .                                                               .
          .                                                               .
          .                                                               .
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code      OPTION_LQ_RELAY_DATA (47)

          option-len       16 + length of DHCP-relay-message.

          peer-address     The address of the relay agent from which
                           the relayed message was received by the
                           server.

          DHCP-relay-message
                           The last complete relayed message, excluding
                           the client's message OPTION_RELAY_MSG,
                           received by the server.
          */
          // Note: special logic not implemented
          // Type: IPv6 address, binary
          {
            "code": 47,
            "data": "2001:db8::18, 1A BB AD AB BA D0 00 00 00 00 00 00 00 00 CA FE",
            "name": "lq-relay-data"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |     OPTION_LQ_CLIENT_LINK     |         option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          |                  link-address (IPv6 address)                  |
          |                                                               |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          |                  link-address (IPv6 address)                  |
          |                                                               |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                              ...                              |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code      OPTION_LQ_CLIENT_LINK (48)

          option-len       Length of the list of links in octets;
                           must be a multiple of 16.

          link-address     A global address used by the server to
                           identify the link on which the client is
                           located.
          */
          // Note: special logic not implemented
          // Type: array of {IPv6 address}
          {
            "code": 48,
            "data": "2001:db8::19, 2001:db8::20",
            "name": "lq-client-link"
          },

          // Option codes 49-50 are not defined in Kea.

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      OPTION_V6_LOST           |         option-length         |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                LoST Server Domain Name                        |
          |                              ...                              |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code: OPTION_V6_LOST (51)

          option-length: Length of the 'LoST Server Domain Name' field
               in octets; variable.

          LoST Server Domain Name: The domain name of the LoST
               server for the client to use.
          */
          // Type: FQDN
          {
            "code": 51,
            "data": "lost.example.org",
            "name": "v6-lost"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |       option-code             |       option-length           |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          +                                                               +
          |                                                               |
          +                          AC IPv6 Address                      +
          |                                                               |
          +                                                               +
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                          ....                                 |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code:   OPTION_CAPWAP_AC_V6 (52)

          option-length:   Length of the 'options' field in octets; MUST be a
             multiple of sixteen (16).

          AC IPv6 Address:  IPv6 address of a CAPWAP AC that the WTP may use.
             The ACs are listed in the order of preference for use by the WTP.
          */
          // Type: array of {IPv6 address}
          {
            "code": 52,
            "data": "2001:db8::21, 2001:db8::22",
            "name": "capwap-ac-v6"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |       OPTION_RELAY_ID         |          option-len           |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          .                                                               .
          .                              DUID                             .
          .                        (variable length)                      .
          .                                                               .
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code   OPTION_RELAY_ID.

          option-len    Length of DUID in octets.

          DUID          The DUID for the relay agent.
          */
          // Type: binary
          {
            "code": 53,
            "data": "1A BB AD AB BA D0 00 00 00 00 00 00 00 00 CA FE",
            "name": "relay-id"
          },

          // Option codes 54-56 are not defined in Kea.

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |    OPTION_V6_ACCESS_DOMAIN    |           Length              |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          .                  Access Network Domain Name                   .
          .                              ...                              .
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code:  OPTION_V6_ACCESS_DOMAIN (57).

          option-length:  The length of the entire access network domain name
             option in octets.

          option-value:  The domain name associated with the access network,
             encoded as described in Section 3.1.
          */
          // Type: FQDN
          {
            "code": 57,
            "data": "v6-access.example.org",
            "name": "v6-access-domain"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |     OPTION_SIP_UA_CS_LIST     |         option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                          searchlist                           |
          |                              ...                              |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code OPTION_SIP_UA_CS_LIST (58)

          option-len  Length of the 'searchlist' field in octets

          searchlist  The specification of the list of domain names in the SIP
                      User Agent Configuration Service Domains
          */
          // Type: array of {FQDN}
          {
            "code": 58,
            "data": "sip-ua1.example.org, sip-ua1.example.org",
            "name": "sip-ua-cs-list"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |       OPT_BOOTFILE_URL        |            option-len         |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          .                  boot-file-url (variable length)              .
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code       OPT_BOOTFILE_URL (59).

          option-len        Length of the boot-file-url in octets.

          boot-file-url     This string is the URL for the boot file.  It MUST
                            comply with STD 66 [RFC3986].  The string is not
                            NUL-terminated.
          */
          // Type: string
          {
            "code": 59,
            "data": "https://boot.example.org/pxe/os.img",
            "name": "bootfile-url"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |       OPT_BOOTFILE_PARAM      |            option-len         |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          | param-len 1                   |                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+           parameter 1         .
          .                                        (variable length)      |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          .                                                               .
          .                       <multiple Parameters>                   .
          .                                                               .
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          | param-len n                   |                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+           parameter n         .
          .                                        (variable length)      |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code       OPT_BOOTFILE_PARAM (60).

          option-len        Length of the Boot File Parameters option in octets
                            (not including the size of the option-code and
                            option-len fields).

          param-len 1...n   This is a 16-bit integer that specifies the length
                            of the following parameter in octets (not including
                            the parameter-length field).

          parameter 1...n   These UTF-8 strings are parameters needed for
                            booting, e.g., kernel parameters.  The strings are
                            not NUL-terminated.
          */
          // Type: array of {tuple}
          {
            "code": 60,
            "data": "root=/dev/sda2, quiet, splash",
            "name": "bootfile-param"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |    OPTION_CLIENT_ARCH_TYPE    |         option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          .                                                               .
          .             architecture-types (variable length)              .
          .                                                               .
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code         OPTION_CLIENT_ARCH_TYPE (61).

          option-len          Length of the "architecture-types" field in
                              octets.  It MUST be an even number greater than
                              zero.  See Section 2.1 of [RFC4578] for details.

          architecture-types  A list of one or more architecture types, as
                              specified in Section 2.1 of [RFC4578].  Each
                              architecture type identifier in this list is a
                              16-bit value that describes the pre-boot runtime
                              environment of the client machine.  A list of
                              valid values is maintained by the IANA (see
                              Section 6).
          */
          // Type: array of {uint16}
          {
            "code": 61,
            "data": "1, 3, 5, 7",
            "name": "client-arch-type"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |           OPTION_NII          |          option-len           |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |     Type      |     Major     |      Minor      |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code       OPTION_NII (62).

          option-len        3

          Type              As specified in Section 2.2 of [RFC4578].

          Major             As specified in Section 2.2 of [RFC4578].

          Minor             As specified in Section 2.2 of [RFC4578].
          */
          // Type: uint8, uint8, array of {uint8}
          {
            "code": 62,
            "data": "1, 2, 11, 13",
            "name": "nii"
          },

          // Option code 63 is not defined in Kea.

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-------------------------------+-------------------------------+
          |    OPTION_AFTR_NAME: 64       |          option-len           |
          +-------------------------------+-------------------------------+
          |                                                               |
          |                  tunnel-endpoint-name (FQDN)                  |
          |                                                               |
          +---------------------------------------------------------------+

          option-len: Length of the tunnel-endpoint-name field in
                      octets.

          tunnel-endpoint-name: A fully qualified domain name of the AFTR
                                tunnel endpoint
          */
          // Type: FQDN
          {
            "code": 64,
            "data": "aftr.example.org",
            "name": "aftr-name"
          },

          /*
          0                   1                   2                   3
          0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          | OPTION_ERP_LOCAL_DOMAIN_NAME|         option-length         |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          | erp-local-domain-name...
          +-+-+-+-+-+-+-+-+-+-+-+-+-

          option code
             OPTION_ERP_LOCAL_DOMAIN_NAME (65)

          option-length
             Length of the erp-local-domain-name field, in octets

          erp-local-domain-name
             This field contains the name of the local ERP domain and MUST be
             encoded as specified in Section 8 of RFC 3315 [RFC3315].  Note
             that this encoding does enable the use of internationalized domain
             names, but only as a set of A-labels [RFC5890].
          */
          // Type: FQDN
          {
            "code": 65,
            "data": "erp-local.example.org",
            "name": "erp-local-domain-name"
          },

          /*
          0                   1                   2                   3
          0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |         OPTION_RSOO         |         option-length         |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |         options...
          +-+-+-+-+-+-+-+-+-+-+-+

          OPTION_RSOO

             Relay-Supplied Options code (66).

          option-length

             Length of the RSOO.

          options

             One or more DHCPv6 options.
          */
          // Type: empty
          {
            "code": 66,
            "name": "rsoo"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |       OPTION_PD_EXCLUDE       |         option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |  prefix-len   | IPv6 subnet ID (1 to 16 octets)               ~
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                                  Prefix Exclude Option

          o  option-code: OPTION_PD_EXCLUDE (67).

          o  option-len: 1 + length of IPv6 subnet ID in octets.  A valid
             option-len is between 2 and 17.

          o  prefix-len: The length of the excluded prefix in bits.  The
             prefix-len MUST be between 'OPTION_IAPREFIX prefix-length'+1 and
             128.

          o  IPv6 subnet ID: A variable-length IPv6 subnet ID up to 128 bits.
          */
          // Type: binary
          {
            "code": 67,
            "data": "2001:db8:1:1::/64",
            "name": "pd-exclude"
          },

          // Option codes 68-73 are not defined in Kea.

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |    OPTION_RDNSS_SELECTION     |         option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          |            DNS-recursive-name-server (IPv6 address)           |
          |                                                               |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          | Reserved  |prf|                                               |
          +-+-+-+-+-+-+-+-+          Domains and networks                 |
          |                          (variable length)                    |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code:  OPTION_RDNSS_SELECTION (74)

          option-len:  Length of the option in octets

          DNS-recursive-name-server:  An IPv6 address of RDNSS

          Reserved:  Field reserved for the future.  MUST be set to zero and
                     MUST be ignored on receipt.

          prf:  RDNSS preference:

                01 High
                00 Medium
                11 Low
                10 Reserved

                Reserved preference value (10) MUST NOT be sent.  On receipt,
                the Reserved value MUST be treated as Medium preference (00).
          */
          // Type: IPv6 address, uint8, array of {FQDN}
          {
            "code": 74,
            "data": "2001:db8::23, 01, example.com, example.org",
            "name": "rdnss-selection"
          },

          // Option codes 75-78 are not defined in Kea.

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          | OPTION_CLIENT_LINKLAYER_ADDR  |           option-length       |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |   link-layer type (16 bits)   |                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
          |               link-layer address (variable length)            |
          |                                                               |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code:        OPTION_CLIENT_LINKLAYER_ADDR (79)
          option-length:      2 + length of link-layer address
          link-layer type:    Client link-layer address type.  The link-layer
                              type MUST be a valid hardware type assigned
                              by the IANA, as described in [RFC0826]
          link-layer address: Client link-layer address
          */
          // Type: binary
          {
            "code": 79,
            "data": "1A BB AD AB BA D0 00 00 00 00 00 00 00 00 CA FE",
            "name": "client-linklayer-addr"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |       OPTION_LINK_ADDRESS     |         option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          |                  link-address (IPv6 address)                  |
          |                                                               |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code: OPTION_LINK_ADDRESS (80)

          option-len: 16 (octets)

          link-address: An IPv6 address used by the server to identify the
          link on which the client is located.
          */
          // Type: IPv6 address
          {
            "code": 80,
            "data": "2001:db8::24",
            "name": "link-address"
          },

          // Option code 81 is not defined in Kea.

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      OPTION_SOL_MAX_RT        |         option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                       SOL_MAX_RT value                        |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code          OPTION_SOL_MAX_RT (82).

          option-len           4.

          SOL_MAX_RT value     Overriding value for SOL_MAX_RT in seconds;
                               MUST be in this range: 60 <= "value" <= 86400
                               (1 day).  A 4-octet field containing an
                               unsigned integer.
          */
          // Type: uint32
          {
            "code": 82,
            "data": "420",
            "name": "solmax-rt"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      OPTION_INF_MAX_RT        |         option-len            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                       INF_MAX_RT value                        |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                        Figure 39: INF_MAX_RT Option Format

          option-code          OPTION_INF_MAX_RT (83).

          option-len           4.

          INF_MAX_RT value     Overriding value for INF_MAX_RT in seconds;
                               MUST be in this range: 60 <= "value" <= 86400
                               (1 day).  A 4-octet field containing an
                               unsigned integer.
          */
          // Type: uint32
          {
            "code": 83,
            "data": "2220",
            "name": "inf-max-rt"
          },

          // Option codes 84-86 are not defined in Kea.

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |           option-code         |           option-len          |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          .                        IPv6 Address(es)                       .
          .                                                               .
          .                                                               .
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code:  OPTION_DHCP4_O_DHCP6_SERVER (88).

          option-len:  Length of the IPv6 address(es) carried by the option,
             i.e., multiple of 16 octets.  Minimal length of this option is 0.

          IPv6 Address:  Zero or more IPv6 addresses of the DHCP 4o6 server(s).
          */
          // Type: array of {IPv6 address}
          {
            "code": 88,
            "data": "2001:db8::25, 2001:db8::26",
            "name": "dhcp4o6-server-addr"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |        OPTION_S46_RULE        |         option-length         |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |     flags     |     ea-len    |  prefix4-len  | ipv4-prefix   |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                  (continued)                  |  prefix6-len  |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                           ipv6-prefix                         |
          |                       (variable length)                       |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          .                        S46_RULE-options                       .
          .                                                               .
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          o  option-code: OPTION_S46_RULE (89)

          o  option-length: length of the option, excluding option-code and
             option-length fields, including length of all encapsulated
             options; expressed in octets.

          o  flags: 8 bits long; carries flags applicable to the rule.  The
             meanings of the specific bits are explained in Figure 2.

          o  ea-len: 8 bits long; specifies the Embedded Address (EA) bit
             length.  Allowed values range from 0 to 48.

          o  prefix4-len: 8 bits long; expresses the prefix length of the
             Rule IPv4 prefix specified in the ipv4-prefix field.  Allowed
             values range from 0 to 32.

          o  ipv4-prefix: a fixed-length 32-bit field that specifies the IPv4
             prefix for the S46 rule.  The bits in the prefix after prefix4-len
             number of bits are reserved and MUST be initialized to zero by the
             sender and ignored by the receiver.

          o  prefix6-len: 8 bits long; expresses the length of the
             Rule IPv6 prefix specified in the ipv6-prefix field.  Allowed
             values range from 0 to 128.

          o  ipv6-prefix: a variable-length field that specifies the IPv6
             domain prefix for the S46 rule.  The field is padded on the right
             with zero bits up to the nearest octet boundary when prefix6-len
             is not evenly divisible by 8.

          o  S46_RULE-options: a variable-length field that may contain zero or
             more options that specify additional parameters for this S46 rule.
             This document specifies one such option: OPTION_S46_PORTPARAMS.
          */
          // Type: uint8, uint8, IPv4 address, IPv6 prefix
          {
            "code": 89,
            "data": "1, 0, 24, 192.0.2.0, 2001:db8:1::/64",
            "name": "s46-rule",
            "space": "s46-cont-mape-options"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |         OPTION_S46_BR         |         option-length         |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                      br-ipv6-address                          |
          |                                                               |
          |                                                               |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          o  option-code: OPTION_S46_BR (90)

          o  option-length: 16

          o  br-ipv6-address: a fixed-length field of 16 octets that specifies
             the IPv6 address for the S46 BR.
          */
          // Type: IPv6 address
          {
            "code": 90,
            "data": "2001:db8::27",
            "name": "s46-br",
            "space": "s46-cont-mape-options"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |        OPTION_S46_DMR         |         option-length         |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |dmr-prefix6-len|            dmr-ipv6-prefix                    |
          +-+-+-+-+-+-+-+-+           (variable length)                   |
          .                                                               .
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          o  option-code: OPTION_S46_DMR (91)

          o  option-length: 1 + length of dmr-ipv6-prefix specified in octets.

          o  dmr-prefix6-len: 8 bits long; expresses the bitmask length of the
             IPv6 prefix specified in the dmr-ipv6-prefix field.  Allowed
             values range from 0 to 128.

          o  dmr-ipv6-prefix: a variable-length field specifying the IPv6
             prefix or address for the BR.  This field is right-padded with
             zeros to the nearest octet boundary when dmr-prefix6-len is not
             divisible by 8.
          */
          // Type: IPv6 prefix
          {
            "code": 91,
            "data": "2001:db8:cafe::/64",
            "name": "s46-dmr",
            "space": "s46-cont-mapt-options"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      OPTION_S46_V4V6BIND      |         option-length         |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                         ipv4-address                          |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |bindprefix6-len|             bind-ipv6-prefix                  |
          +-+-+-+-+-+-+-+-+             (variable length)                 |
          .                                                               .
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          .                      S46_V4V6BIND-options                     .
          .                                                               .
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          o  option-code: OPTION_S46_V4V6BIND (92)

          o  option-length: length of the option, excluding option-code and
             option-length fields, including length of all encapsulated
             options; expressed in octets.

          o  ipv4-address: a fixed-length field of 4 octets specifying an IPv4
             address.

          o  bindprefix6-len: 8 bits long; expresses the bitmask length of the
             IPv6 prefix specified in the bind-ipv6-prefix field.  Allowed
             values range from 0 to 128.

          o  bind-ipv6-prefix: a variable-length field specifying the IPv6
             prefix or address for the S46 CE.  This field is right-padded with
             zeros to the nearest octet boundary when bindprefix6-len is not
             divisible by 8.

          o  S46_V4V6BIND-options: a variable-length field that may contain
             zero or more options that specify additional parameters.  This
             document specifies one such option: OPTION_S46_PORTPARAMS.
          */
          // Type: IPv4 address, IPv6 prefix
          {
            "code": 92,
            "data": "192.0.2.78, 2001:db8:1:cafe::/64",
            "name": "s46-v4v6bind",
            "space": "s46-cont-lw-options"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |     OPTION_S46_PORTPARAMS     |         option-length         |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |   offset      |    PSID-len   |              PSID             |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          o  option-code: OPTION_S46_PORTPARAMS (93)

          o  option-length: 4

          o  offset: Port Set Identifier (PSID) offset.  8 bits long; specifies
             the numeric value for the S46 algorithm's excluded port range/
             offset bits (a-bits), as per Section 5.1 of [RFC7597].  Allowed
             values are between 0 and 15.  Default values for this field are
             specific to the softwire mechanism being implemented and are
             defined in the relevant specification document.

          o  PSID-len: 8 bits long; specifies the number of significant bits in
             the PSID field (also known as 'k').  When set to 0, the PSID field
             is to be ignored.  After the first 'a' bits, there are k bits in
             the port number representing the value of the PSID.  Consequently,
             the address-sharing ratio would be 2^k.

          o  PSID: 16 bits long.  The PSID value algorithmically identifies a
             set of ports assigned to a CE.  The first k bits on the left of
             this field contain the PSID binary value.  The remaining (16 - k)
             bits on the right are padding zeros.
          */
          // Type: uint8, PSID
          {
            "code": 93,
            "data": "2, 3/4",
            "name": "s46-portparams",
            "space": "s46-rule-options"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |        OPTION_S46_CONT_MAPE   |         option-length         |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          .            encapsulated-options (variable length)             .
          .                                                               .
          +---------------------------------------------------------------+

          o  option-code: OPTION_S46_CONT_MAPE (94)

          o  option-length: length of encapsulated options, expressed in
             octets.

          o  encapsulated-options: options associated with this Softwire46
             MAP-E domain.
          */
          // Type: empty
          {
            "code": 94,
            "name": "s46-cont-mape",
            "space": "dhcp6"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |     OPTION_S46_CONT_MAPT      |         option-length         |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          .            encapsulated-options (variable length)             .
          .                                                               .
          +---------------------------------------------------------------+

          o  option-code: OPTION_S46_CONT_MAPT (95)

          o  option-length: length of encapsulated options, expressed in
             octets.

          o  encapsulated-options: options associated with this Softwire46
             MAP-T domain.
          */
          // Type: empty
          {
            "code": 95,
            "name": "s46-cont-mapt",
            "space": "dhcp6"
          },

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      OPTION_S46_CONT_LW       |         option-length         |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          +            encapsulated-options (variable length)             .
          .                                                               .
          +---------------------------------------------------------------+

          o  option-code: OPTION_S46_CONT_LW (96)

          o  option-length: length of encapsulated options, expressed in
             octets.

          o  encapsulated-options: options associated with this Softwire46
             Lightweight 4over6 domain.
          */
          // Type: empty
          {
            "code": 96,
            "name": "s46-cont-lw",
            "space": "dhcp6"
          },

          // Option codes 97-102 are not defined in Kea.

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |          option-code          |          option-len           |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          .                      URI (variable length)                    .
          |                              ...                              |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          o  option-code: The Captive-Portal DHCPv6 option (103) (two octets).

          o  option-len: The length, in octets of the URI.

          o  URI: The contact URI for the captive portal that the user should
             connect to (encoded following the rules in [RFC3986]).
          */
          // Type: string
          {
            "code": 103,
            "data": "https://example.org/captive-portal",
            "name": "v6-captive-portal"
          },

          // Option codes 104-111 are not defined in Kea.
          // Option code 112 is unassigned.
          // Option codes 113-134 are not defined in Kea.

          /*
           0                   1                   2                   3
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |       option-code (136)       |          option-length        |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          .           bootstrap-server-list (variable length)             .
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          option-code: OPTION_V6_SZTP_REDIRECT (136)

          option-length: The option length in octets.

          bootstrap-server-list: A list of servers for the
           client to attempt contacting, in order to obtain
           further bootstrapping data. Each URI entry in the
           bootstrap-server-list is structured as follows:

          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-...-+-+-+-+-+-+-+
          |       uri-length              |          URI                  |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-...-+-+-+-+-+-+-+

          uri-length: 2 octets long; specifies the length of the URI data.
          URI: URI of the SZTP bootstrap server.
          */
          // Type: array of {tuple}
          {
            "code": 136,
            "data": "https://sztp1.example.com:8443, https://sztp2.example.com:8444",
            "name": "v6-sztp-redirect"
          },

          // Option codes 137-142 are unassigned.

          /*
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |      Option Code              |         Length                |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                         IP Address                            |
          .                                                               .
          +---------------------------------------------------------------+

          Option Code
             OPTION-IPv6_Address-ANDSF (143)

          Length
             Length (in bytes) of the option excluding the 'Option Code' and
             the 'Length' fields; 'Length' field is set to 16N, where N is the
             number of IPv6 addresses carried in the option

          IP Address
             IPv6 address(es) of ANDSF server(s)
          */
          // Type: IPv6 address
          {
            "code": 143,
            "data": "2001:db8::28",
            "name": "ipv6-address-andsf"
          },

          /*
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |       Option-code             |         Option-length         |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |       Service Priority        |         ADN Length            |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          ~                   authentication-domain-name                  ~
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |         Addr Length           |                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
          ~                        ipv6-address(es)                       ~
          |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                               |                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
          ~                 Service Parameters (SvcParams)                ~
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          Option-code:  OPTION_V6_DNR (144)

          Option-length:  Length of the enclosed data in octets.  The option
             length is ('ADN Length' + 4) when only an ADN is included in the
             option.

          Service Priority:  The priority of this OPTION_V6_DNR instance
             compared to other instances.  This 16-bit unsigned integer is
             interpreted following the rules specified in Section 2.4.1 of
             [RFC9460].

          ADN Length:  Length of the authentication-domain-name field in
             octets.

          authentication-domain-name (variable length):  A fully qualified
             domain name of the encrypted DNS resolver.  This field is
             formatted as specified in Section 10 of [RFC9915].

          Addr Length:  Length of enclosed IPv6 addresses in octets.  When
             present, it MUST be a multiple of 16.

          ipv6-address(es) (variable length):  Indicates one or more IPv6
             addresses to reach the encrypted DNS resolver.  An address can be
             link-local, ULA, or GUA.

          Service Parameters (SvcParams) (variable length):  Specifies a set of
             service parameters that are encoded following the rules in
             Section 2.2 of [RFC9460].
          */
          // Type: internal
          {
            // DNR option may be configured using convenient notation. Comma separated fields must be provided:
            // - service priority (mandatory),
            // - ADN (mandatory),
            // - IP address(es) (optional - if more than one - they must be space-separated)
            // - SvcParams (optional - if more than one - they must be space-separated;
            //   to provide more than one alpn-id separate them with double-backslash escaped comma like in the
            //   example below).
            // Basing on the config, Kea will encode the option according to RFC9463.
            "code": 144,
            "name": "v6-dnr",
            "data": "100, resolver.example., 2001:db8::1 2001:db8::2, alpn=dot\\,h2\\,h3 port=8530 dohpath=/dns-query{?dns}"
          },

          // Option codes 145-65535 are unassigned.

          /*
                                     Custom option data
          */
          // See "option-def" below for the definitions.
          {
            "code": 111,
            "data": "88, 96, 64",
            "name": "s46-priority"
          },
          {
            "code": 1,
            "name": "my-empty-option",
            "space": "my-fancy-space"
          },
          {
            "code": 222,
            "data": "2001:db8::29, 2001:db8::/64, 3/4, 1, example.org, string",
            "name": "my-lengthy-option",
            "space": "my-fancy-space"
          },
          {
            "code": 65432,
            "data": "127, 32767, 2147483647, 255, 65535, 4294967295, 192.0.2.79, 2001:db8::30, 2001:db8::/64, 3/4, 1, example.org, string",
            "name": "my-fancy-option",
            "space": "my-fancy-space"
          },
          {
            "code": 12321,
            "name": "my-encapsulating-option",
            "space": "my-encapsulating-space"
          }
        ],

        /*
                                 Custom option definitions
        */
        // For kea-dhcp6, custom option definitions are always global. Even when
        // data for said options is then configured at subnet level.
        "option-def": [
          // Inside the default space. Codes need to not overlap with other
          // standard/custom option definitions.
          // An option from an actual RFC (8026) not implemented amongst the
          // standard definitions. The option is structured as an array of 16-bit
          // integers so "array" is set to true and "type" to "uint16".
          {
            "array": true,
            "code": 111,
            "encapsulate": "",
            "name": "s46-priority",
            "record-types": "",
            "space": "dhcp6",
            "type": "uint16"
          },

          // New option space allows for a new set of option codes.
          // An empty option requires no "data" in "option-data". It's
          // presence should be sufficient to trigger custom behavior.
          {
            "array": false,
            "code": 1,
            "encapsulate": "",
            "name": "my-empty-option",
            "record-types": "",
            "space": "my-fancy-space",
            "type": "empty"
          },

          // A custom type has "type" set to "record" and all data types (which need
          // to be more than 1, otherwise you're better off using the type directly)
          // are specified in "record-types". If "string" is part of them, it needs
          // to be last.
          {
            "array": false,
            "code": 222,
            "encapsulate": "",
            "name": "my-lengthy-option",
            "record-types": "ipv6-address, ipv6-prefix, psid, tuple, fqdn, string",
            "space": "my-fancy-space",
            "type": "record"
          },

          // Contains arrays of all types except strings since an array of strings
          // is not a valid option definition.
          {
            "array": true,
            "code": 65432,
            "encapsulate": "",
            "name": "my-fancy-option",
            "record-types": "int8, int16, int32, uint8, uint16, uint32, ipv4-address, ipv6-address, ipv6-prefix, psid, tuple, fqdn",
            "space": "my-fancy-space",
            "type": "record"
          },

          // A single encapsulating space can be used. An option containing any
          // option from said space will now be unpacked successfully by Kea.
          {
            "array": false,
            "code": 12321,
            "encapsulate": "my-fancy-space",
            "name": "my-encapsulating-option",
            "record-types": "",
            "space": "my-encapsulating-space",
            "type": "empty"
          }
        ],

        "subnet6": [
          /*
                                     DOCSIS3 option data
          */
          // Headers are as defined in CL-SP-CANN-DHCP-Reg-I16-200715.
          // "space" is required to be explicitly defined as "docsis3-v6"
          {
            "option-data": [
              /*
               0                   1                   2                   3
               0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |          option-code          |          option-len           |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |                          device-type                          |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |                              ...                              |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

              option-code   CL_OPTION_DEVICE_TYPE (2)

              option-len    length of device-type field in bytes.

              device-type   The device type as NVT ASCII text MUST NOT be null terminated.
                 "ECM" for embedded Cable Modem (as specified by DOCSIS 1.0, 1.1, 2.0, 3.0
                 or 3.1 Base Specifications)
                 "EPS" for CableHome embedded Portal Services Element
                 "EMTA" for PacketCable embedded Multimedia Terminal Adapter
                 "EDVA" for PacketCable embedded Digital Voice Adapter
                 "ESTB" for an embedded Set-Top Box
                 "EROUTER" for an embedded DOCSIS Router
                 "SROUTER" for a Standalone Router
              */
              // Type: string
              {
                "code": 2,
                "data": "ECM",
                "name": "device-type",
                "space": "docsis3-v6"
              },

              /*
               0                   1                   2                   3
               0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |          option-code          |          option-len           |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |                                                               .
              .                          vendor-name                          .
              .                                                               |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

              option code:         CL_OPTION_VENDOR_NAME(10)

              option length:       n (for string of length n)

              vendor-name:         The vendor name string NVT ASCII text MUST NOT be
                                   null terminated.
              */
              // Type: string
              {
                "code": 10,
                "data": "CableLabs",
                "name": "vendor-type",
                "space": "docsis3-v6"
              },

              /*
               0                   1                   2                   3
               0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |          option-code          |          option-len           |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |                                                               |
              |                         TFTP-server-1                         |
              |                                                               |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |                                                               |
              |                         TFTP-server-2                         |
              |                                                               |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              .                                                               .
              .                                                               .
              .                                                               .
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |                                                               |
              |                         TFTP-server-n                         |
              |                                                               |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

              option code:         CL_OPTION_TFTP_SERVERS(32)

              option length:       16*n (for n servers in the option) in bytes

              TFTP-server:         The IPv6 address of a TFTP server
              */
              // Type: array of {IPv6 address}
              {
                "code": 32,
                "data": "2001:db8::31",
                "name": "tftp-servers",
                "space": "docsis3-v6"
              },

              /*
               0                   1                   2                   3
               0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |          option-code          |          option-len           |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |                                                               .
              .                    configuration-file-name                    .
              .                                                               |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

              option code:         CL_OPTION_CONFIG_FILE_NAME(33)

              option length:       n (for file name of length n)

              configuration-file-name: The name of the configuration file for the client
              */
              // Type: string
              {
                "code": 33,
                "data": "cm/012345678.cfg",
                "name": "config-file",
                "space": "docsis3-v6"
              },

              /*
               0                   1                   2                   3
               0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |          option-code          |          option-len           |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |                                                               .
              .                          vendor-name                          .
              .                                                               |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

              option code:           CL_OPTION_VENDOR_NAME(10)

              option length:         n (for string of length n)

              vendor-name:           The vendor name string NVT ASCII text MUST NOT be
                                     null terminated.
              */
              // Type: array of {IPv6 address}
              {
                "code": 34,
                "data": "2001:db8::32",
                "name": "syslog-servers",
                "space": "docsis3-v6"
              },

              /*
               0                   1                   2                   3
               0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |          option-code          |          option-len           |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |                                                               .
              .                          vendor-name                          .
              .                                                               |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

              option code:           CL_OPTION_VENDOR_NAME(10)

              option length:         n (for string of length n)

              vendor-name:           The vendor name string NVT ASCII text MUST NOT be
                                     null terminated.
              */
              // Type: binary
              {
                "code": 36,
                "data": "1A BB AD AB BA D0 00 00 00 00 00 00 00 00 CA FE",
                "name": "device-id",
                "space": "docsis3-v6"
              },

              /*
               0                   1                   2                   3
               0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |          option-code          |          option-len           |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |                                                               .
              .                          vendor-name                          .
              .                                                               |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

              option code:           CL_OPTION_VENDOR_NAME(10)

              option length:         n (for string of length n)

              vendor-name:           The vendor name string NVT ASCII text MUST NOT be
                                     null terminated.
              */
              // Type: int32
              {
                "code": 37,
                "data": "2001:db8::33",
                "name": "time-servers",
                "space": "docsis3-v6"
              },

              /*
               0                   1                   2                   3
               0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |          option-code          |          option-len           |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
              |                                                               .
              .                          vendor-name                          .
              .                                                               |
              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

              option code:           CL_OPTION_VENDOR_NAME(10)

              option length:         n (for string of length n)

              vendor-name:           The vendor name string NVT ASCII text MUST NOT be
                                     null terminated.
              */
              // Type: int32
              {
                "code": 38,
                "data": "-25200",
                "name": "time-offset",
                "space": "docsis3-v6"
              }
            ],
            "subnet": "2001:db8:d0c5:15::/64",
            "id": 1
          }
        ]
      }
    }

.. _config-example-kea6-backends-json:

------------------
kea6/backends.json
------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv6 server in Kea.
    // It is a basic scenario with one IPv6 subnet configured. It demonstrates
    // how to configure Kea to use various backends to store leases:
    // - memfile
    // - MySQL
    // - PostgreSQL

    { "Dhcp6":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // We need to specify lease type. Exactly one lease-database section
    // should be present. Make sure you uncomment only one.

    // 1. memfile backend. Leases information will be stored in flat CSV file.
    // This is the easiest backend to use as it does not require any extra
    // dependencies or services running.
      "lease-database": {
          "type": "memfile",
          "persist": true,
          "lfc-interval": 3600
      },

    // 2. MySQL backend. Leases will be stored in MySQL database. Make sure it
    // is up, running and properly initialized. See kea-admin documentation
    // for details on how to initialize the database. The only strictly required
    // parameters are type and name. If other parameters are not specified,
    // Kea will assume the database is available on localhost, that user and
    // password is not necessary to connect and that timeout is 5 seconds.
    // Kea must be compiled with the "-D mysql" option to use this backend.
    //  "lease-database": {
    //      "type": "mysql",
    //      "name": "keatest",
    //      "host": "localhost",
    //      "port": 3306,
    //      "user": "keatest",
    //      "password": "1234",
    //      "reconnect-wait-time": 3000, // expressed in ms
    //      "max-reconnect-tries": 3,
    //      "on-fail": "stop-retry-exit",
    //      "retry-on-startup": false,
    //      "connect-timeout": 3
    //  },
    // Since Kea.2.7.4, the libdhcp_mysql.so hook library must be loaded in order to
    // store leases in the MySQL Lease Database Backend.
    // Specify the lease backend hook library location.
    //  {
    //      // the MySQL lease backend hook library required for lease storage.
    //      "library": "libdhcp_mysql.so"
    //  },

    // 3. PostgreSQL backend. Leases will be stored in PostgreSQL database. Make
    // sure it is up, running and properly initialized. See kea-admin documentation
    // for details on how to initialize the database. The only strictly required
    // parameters are type and name. If other parameters are not specified,
    // Kea will assume the database is available on localhost, that user and
    // password is not necessary to connect and that timeout is 5 seconds.
    // Kea must be compiled with the "-D postgresql" option to use this backend.
    //  "lease-database": {
    //      "type": "postgresql",
    //      "name": "keatest",
    //      "host": "localhost",
    //      "port": 5432,
    //      "user": "keatest",
    //      "password": "1234",
    //      "reconnect-wait-time": 3000, // expressed in ms
    //      "max-reconnect-tries": 3,
    //      "on-fail": "stop-retry-exit",
    //      "retry-on-startup": false,
    //      "connect-timeout": 3
    //  },
    // Since Kea.2.7.4, the libdhcp_pgsql.so hook library must be loaded in order to
    // store leases in the PostgreSQL Lease Database Backend.
    // Specify the lease backend hook library location.
    //  {
    //      // the PostgreSQL lease backend hook library required for lease storage.
    //      "library": "libdhcp_pgsql.so"
    //  },

    // Addresses will be assigned with preferred and valid lifetimes
    // being 3000 and 4000, respectively. Client is told to start
    // renewing after 1000 seconds. If the server does not respond
    // after 2000 seconds since the lease was granted, client is supposed
    // to start REBIND procedure (emergency renewal that allows switching
    // to a different server).
      "preferred-lifetime": 3000,
      "valid-lifetime": 4000,
      "renew-timer": 1000,
      "rebind-timer": 2000,

    // The following list defines subnets. Each subnet consists of at
    // least subnet and pool entries.
      "subnet6": [
        {
          "pools": [ { "pool": "2001:db8:1::/80" } ],
          "id": 1,
          "subnet": "2001:db8:1::/64",
          "interface": "eth0"
        }
      ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp6",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "debuglevel": 0,
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea6-classify-json:

------------------
kea6/classify.json
------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv6 server in Kea.
    // The purpose of this example is to showcase how clients can be classified.

    { "Dhcp6":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // Let's use the simplest backend: memfile and use some reasonable values
    // for timers. They are of no concern for the classification demonstration.
      "lease-database": {
          "type": "memfile",
          "lfc-interval": 3600
      },
      "renew-timer": 1000,
      "rebind-timer": 2000,
      "preferred-lifetime": 3000,
      "valid-lifetime": 4000,

    // This list defines several classes that incoming packets can be assigned to.
    // One packet can belong to zero or more classes.
      "client-classes": [

    // The first class attempts to match all packets coming in on eth0 interface.
      {
          "name": "lab",
          "test": "pkt.iface == 'eth0'",
          "option-data": [{
              "name": "dns-servers",
              "data": "2001:db8::1"
          }]
      },

    // Let's classify all incoming RENEW (message type 5) to a separate
    // class.
      {
          "name": "renews",
          "test": "pkt6.msgtype == 5"
      },

    // Let's pick cable modems. In this simple example we'll assume the device
    // is a cable modem if it sends a vendor option with enterprise-id equal
    // to 4491.
      {
          "name": "cable-modems",
          "test": "vendor.enterprise == 4491"
      }

      ],


    // The following list defines subnets. Each subnet consists of at
    // least subnet and pool entries.
      "subnet6": [
        {
            "id": 1,
            "pools": [ { "pool": "2001:db8:1::/80" } ],
            "subnet": "2001:db8:1::/64",
            "client-classes": [ "cable-modems" ],
            "interface": "eth0"
        },

        // The following subnet contains a class reservation for a client using
        // DUID 01:02:03:04:05:0A:0B:0C:0D:0E. This client will always be assigned
        // to this class.
        {
            "id": 2,
            "pools": [ { "pool": "2001:db8:2::/80" } ],
            "subnet": "2001:db8:2::/64",
            "reservations": [
            {
                "duid": "01:02:03:04:05:0A:0B:0C:0D:0E",
                "client-classes": [ "cable-modems" ]
            } ],
            "interface": "eth0"
        },

        // The following subnet contains a pool with a class constraint: only
        // clients which belong to the class are allowed to use this pool.
        {
            "id": 3,
            "pools": [
               {
                   "pool": "2001:db8:4::/80",
                   "client-classes": [ "cable-modems" ]
               } ],
             "subnet": "2001:db8:4::/64",
             "interface": "eth1"
        }

      ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp6",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "debuglevel": 0,
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea6-classify2-json:

-------------------
kea6/classify2.json
-------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv6 server in Kea.
    // The purpose of this example is to showcase how clients can be classified.

    { "Dhcp6":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // Let's use the simplest backend: memfile and use some reasonable values
    // for timers. They are of no concern for the classification demonstration.
      "lease-database": {
          "type": "memfile",
          "lfc-interval": 3600
      },
      "renew-timer": 1000,
      "rebind-timer": 2000,
      "preferred-lifetime": 3000,
      "valid-lifetime": 4000,

    // This list defines several classes that incoming packets can be assigned to.
    // One packet can belong to zero or more classes.
      "client-classes": [

    // This class is included by the second subnet in its 'evaluate-additional-classes'
    // list so 'only-in-additional-list' is enabled. This ensures the class will only
    // be evaluated if the second subnet is selected. The test expression returns true.
    // Note it is not possible to depend on cable-modems class because it
    // is not yet defined.
      {
          "name": "second_subnet",
          "only-in-additional-list": true,
          "test": "member('ALL')",
          "option-data": [{
              "name": "dns-servers",
              "data": "2001:db8::1"
          }]
      },

    // Let's classify all incoming RENEW (message type 5) to a separate
    // class.
      {
          "name": "renews",
          "test": "pkt6.msgtype == 5"
      },

    // Let's pick cable modems. In this simple example we'll assume the device
    // is a cable modem if it sends a vendor option with enterprise-id equal
    // to 4491.
      {
          "name": "cable-modems",
          "test": "vendor.enterprise == 4491"
      },

    // Both a cable modem (by evaluation or host reservation) and has a host
    // reservation.
      {
          "name": "cable-modem-hosts",
          "test": "member('cable-modems') and member('KNOWN')"
      }

      ],


    // The following list defines subnets. Each subnet consists of at
    // least subnet and pool entries.
      "subnet6": [
        {
            "id": 1,
            "pools": [ { "pool": "2001:db8:1::/80" } ],
            "subnet": "2001:db8:1::/64",
            "client-classes": [ "cable-modems" ],
            "interface": "eth0"
        },
    // The following subnet contains a class reservation for a client using
    // DUID 01:02:03:04:05:0A:0B:0C:0D:0E. This client will always be assigned
    // to this class.
        {
            "id": 2,
            "pools": [ { "pool": "2001:db8:2::/80" } ],
            "subnet": "2001:db8:2::/64",
            "reservations": [
            {
                "duid": "01:02:03:04:05:0A:0B:0C:0D:0E",
                "client-classes": [ "cable-modems" ]
            } ],
            "interface": "eth0",
            "evaluate-additional-classes": [ "second_subnet" ]
        },
    // The following subnet contains a pool with a class constraint: only
    // clients which belong to the class are allowed to use this pool.
        {
            "id": 3,
            "pools": [
               {
                   "pool": "2001:db8:4::/80",
                   "client-classes": [ "cable-modems" ]
               } ],
             "subnet": "2001:db8:4::/64",
             "interface": "eth1"
        },
    // This subnet is divided in two pools for unknown and known
    // (i.e. which have a reservation) clients. The built-in KNOWN and
    // UNKNOWN classes are set or not at host reservation lookup (KNOWN if
    // this returns something, UNKNOWN if this finds nothing) and client
    // classes depending on it are evaluated.
    // This happens after subnet selection and before address allocation
    // from pools.
        {
            "id": 4,
            "pools": [
                {
                   "pool": "2001:db8:8::/64",
                   "client-classes": [ "UNKNOWN" ]
                },
                {
                   "pool": "2001:db8:9::/64",
                   "client-classes": [ "KNOWN" ]
               }
            ],
            "subnet": "2001:db8:8::/46",
            "reservations": [
                {  "hw-address": "00:00:00:11:22:33", "hostname": "h1" },
                {  "hw-address": "00:00:00:44:55:66", "hostname": "h4" },
                {  "hw-address": "00:00:00:77:88:99", "hostname": "h7" },
                {  "hw-address": "00:00:00:aa:bb:cc", "hostname": "ha" }
            ]
        }

      ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp6",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "debuglevel": 0,
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea6-comments-json:

------------------
kea6/comments.json
------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv6 server in Kea.
    // It uses embedded (i.e., which will be included in configuration objects
    // and not stripped by at lexical analysis) comments.

    { "Dhcp6":

    {
       // Global scope
       "comment": "A DHCPv6 server",

       // In interface config
       "interfaces-config": {
           "comment": "Use wildcard",
           "interfaces": [ "*" ] },

       // In option definitions
       "option-def": [ {
           "comment": "An option definition",
           "name": "foo",
           "code": 100,
           "type": "ipv6-address",
           "space": "isc"
        } ],

       // In option data
       "option-data": [ {
           "comment": "Set option value",
           "name": "subscriber-id",
           "data": "ABCDEF0105",
           "csv-format": false
        } ],

       // In client classes
       "client-classes": [
           {
              "comment": "match all",
              "name": "all",
              "test": "'' == ''"
           },
           // Of course comments are optional
           {
              "name": "none"
           },
           // A comment and a user-context can be specified
           {
              "comment": "a comment",
              "name": "both",
              "user-context": {
                  "version": 1
              }
           }
       ],

       // In control sockets
       "control-sockets": [
           {
               "socket-type": "unix",
               "socket-name": "kea6-ctrl-socket",
               "user-context": { "comment": "Indirect comment" }
           },
           {
               "comment": "HTTP control socket",
               "socket-type": "http",
               "socket-address": "127.0.0.1",
               "socket-port": 8006,

               // In authentication
               "authentication": {
                   "comment": "basic HTTP authentication",
                   "type": "basic",
                   // In basic HTTP authentication clients
                   "clients": [ {
                       "user": "admin",
                       "password": "1234"
                   } ]
               }
           }
       ],

       // In shared networks
       "shared-networks": [ {
           "comment": "A shared network",
           "name": "foo",

           // In subnets
           "subnet6": [
             {
               "comment": "A subnet",
               "subnet": "2001:db1::/64",
               "id": 100,

               // In pools
               "pools": [
                 {
                    "comment": "A pool",
                    "pool": "2001:db1::/64"
                 }
               ],

               // In prefix pools
               "pd-pools": [
                 {
                    "comment": "A prefix pool",
                    "prefix": "2001:db2::",
                    "prefix-len": 48,
                    "delegated-len": 64
                 }
               ],

               // In host reservations
               "reservations": [
                 {
                    "comment": "A host reservation",
                    "hw-address": "AA:BB:CC:DD:EE:FF",
                    "hostname": "foo.example.com",

                    // Again in an option data
                    "option-data": [ {
                        "comment": "An option in a reservation",
                        "name": "domain-search",
                        "data": "example.com"
                    } ]
                 }
               ]
             }
           ]
        } ],

       // In dhcp ddns
       "dhcp-ddns": {
           "comment": "No dynamic DNS",
           "enable-updates": false
       },

       // In loggers
       "loggers": [ {
           "comment": "A logger",
           "name": "kea-dhcp6"
       } ]
    }

    }

.. _config-example-kea6-config-backend-json:

------------------------
kea6/config-backend.json
------------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv4 server in Kea.
    // It demonstrates how to enable Kea Configuration Backend using MySQL.
    // It requires that libdhcp_mysql.so library is available and
    // optionally libdhcp_cb_cmds.so hook library.

    { "Dhcp6":

    {
        // Set the server tag for the configuration backend. This instance will
        // be named server2. Every configuration element that is applicable to
        // either "all" or "server2" will be used by this instance.
        "server-tag": "server2",

        // Kea is told to listen on eth0 interface only.
        "interfaces-config": {
            "interfaces": [ "eth0" ]
        },

        // Use memfile lease database backend.
        "lease-database": {
            "type": "memfile",
            "lfc-interval": 3600
        },

        // This parameter controls how the server accesses the configuration
        // database. Currently only two database types are available - "mysql" and
        // "postgresql".
        // Using "mysql" requires that the libdhcp_mysql.so hook library is loaded.
        // If using "postgresql", then loading libdhcp_pgsql.so hook library is
        // required.
        "config-control": {
            // A list of database backends to connect to. Currently, it is limited
            // to a single backend.
            "config-databases": [
                {
                    "type": "mysql",
                    "reconnect-wait-time": 3000, // expressed in ms
                    "max-reconnect-tries": 3,
                    "name": "kea",
                    "user": "kea",
                    "password": "1234",
                    "host": "localhost",
                    "port": 3306
                }
            ],
            // Controls how often the server polls the database for the
            // configuration updates. The setting below implies that it
            // will take up to approx. 20 seconds for the server to
            // discover and fetch configuration changes.
            "config-fetch-wait-time": 20
        },

        // This defines a control socket. If defined, Kea will open a UNIX socket
        // and will listen for incoming commands. See section 17 of the Kea ARM for
        // details.
        "control-socket": {
            "socket-type": "unix",
            "socket-name": "kea6-ctrl-socket"
        },

        // Hooks libraries that enable configuration backend are loaded.
        "hooks-libraries": [
            // The libdhcp_mysql.so is required to use MySQL Configuration
            // Backend.
            {
                "library": "libdhcp_mysql.so"
            }
            // If using PostgreSQL Configuration Backend, the "libdhcp_pgsql.so" is
            // required.
            // {
            //    "library": "libdhcp_pgsql.so"
            // }
            // The libdhcp_cb_cmds.so is optional. It allows for managing the
            // configuration in the database. If this library is not loaded,
            // the configuration can be managed directly using available
            // tools that work directly with the MySQL database.
            // ,{
            //     "library": "libdhcp_cb_cmds.so"
            // }
        ],

        // The following configures logging. It assumes that messages with at
        // least informational level (info, warn, error and fatal) should be
        // logged to stdout. Alternatively, you can specify stderr here, a filename
        // or 'syslog', which will store output messages via syslog.
        "loggers": [
            {
                "name": "kea-dhcp6",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "debuglevel": 0,
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea6-dhcpv4-over-dhcpv6-json:

----------------------------
kea6/dhcpv4-over-dhcpv6.json
----------------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv6 server of
    // DHCPv4-over-DHCPv6 tests in Kea.

    {

    // DHCPv6 conf
    "Dhcp6":
    {
      "interfaces-config": {
    // Enable unicast
        "interfaces": [ "eth0/2001:db8:1::1" ]
      },

      "lease-database": {
          "type": "memfile",
          "name": "kea-leases6.csv"
      },

      "preferred-lifetime": 3000,
      "valid-lifetime": 4000,
      "renew-timer": 1000,
      "rebind-timer": 2000,

      "subnet6": [
       {    "id": 1,
            "subnet": "2001:db8:1:1::/64",
            "interface": "eth0",
            "pools": [ { "pool": "2001:db8:1:1::1:0/112" } ] }
      ],

    // This enables DHCPv4-over-DHCPv6 support
      "dhcp4o6-port": 786,

    // Required by DHCPv4-over-DHCPv6 clients
      "option-data": [
       {  "name": "dhcp4o6-server-addr",
          "code": 88,
          "space": "dhcp6",
          "csv-format": true,
    // Put the server address here
          "data": "2001:db8:1:1::1" }
      ],

      "loggers": [
        {
          "name": "kea-dhcp6",
          "output-options": [
              {
                "output": "kea-dhcp6.log"
              }
          ],
          "severity": "DEBUG",
          "debuglevel": 0
        }
      ]
    }

    }

.. _config-example-kea6-duid-json:

--------------
kea6/duid.json
--------------

.. code-block::
    :linenos:

    // This is an example configuration file for DHCPv6 server in Kea.
    // It demonstrates how to configure Kea to use DUID-LLT with some
    // values specified explicitly.

    { "Dhcp6":

    {

    // Configure server identifier (DUID-LLT). The hexadecimal value of the
    // identifier will be used as link layer address component of the DUID.
    // The link layer type will be ethernet. The value of time is set to 0
    // which indicates that the server must generate this value, i.e. use
    // current time. Note that it is easy to move from this configuration
    // to DUID-EN or DUID-LL. It would require changing the "type" value
    // to "EN" or "LL" respectively. The "identifier" would hold a
    // DUID-EN variable length identifier or DUID-LL link layer address.
    // The values of "time" and "htype" would be ignored for DUID-EN.
    // If one wanted to use a non-default enterprise-id for DUID-EN, the
    // "enterprise-id" parameter would need to be added. Note that only
    // a "type" parameter is mandatory while specifying "server-id" map.
      "server-id": {
        "type": "LLT",
        "identifier": "12C4D5AF870C",
        "time": 0,
        "htype": 1
      },

    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // We need to specify the database used to store leases. As of
    // June 2022, three database backends are supported: MySQL,
    // PostgreSQL and the in-memory database, Memfile.
    // We'll use memfile because it doesn't require any prior set up.
      "lease-database": {
          "type": "memfile",
          "lfc-interval": 3600
      },

    // Addresses will be assigned with preferred and valid lifetimes
    // being 3000 and 4000, respectively. Client is told to start
    // renewing after 1000 seconds. If the server does not respond
    // after 2000 seconds since the lease was granted, client is supposed
    // to start REBIND procedure (emergency renewal that allows switching
    // to a different server).
      "preferred-lifetime": 3000,
      "valid-lifetime": 4000,
      "renew-timer": 1000,
      "rebind-timer": 2000,

    // The following list defines subnets. Each subnet consists of at
    // least subnet and pool entries.
      "subnet6": [
        {
          "id": 1,
          "pools": [ { "pool": "2001:db8:1::/80" } ],
          "subnet": "2001:db8:1::/64",
          "interface": "eth0"
        }
      ],

    // The following configures logging. It assumes that messages with at least
    // informational level (info, warn, error) will will be logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp6",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "debuglevel": 0,
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea6-global-reservations-json:

-----------------------------
kea6/global-reservations.json
-----------------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv6 server in Kea.
    // It demonstrates how global host reservations can be configured.
    // The global reservations are not associated with any subnet. They
    // are assigned regardless of the subnet to which the DHCP client belongs.
    // Global reservations are assigned to the DHCP clients using the
    // same host identifier types as subnet specific reservations. This file
    // contains multiple examples of host reservations using different
    // identifier types, e.g. DUID, MAC address etc.
    { "Dhcp6":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // We need to specify the database used to store leases. As of
    // June 2022, three database backends are supported: MySQL,
    // PostgreSQL and the in-memory database, Memfile.
    // We'll use memfile because it doesn't require any prior set up.
      "lease-database": {
          "type": "memfile",
          "lfc-interval": 3600
      },

    // This is pretty basic stuff, it has nothing to do with reservations.
      "preferred-lifetime": 3000,
      "valid-lifetime": 4000,
      "renew-timer": 1000,
      "rebind-timer": 2000,

    // Kea supports three types of identifiers in DHCPv6: hw-address (hardware/MAC
    // address of the client), duid (DUID inserted by the client) and flex-id
    // (flexible identifier available when flex_id hook library is loaded) When told
    // to do so, Kea can check for each of these identifier types, but it takes a
    // costly database lookup to do so. It is therefore useful from a performance
    // perspective to use only the reservation types that are actually used in a
    // given network.
      "host-reservation-identifiers": [ "duid", "hw-address", "flex-id" ],

    // This directive tells Kea that reservations are global. Note that this
    // can also be specified at shared network and/or subnet level.

    // Specify whether the server should look up global reservations.
      "reservations-global": true,

    // Specify whether the server should look up in-subnet reservations.
      "reservations-in-subnet": false,

    // Specify whether the server can assume that all reserved addresses
    // are out-of-pool.
    // Ignored when reservations-in-subnet is false.
    // If specified, it is inherited by "shared-networks" and "subnet6" levels.
      "reservations-out-of-pool": false,

    // Define several global host reservations.
      "reservations": [

    // This is a simple host reservation. The host with DUID matching
    // the specified value will get an address of 2001:db8:1::100.
    // Note it is not recommended but still allowed to reverse addresses at
    // the global scope: as it breaks the link between the reservation and
    // the subnet it can lead to a client localized in another subnet than
    // its address belongs to.
          {
              "duid": "01:02:03:04:05:0A:0B:0C:0D:0E",
              "ip-addresses": [ "2001:db8:1::100" ]
          },

    // This is similar to the previous one, but this time the reservation
    // is done based on hardware/MAC address. The server will do its best to
    // extract the hardware/MAC address from received packets (see
    // 'mac-sources' directive for details). This particular reservation
    // also specifies two extra options to be available for this client. If
    // there are options with the same code specified in a global, subnet or
    // class scope, the values defined at host level take precedence for
    // this particular DHCP client.
          {
              "hw-address": "00:01:02:03:04:05",
              "ip-addresses": [ "2001:db8:1::101" ],
              "option-data": [
                  {
                      "name": "dns-servers",
                      "data": "3000:1::234"
                  },
                  {
                      "name": "nis-servers",
                      "data": "3000:1::234"
                  }
              ],
              "client-classes": [ "special_snowflake", "office" ]
          },

    // This is a bit more advanced reservation. The client with the specified
    // DUID will get a reserved address, a reserved prefix and a hostname.
    // At least one of the three must be specified in a reservation.
    // Finally, this reservation features vendor specific options for CableLabs,
    // which happen to use enterprise-id 4491. Those particular values will
    // be returned only to the client that has a DUID matching this reservation.
          {
              "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"
                  }
              ]
          },

    // This reservation is using flexible identifier. Instead of relying
    // on specific field, sysadmin can define an expression similar to what
    // is used for client classification,
    // e.g. substring(relay[0].option[17],0,6). Then, based on the value of
    // that expression for incoming packet, the reservation is matched.
    // Expression can be specified either as hex or plain text using single
    // quotes.
    // Note: flexible identifier requires flex_id hook library to be
    // loaded to work.
          {
              "flex-id": "'somevalue'",
              "ip-addresses": [ "2001:db8:1:cafe::2" ]
          }
      ],

    // The following list defines subnets. Subnet, pools and interface definitions
    // are the same as in the regular scenario.
        "subnet6": [
            {
                "id": 1,

                "subnet": "2001:db8::/47",

                "pools": [ { "pool": "2001:db8::/64" } ],

                "pd-pools": [
                    {
                        "prefix": "2001:db8:1:8000::",
                        "prefix-len": 56,
                        "delegated-len": 64
                    }
                ],
                "interface": "eth0"
            }
        ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp6",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "debuglevel": 0,
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea6-ha-hot-standby-server1-with-tls-json:

-----------------------------------------
kea6/ha-hot-standby-server1-with-tls.json
-----------------------------------------

.. code-block::
    :linenos:

    // This is an example configuration of the Kea DHCPv6 server. It uses High
    // Availability hook library and Lease Commands hook library to enable
    // High Availability function for the DHCP server. Note that almost exactly
    // the same configuration must be used on the second server (partner).
    // The only difference is that "this-server-name" must be set to "server2"
    // on this other server. Also, the interface configuration and location of TLS
    // specific files depend on the network settings and configuration of the
    // particular machine.
    //
    // The servers using this configuration work in hot standby mode.
    {

    // DHCPv6 configuration starts here.
    "Dhcp6": {
        // Add names of your network interfaces to listen on.
        "interfaces-config": {
            // The DHCPv6 server listens on this interface.
            "interfaces": [ "eth0" ]
        },

        // Use Memfile lease database backend to store leases in a CSV file.
        // Depending on how Kea was compiled, it may also support SQL databases
        // (MySQL and/or PostgreSQL). Those database backends require more
        // parameters, like name, host and possibly user and password.
        // There are dedicated examples for each backend. See Section 7.2.2 "Lease
        // Storage" for details.
        "lease-database": {
            // Memfile is the simplest and easiest backend to use. It's an in-memory
            "type": "memfile"
        },

        // HA requires two hook libraries to be loaded: libdhcp_lease_cmds.so and
        // libdhcp_ha.so. The former handles incoming lease updates from the HA peers.
        // The latter implements high availability feature for Kea.
        "hooks-libraries": [
            // The lease_cmds library must be loaded because HA makes use of it to
            // deliver lease updates to the server as well as synchronize the
            // lease database after failure.
            {
                "library": "libdhcp_lease_cmds.so",
                "parameters": { }
            },
            {
                // The HA hook library should be loaded.
                "library": "libdhcp_ha.so",
                "parameters": {
                    // High Availability configuration is specified for the HA hook library.
                    // Each server should have the same HA configuration, except for the
                    // "this-server-name" parameter.
                    "high-availability": [ {
                        // This parameter points to this server instance. The respective
                        // HA peers must have this parameter set to their own names.
                        "this-server-name": "server1",
                        // The HA mode is set to hot-standby. This server will receive lease
                        // updates from the primary. The primary will be responding to all
                        // DHCP queries.
                        "mode": "hot-standby",
                        // Heartbeat is to be sent every 10 seconds if no other control
                        // commands are transmitted.
                        "heartbeat-delay": 10000,
                        // Maximum time for partner's response to a heartbeat, after which
                        // failure detection is started. This is specified in milliseconds.
                        "max-response-delay": 60000,
                        // The following parameters control how the server detects the
                        // partner's failure. The ACK delay sets the threshold for the
                        // 'secs' field of the received discovers. This is specified in
                        // milliseconds.
                        "max-ack-delay": 5000,
                        // This specifies the number of clients which send messages to
                        // the partner but appear to not receive any response.
                        "max-unacked-clients": 5,
                        // Trust anchor aka certificate authority file or directory.
                        "trust-anchor": "/usr/lib/kea/CA.pem",
                        // Client certificate file name.
                        "cert-file": "/usr/lib/kea/server_cert.pem",
                        // Private key file name.
                        "key-file": "/usr/lib/kea/server_key.pem",
                        // Client certificates are required and verified.
                        "require-client-certs": true,
                        "peers": [
                            // This is the configuration of this server instance.
                            {
                                "name": "server1",
                                // This specifies the URL of this server instance.
                                "url": "http://192.168.56.33:8007/",
                                // This server is primary. The other one must be
                                // standby.
                                "role": "primary"
                            },
                            // This is the configuration of the HA peer.
                            {
                                "name": "server2",
                                // Specifies the URL on which the partner's control
                                // channel can be reached.
                                "url": "http://192.168.56.66:8007/",
                                // The partner is standby. This server is primary.
                                "role": "standby"
                            }
                        ]
                    } ]
                }
            }
        ],

        // The following list defines subnets. Each subnet consists of at
        // least subnet and pool entries.
        "subnet6": [
            {
                "id": 1,

                "subnet": "2001:db8:1::/64",

                "pools": [
                    {
                        "pool": "2001:db8:1::100 - 2001:db8:1::250"
                    }
                ],

                 "interface": "eth0"
            }
        ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout. Alternatively, you can specify stderr here, a filename
    // or 'syslog', which will store output messages via syslog.
        "loggers": [
            {
                // This section affects kea-dhcp6, which is the base logger for DHCPv6
                // component. It tells DHCPv6 server to write all log messages (on
                // severity INFO or more) to a file.
                "name": "kea-dhcp6",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "severity": "INFO",
                "debuglevel": 0
            },
            {
                // This section specifies configuration of the HA hook library-specific
                // logger.
                "name": "kea-dhcp6.ha-hooks",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "severity": "INFO",
                "debuglevel": 99
            }
        ]
    }
    }

.. _config-example-kea6-ha-hot-standby-server2-json:

--------------------------------
kea6/ha-hot-standby-server2.json
--------------------------------

.. code-block::
    :linenos:

    // This is an example configuration of the Kea DHCPv6 server. It uses High
    // Availability hook library and Lease Commands hook library to enable
    // High Availability function for the DHCP server. Note that almost exactly
    // the same configuration must be used on the second server (partner).
    // The only difference is that "this-server-name" must be set to "server1"
    // on this other server. Also, the interface configuration depends on the
    // network settings of the particular machine.
    //
    // The servers using this configuration work in hot standby mode.
    {

    // DHCPv6 configuration starts here.
    "Dhcp6": {
        // Add names of your network interfaces to listen on.
        "interfaces-config": {
            // The DHCPv6 server listens on this interface.
            "interfaces": [ "eth0" ]
        },

        // Use Memfile lease database backend to store leases in a CSV file.
        // Depending on how Kea was compiled, it may also support SQL databases
        // (MySQL and/or PostgreSQL). Those database backends require more
        // parameters, like name, host and possibly user and password.
        // There are dedicated examples for each backend. See Section 7.2.2 "Lease
        // Storage" for details.
        "lease-database": {
            // Memfile is the simplest and easiest backend to use. It's an in-memory
            "type": "memfile"
        },

        // HA requires two hook libraries to be loaded: libdhcp_lease_cmds.so and
        // libdhcp_ha.so. The former handles incoming lease updates from the HA peers.
        // The latter implements high availability feature for Kea.
        "hooks-libraries": [
            // The lease_cmds library must be loaded because HA makes use of it to
            // deliver lease updates to the server as well as synchronize the
            // lease database after failure.
            {
                "library": "libdhcp_lease_cmds.so",
                "parameters": { }
            },
            {
                // The HA hook library should be loaded.
                "library": "libdhcp_ha.so",
                "parameters": {
                    // High Availability configuration is specified for the HA hook library.
                    // Each server should have the same HA configuration, except for the
                    // "this-server-name" parameter.
                    "high-availability": [ {
                        // This parameter points to this server instance. The respective
                        // HA peers must have this parameter set to their own names.
                        "this-server-name": "server2",
                        // The HA mode is set to hot-standby. This server will receive lease
                        // updates from the primary. The primary will be responding to all
                        // DHCP queries.
                        "mode": "hot-standby",
                        // Heartbeat is to be sent every 10 seconds if no other control
                        // commands are transmitted.
                        "heartbeat-delay": 10000,
                        // Maximum time for partner's response to a heartbeat, after which
                        // failure detection is started. This is specified in milliseconds.
                        "max-response-delay": 60000,
                        // The following parameters control how the server detects the
                        // partner's failure. The ACK delay sets the threshold for the
                        // 'secs' field of the received discovers. This is specified in
                        // milliseconds.
                        "max-ack-delay": 5000,
                        // This specifies the number of clients which send messages to
                        // the partner but appear to not receive any response.
                        "max-unacked-clients": 5,
                        "peers": [
                            // This is the configuration of the HA peer.
                            {
                                "name": "server1",
                                // Specifies the URL on which the partner's control
                                // channel can be reached.
                                "url": "http://192.168.56.33:8007/",
                                // The partner is primary. This server is standby.
                                "role": "primary"
                            },
                            // This is the configuration of this server instance.
                            {
                                "name": "server2",
                                // This specifies the URL of this server instance.
                                "url": "http://192.168.56.66:8007/",
                                // This server is standby. The other one must be
                                // primary.
                                "role": "standby"
                            }
                        ]
                    } ]
                }
            }
        ],

        // The following list defines subnets. Each subnet consists of at
        // least subnet and pool entries.
        "subnet6": [
            {
                "id": 1,

                "subnet": "2001:db8:1::/64",

                "pools": [
                    {
                        "pool": "2001:db8:1::100 - 2001:db8:1::250"
                    }
                ],

                 "interface": "eth0"
            }
        ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout. Alternatively, you can specify stderr here, a filename
    // or 'syslog', which will store output messages via syslog.
        "loggers": [
            {
                // This section affects kea-dhcp6, which is the base logger for DHCPv6
                // component. It tells DHCPv6 server to write all log messages (on
                // severity INFO or more) to a file.
                "name": "kea-dhcp6",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "severity": "INFO",
                "debuglevel": 0
            },
            {
                // This section specifies configuration of the HA hook library-specific
                // logger.
                "name": "kea-dhcp6.ha-hooks",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "severity": "INFO",
                "debuglevel": 99
            }
        ]
    }
    }

.. _config-example-kea6-hooks-rbac-json:

--------------------
kea6/hooks-rbac.json
--------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv6 server in Kea using
    // the Role Based Access Control (RBAC) hook library. It uses a basic scenario
    // of one IPv6 subnet configured with the default values for all parameters.

    {"Dhcp6":

    {
    // Kea is told to listen on the eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // Set up the storage for leases.
      "lease-database": {
        "type": "memfile"
      },

    // Set values to mandatory timers
      "renew-timer": 900,
      "rebind-timer": 1200,
      "preferred-lifetime": 1800,
      "valid-lifetime": 2700,

    // Define a single subnet.
      "subnet6": [
        {
          "id": 1,
          "pools": [
            {
              "pool": "2001:db8:1::/80",
              "user-context": { "charging": true }
            } ],
          "subnet": "2001:db8:1::/64",
          "interface": "eth0"
        }
      ],

    // Control sockets.
      "control-sockets": [
        {
          "socket-type": "https",
          "socket-address": "::1",
          "socket-port": 8000,
          "trust-anchor": "my-ca",
          "cert-file": "my-cert",
          "key-file": "my-key",
          "cert-required": true
        }
      ],

    // Add hooks here.
      "hooks-libraries": [
        {
          "library": "libdhcp_rbac.so",
          "parameters": {
              // This section configures the RBAC hook library.
              // Mandatory parameters.
              "assign-role-method": "cert-subject",
              "api-files": "/opt/share/kea/api",
              // Optional parameters.
              "require-tls": true,
              "commands": [
              {
                  "name": "my-command",
                  "access": "read",
                  "hook": "my-hook"
              } ],
              "access-control-lists": [
              {
                  "my-none": { "not": "ALL" }
              },{
                  "another-none": { "and": [ "ALL", "NONE" ] }
              },{
                  "my-read": { "access": "read" }
              } ],
              "roles": [
              {
                  "name": "kea-client",
                  "accept-commands":
                  {
                      "commands": [ "list-commands", "status-get" ]
                  },
                  "reject-commands": "NONE",
                  "other-commands": "reject",
                  "list-match-first": "accept",
                  "response-filters": [ "list-commands" ]
              },{
                  "name": "admin",
                  "accept-commands": "ALL",
                  "reject-commands":
                  {
                      "hook": "cb_cmds"
                  },
                  "list-match-first": "reject"
              } ],
              "default-role":
              {
                  "accept-commands": "NONE",
                  "reject-commands": "ALL"
              },
              "unknown-role":
              {
                  "accept-commands": "READ",
                  "reject-commands": "WRITE"
              }
          }
        }
      ]
    }

    }

.. _config-example-kea6-hooks-json:

---------------
kea6/hooks.json
---------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv6 server in Kea
    // illustrating the configuration of hook libraries.  It uses a basic scenario
    // of one IPv6 subnet configured with the default values for all parameters.

    {"Dhcp6":

    {
    // Kea is told to listen on the eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // Set up the storage for leases.
      "lease-database": {
        "type": "memfile"
      },

    // Set values to mandatory timers
      "renew-timer": 900,
      "rebind-timer": 1200,
      "preferred-lifetime": 1800,
      "valid-lifetime": 2700,

    // Define a single subnet.
      "subnet6": [
        {
          "id": 1,
          "pools": [
            {
              "pool": "2001:db8:1::/80",
              "user-context": { "charging": true }
            } ],
          "subnet": "2001:db8:1::/64",
          "interface": "eth0"
        }
      ],

    // Set up the hook libraries.  For this example, we assume that two libraries
    // are loaded, called "security" and "charging".  Note that order is important:
    // "security" is specified first so if both libraries supply a hook function
    // for a given hook, the function in "security" will be called before that in
    // "charging".

      "hooks-libraries": [
         {
            "library": "security.so"
         },
         {
            "library": "charging.so",
            "parameters": {
                 "path": "/var/log/kea",
                 "base-name": "kea-forensic6"
            }
         }
      ]
    }

    }

.. _config-example-kea6-iPXE-json:

--------------
kea6/iPXE.json
--------------

.. code-block::
    :linenos:

    // This is an example configuration for iPXE boot in Kea6.

    {
       "Dhcp6": {
       // Mandatory part of the config that list interfaces on which
       // Kea will listen for incoming traffic.
          "interfaces-config": {
             "interfaces": [ "eth0" ]
          },

    // Two classes are migrated form ISC-DHCP example:
    // if exists dhcp6.client-arch-type and
    //    option dhcp6.client-arch-type = 00:07 {
    //    option dhcp6.bootfile-url "http://[2001:db8::1]/ipxe.efi";
    // } else if exists dhcp6.user-class and
    //          substring(option dhcp6.user-class, 2, 4) = "iPXE" {
    //    option dhcp6.bootfile-url "http://[2001:db8::1]/ubuntu.cfg";
    // }

    // In example shown below incoming packet will receive value
    // http://[2001:db8::1]/ubuntu.cfg if incoming packet will include user
    // class option with "iPXE" in it and value http://[2001:db8::1]/ipxe.efi
    // if option client architecture type will be 7.
    // If incoming packet will include both of those options with matching
    // values it will be assigned to class "a-ipxe" because it was first
    // matching class. If you want to change that order names of the classes
    // have to have different alphabetical order. In Kea 1.3.0 (and previous
    // versions) alphabetical order is used in classification. Note this
    // should change in next versions, for instance to keep the definition
    // order.
          "client-classes": [
             {
                "name": "a-ipxe",
                // user-class option (code 15) is a tuple array
                // so we need to skip the length (tuple first element)
                "test": "substring(option[15].hex, 2, 4) == 'iPXE'",
                "option-data": [
                   {
                      "space": "dhcp6",
                      "name": "bootfile-url",
                      "code": 59,
                      "data": "http://[2001:db8::1]/ubuntu.cfg"
                   }
                ]
             },
             {
                "name": "b-efi",
                // please consider to add a not a-ipxe here to enforce
                // the "else"?
                "test": "option[61].hex == 0x0007",
                "option-data": [
                   {
                      "space": "dhcp6",
                      "name": "bootfile-url",
                      "code": 59,
                      "data": "http://[2001:db8::1]/ipxe.efi"
                   }
                ]
             }
          ],
          "subnet6": [
             {
                "id": 1,
                "subnet": "2001:db8::/64"
             }
          ]
       }
    }

.. _config-example-kea6-leases-expiration-json:

---------------------------
kea6/leases-expiration.json
---------------------------

.. code-block::
    :linenos:

    // This is an example configuration file for DHCPv6 server in Kea.
    // It provides parameters controlling processing of expired leases,
    // a.k.a. leases reclamation.

    { "Dhcp6":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // We need to specify the database used to store leases. As of
    // June 2022, three database backends are supported: MySQL,
    // PostgreSQL and the in-memory database, Memfile.
    // We'll use memfile because it doesn't require any prior set up.
    // Note, we're setting the maximum number of row read errors to 100,
    // (defaults to 0, meaning unlimited).
      "lease-database": {
          "type": "memfile",
          "lfc-interval": 3600,
          "max-row-errors": 100
      },

    // The following parameters control processing expired leases. Expired leases
    // will be reclaimed periodically according to the "reclaim-timer-wait-time"
    // parameter. Reclaimed leases will be held in the database for 1800s to
    // facilitate lease affinity. After this period the leases will be removed.
    // The frequency of removal is controlled by the
    // "flush-reclaimed-timer-wait-time" parameter. The lease reclamation
    // routine will process at most 500 leases or will last for at most
    // 100ms, during a single run. If there are still some unreclaimed
    // leases after 10 attempts, a warning message is issued.
    // If both "flush-reclaimed-timer-wait-time" and "hold-reclaimed-time" are not
    // 0, when the client sends a release message the lease is expired instead of
    // being deleted from lease storage.
      "expired-leases-processing": {
        "reclaim-timer-wait-time": 5,
        "hold-reclaimed-time": 1800,
        "flush-reclaimed-timer-wait-time": 10,
        "max-reclaim-leases": 500,
        "max-reclaim-time": 100,
        "unwarned-reclaim-cycles": 10
      },

    // Addresses will be assigned with preferred and valid lifetimes
    // being 3000 and 4000, respectively. Client is told to start
    // renewing after 1000 seconds. If the server does not respond
    // after 2000 seconds since the lease was granted, client is supposed
    // to start REBIND procedure (emergency renewal that allows switching
    // to a different server).
      "preferred-lifetime": 3000,
      "valid-lifetime": 4000,
      "renew-timer": 1000,
      "rebind-timer": 2000,

    // The following list defines subnets. Each subnet consists of at
    // least subnet and pool entries.
      "subnet6": [
        {
          "id": 1,
          "pools": [ { "pool": "2001:db8:1::/80" } ],
          "subnet": "2001:db8:1::/64",
          "interface": "eth0"
        }
      ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp6",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "debuglevel": 0,
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea6-multiple-options-json:

--------------------------
kea6/multiple-options.json
--------------------------

.. code-block::
    :linenos:

    // This is an example configuration file for DHCPv6 server in Kea.
    // It demonstrates simple configuration of the options for a subnet.

    { "Dhcp6":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // We need to specify the database used to store leases. As of
    // June 2022, three database backends are supported: MySQL,
    // PostgreSQL and the in-memory database, Memfile.
    // We'll use memfile because it doesn't require any prior set up.
      "lease-database": {
        "type": "memfile"
      },

    // Addresses will be assigned with preferred and valid lifetimes
    // being 3000 and 4000, respectively. Client is told to start
    // renewing after 1000 seconds. If the server does not respond
    // after 2000 seconds since the lease was granted, client is supposed
    // to start REBIND procedure (emergency renewal that allows switching
    // to a different server).
      "preferred-lifetime": 3000,
      "valid-lifetime": 4000,
      "renew-timer": 1000,
      "rebind-timer": 2000,

    // Defining a subnet. There are some DHCP options returned to the
    // clients connected to this subnet. The first option is identified
    // by the name. The second option is identified by the code.
    // There are two address pools defined within this subnet. Pool
    // specific value for option 12 is defined for the pool:
    // 2001:db8:1::1 - 2001:db8:1::100. Clients obtaining an address
    // from this pool will be assigned option 12 with a value of
    // 3001:cafe::21. Clients belonging to this subnet but obtaining
    // addresses from the other pool, or the clients obtaining
    // stateless configuration will be assigned subnet specific value
    // of option 12, i.e. 2001:db8:1:0:ff00::1.
    // For DHCPv6 subnets can have prefix delegation pools too so
    // a pd-pools with an option-data is defined too.
      "subnet6": [
        {
            // This is how option values are defined for this particular subnet.
            "option-data": [
                // When specifying options, you typically need to specify
                // one of (name or code) and data. The full option specification
                // covers name, code, space, csv-format and data.
                // space defaults to "dhcp6" which is usually correct, unless you
                // use encapsulate options. csv-format defaults to "true", so
                // this is also correct, unless you want to specify the whole
                // option value as long hex string. For example, to specify
                // domain-name-servers you could do this:
                // {
                //     "name": "dns-servers",
                //     "code": 23,
                //     "csv-format": true,
                //     "space": "dhcp6",
                //     "data": "2001:db8:2::45, 2001:db8:2::100"
                // }
                // but it's a lot of writing, so it's easier to do this instead:
                {
                    "name": "dns-servers",
                    "data": "2001:db8:2::45, 2001:db8:2::100"
                },

                // Typically people prefer to refer to options by their
                // names, so they don't need to remember the code
                // names. However, some people like to use numerical
                // values. For example, DHCPv6 can optionally use server
                // unicast communication, if extra option is present. Option
                // "unicast" uses option code 12, so you can reference to it
                // either by "name": "unicast" or "code": 12.
                {
                    "code": 12,
                    "data": "2001:db8:1:0:ff00::1"
                },

                // Options can also be specified using hexadecimal format.
                // This should be avoided if possible, because Kea ability to
                // validate correctness is limited when using hex values.
                {
                    "name": "sntp-servers",
                    "csv-format": false,
                    "data": "20010db8000000000000000000000001"
                },

                // String options that have a comma in their values need to have
                // it escaped (i.e. each comma is preceded by two backslashes).
                // That's because commas are reserved for separating fields in
                // compound options. At the same time, we need to be conformant
                // with JSON spec, that does not allow "\,". Therefore the
                // slightly uncommon double backslashes notation is needed.

                // Legal JSON escapes are \ followed by "\/bfnrt character
                // or \u followed by 4 hexa-decimal numbers (currently Kea
                // supports only \u0000 to \u00ff code points).
                // CSV processing translates '\\' into '\' and '\,' into ','
                // only so for instance '\x' is translated into '\x'. But
                // as it works on a JSON string value each of these '\'
                // characters must be doubled on JSON input.
                {
                    "name": "new-posix-timezone",
                    "data": "EST5EDT4\\,M3.2.0/02:00\\,M11.1.0/02:00"
                },

                // Options that take integer values can either be specified in
                // dec or hex format. Hex format could be either plain (e.g. abcd)
                // or prefixed with 0x (e.g. 0xabcd).
                {
                    "name": "preference",
                    "data": "0xf0"
                },

                // A few options are encoded in (length, string) tuples
                // which can be defined using only strings as the CSV
                // processing computes lengths.
                {
                    "name": "bootfile-param",
                    "data": "root=/dev/sda2, quiet, splash"
                },

                // At a few exceptions options are added to response only when
                // the client requests them. The always-send flag should be used
                // to enforce a particular option.
                {
                    "name": "pana-agent",
                    "data": "2001:db8:2::123",
                    "always-send": true
                }
          ],
          "pools": [
            {
                "pool": "2001:db8:1::1 - 2001:db8:1::100",
                "option-data": [
                  {
                      "code": 12,
                      "data": "3001:cafe::21"
                  }
                ]
            },
            {
                "pool": "2001:db8:1::500 - 2001:db8:1::1000"
            }
          ],
          "pd-pools": [
            {
                 "prefix": "2001:2b8:2::",
                 "prefix-len": 56,
                 "delegated-len": 64,
                 "option-data": [
                   {
                       "code": 12,
                       "data": "3001:cafe::12"
                   }
                 ]
             }
          ],
          "id": 1,
          "subnet": "2001:db8:1::/64",
          "interface": "eth0"
        }
      ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp6",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "debuglevel": 0,
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea6-mysql-reservations-json:

----------------------------
kea6/mysql-reservations.json
----------------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv6 server in Kea.
    // It contains configuration of the MySQL host database backend, used
    // to retrieve reserved addresses, host names, DHCPv4 message fields
    // and DHCP options from MySQL database.
    { "Dhcp6":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // We need to specify the database used to store leases. As of
    // June 2022, three database backends are supported: MySQL,
    // PostgreSQL and the in-memory database, Memfile.
    // We'll use memfile because it doesn't require any prior set up.
      "lease-database": {
          "type": "memfile",
          "lfc-interval": 3600
      },

    // This is pretty basic stuff, it has nothing to do with reservations.
      "preferred-lifetime": 3000,
      "valid-lifetime": 4000,
      "renew-timer": 1000,
      "rebind-timer": 2000,

    // Kea supports two types of identifiers in DHCPv6: hw-address
    // (hardware/MAC address of the client) and duid (DUID inserted by the
    // client). When told to do so, Kea can check for each of these
    // identifier types, but it takes a costly database lookup to do so. It
    // is therefore useful from a performance perspective to use only the
    // reservation types that are actually used in a given network.
        "host-reservation-identifiers": [ "duid", "hw-address" ],

    // Specify connection to the database holding host reservations. The type
    // specifies that the MySQL database is used. user and password are the
    // credentials used to connect to the database. host and name specify
    // location of the host where the database instance is running, and the
    // name of the database to use. The server processing a packet will first
    // check if there are any reservations specified for this client in the
    // reservations list, within the subnet (configuration file). If there are
    // no reservations there, the server will try to retrieve reservations
    // from this database.
      "hosts-database": {
        "type": "mysql",
        "reconnect-wait-time": 3000, // expressed in ms
        "max-reconnect-tries": 3,
        "name": "keatest",
        "user": "keatest",
        "password": "1234",
        "host": "localhost",
        "port": 3306,
        "readonly": true,
        "trust-anchor": "my-ca",
        "cert-file": "my-cert",
        "key-file": "my-key",
        "cipher-list": "AES"
      },
    // Since Kea.2.7.4, the libdhcp_mysql.so hook library must be loaded in order to
    // store host reservations in the MySQL Host Database Backend.
    // Specify the host backend hook library location.
      "hooks-libraries": [
        {
            // the MySQL host backend hook library required for host storage.
            "library": "libdhcp_mysql.so"
        }
      ],

    // Define a subnet with a pool of dynamic addresses and a pool of dynamic
    // prefixes. Addresses and prefixes from those pools will be assigned to
    // clients which don't have reservations in the database. Subnet identifier
    // is equal to 1. If this subnet is selected for the client, this subnet
    // id will be used to search for the reservations within the database.
      "subnet6": [
        {
          "subnet": "2001:db8:1::/48",

          "pools": [ { "pool": "2001:db8:1::/80" } ],

          "pd-pools": [
              {
                  "prefix": "2001:db8:1:8000::",
                  "prefix-len": 56,
                  "delegated-len": 64
              }
          ],
          "interface": "eth0",
          "id": 1
        }
      ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp6",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "debuglevel": 0,
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea6-pgsql-reservations-json:

----------------------------
kea6/pgsql-reservations.json
----------------------------

.. code-block::
    :linenos:

    // This is an example configuration file for the DHCPv6 server in Kea.
    // It contains configuration of the PostgreSQL host database backend, used
    // to retrieve reserved addresses, host names, DHCPv4 message fields
    // and DHCP options from PostgreSQL database.
    { "Dhcp6":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // We need to specify the database used to store leases. As of
    // June 2022, three database backends are supported: MySQL,
    // PostgreSQL and the in-memory database, Memfile.
    // We'll use memfile because it doesn't require any prior set up.
      "lease-database": {
        "type": "memfile"
      },

    // This is pretty basic stuff, it has nothing to do with reservations.
      "preferred-lifetime": 3000,
      "valid-lifetime": 4000,
      "renew-timer": 1000,
      "rebind-timer": 2000,

    // Kea supports two types of identifiers in DHCPv6: hw-address
    // (hardware/MAC address of the client) and duid (DUID inserted by the
    // client). When told to do so, Kea can check for each of these
    // identifier types, but it takes a costly database lookup to do so. It
    // is therefore useful from a performance perspective to use only the
    // reservation types that are actually used in a given network.
        "host-reservation-identifiers": [ "duid", "hw-address" ],

    // Specify connection to the database holding host reservations. The type
    // specifies that the PostgreSQL database is used. user and password are the
    // credentials used to connect to the database. host and name specify
    // location of the host where the database instance is running, and the
    // name of the database to use. The server processing a packet will first
    // check if there are any reservations specified for this client in the
    // reservations list, within the subnet (configuration file). If there are
    // no reservations there, the server will try to retrieve reservations
    // from this database.
    // The database specification can go into one hosts-database entry for
    // backward compatibility or be listed in hosts-databases list.
      "hosts-databases": [
        {
           "type": "postgresql",
           "reconnect-wait-time": 3000, // expressed in ms
           "max-reconnect-tries": 3,
           "name": "keatest",
           "user": "keatest",
           "password": "1234",
           "host": "localhost"
        }
      ],
    // Since Kea.2.7.4, the libdhcp_pgsql.so hook library must be loaded in order to
    // store host reservations in the PostgreSQL Host Database Backend.
    // Specify the host backend hook library location.
      "hooks-libraries": [
        {
            // the PostgreSQL host backend hook library required for host storage.
            "library": "libdhcp_pgsql.so"
        }
      ],

    // Define a subnet with a pool of dynamic addresses and a pool of dynamic
    // prefixes. Addresses and prefixes from those pools will be assigned to
    // clients which don't have reservations in the database. Subnet identifier
    // is equal to 1. If this subnet is selected for the client, this subnet
    // id will be used to search for the reservations within the database.
      "subnet6": [
        {
          "subnet": "2001:db8:1::/48",

          "pools": [ { "pool": "2001:db8:1::/80" } ],

          "pd-pools": [
              {
                  "prefix": "2001:db8:1:8000::",
                  "prefix-len": 56,
                  "delegated-len": 64
              }
          ],
          "interface": "eth0",
          "id": 1
        }
      ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp6",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "debuglevel": 0,
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea6-reservations-json:

----------------------
kea6/reservations.json
----------------------

.. code-block::
    :linenos:

    // This is an example configuration file for DHCPv6 server in Kea
    // that showcases how to do host reservations. It is
    // assumed that one subnet (2001:db8:1::/64) is available directly
    // over eth0 interface. A number of hosts have various combinations
    // of addresses and prefixes reserved for them.

    { "Dhcp6":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // We need to specify the database used to store leases. As of
    // June 2022, three database backends are supported: MySQL,
    // PostgreSQL and the in-memory database, Memfile.
    // We'll use memfile because it doesn't require any prior set up.
      "lease-database": {
          "type": "memfile",
          "lfc-interval": 3600
      },

    // This is pretty basic stuff, it has nothing to do with reservations.
      "preferred-lifetime": 3000,
      "valid-lifetime": 4000,
      "renew-timer": 1000,
      "rebind-timer": 2000,

    // Kea supports three types of identifiers in DHCPv6: hw-address (hardware/MAC
    // address of the client), duid (DUID inserted by the client) and flex-id
    // (flexible identifier available when flex_id hook library is loaded) When told
    // to do so, Kea can check for each of these identifier types, but it takes a
    // costly database lookup to do so. It is therefore useful from a performance
    // perspective to use only the reservation types that are actually used in a
    // given network.
        "host-reservation-identifiers": [ "duid", "hw-address", "flex-id" ],

    // The following list defines subnets. Subnet, pools and interface definitions
    // are the same as in the regular scenario, without host reservations.
    // least subnet and pool entries.
      "subnet6": [
        {
            "id": 1,

            "subnet": "2001:db8:1::/48",

            // This directive tells Kea that reservations may be made both in-pool
            // and out-of-pool. For improved performance, you may move all reservations
            // out of the dynamic pool and set "reservations-out-of-pool" to true.
            // Kea will then be able to skip querying for host reservations when
            // assigning leases from dynamic pool.

            // Specify whether the server should look up global reservations.
            // Defaults to false.
            "reservations-global": false,

            // Specify whether the server should look up in-subnet reservations.
            // Defaults to true.
            "reservations-in-subnet": true,

            // Specify whether the server can assume that all reserved addresses
            // are out-of-pool. Defaults to false.
            // Ignored when reservations-in-subnet is false.
            // If specified, it is inherited by "shared-networks" and
            // "subnet6" levels.
            "reservations-out-of-pool": false,

            "pools": [ { "pool": "2001:db8:1::/120" } ],

            "pd-pools": [
              {
                  "prefix": "2001:db8:1:8000::",
                  "prefix-len": 56,
                  "delegated-len": 64
              }
            ],
            "interface": "eth0",

    // Host reservations. Define several reservations, note that
    // they are all within the range of the pool of the dynamically
    // allocated address. The server will exclude the addresses from this
    // pool and only assign them to the client which has a reservation for
    // them.
           "reservations": [
    // This is a simple host reservation. The host with DUID matching
    // the specified value will get an address of 2001:db8:1::100.
              {
                  "duid": "01:02:03:04:05:0A:0B:0C:0D:0E",
                  "ip-addresses": [ "2001:db8:1::100" ]
              },
    // This is similar to the previous one, but this time the reservation
    // is done based on hardware/MAC address. The server will do its best to
    // extract the hardware/MAC address from received packets (see
    // 'mac-sources' directive for details). This particular reservation
    // also specifies two extra options to be available for this client. If
    // there are options with the same code specified in a global, subnet or
    // class scope, the values defined at host level take precedence.
              {
                  "hw-address": "00:01:02:03:04:05",
                  "ip-addresses": [ "2001:db8:1::101" ],
                  "option-data": [
                  {
                      "name": "dns-servers",
                      "data": "3000:1::234"
                  },
                  {
                      "name": "nis-servers",
                      "data": "3000:1::234"
                  } ],
                  "client-classes": [ "special_snowflake", "office" ]
              },
    // This is a bit more advanced reservation. The client with the specified
    // DUID will get a reserved address, a reserved prefix and a hostname.
    // This reservation is for an address that it not within the dynamic pool.
    // Finally, this reservation features vendor specific options for CableLabs,
    // which happen to use enterprise-id 4491. Those particular values will
    // be returned only to the client that has a DUID matching this reservation.
              {
                  "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"
                  } ]

              },
    // This reservation is using flexible identifier. Instead of relying
    // on specific field, sysadmin can define an expression similar to what
    // is used for client classification,
    // e.g. substring(relay[0].option[17],0,6). Then, based on the value of
    // that expression for incoming packet, the reservation is matched.
    // Expression can be specified either as hex or plain text using single
    // quotes.
    // Note: flexible identifier requires flex_id hook library to be
    // loaded to work.
             {
                 "flex-id": "'somevalue'",
                 "ip-addresses": [ "2001:db8:1:cafe::2" ]
             }

          ]
        }
      ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp6",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "debuglevel": 0,
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea6-several-subnets-json:

-------------------------
kea6/several-subnets.json
-------------------------

.. code-block::
    :linenos:

    // This is an example configuration file for DHCPv6 server in Kea.
    // It's a basic scenario with four IPv6 subnets configured. In each
    // subnet, there's a smaller pool of dynamic addresses.

    { "Dhcp6":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // We need to specify the database used to store leases. As of
    // June 2022, three database backends are supported: MySQL,
    // PostgreSQL and the in-memory database, Memfile.
    // We'll use memfile because it doesn't require any prior set up.
      "lease-database": {
        "type": "memfile"
      },

    // Addresses will be assigned with preferred and valid lifetimes
    // being 3000 and 4000, respectively. Client is told to start
    // renewing after 1000 seconds. If the server does not respond
    // after 2000 seconds since the lease was granted, client is supposed
    // to start REBIND procedure (emergency renewal that allows switching
    // to a different server).
      "preferred-lifetime": 3000,
      "valid-lifetime": 4000,
      "renew-timer": 1000,
      "rebind-timer": 2000,

    // The following list defines subnets. Each subnet consists of at
    // least subnet and pool entries.
      "subnet6": [
      {    "pools": [ { "pool": "2001:db8:1::/80" } ],
           "id": 1, "subnet": "2001:db8:1::/64"  },
      {    "pools": [ { "pool": "2001:db8:2::/80" } ],
           "id": 2, "subnet": "2001:db8:2::/64"  },
      {    "pools": [ { "pool": "2001:db8:3::/80" } ],
           "id": 3, "subnet": "2001:db8:3::/64"  },
      {    "pools": [ { "pool": "2001:db8:4::/80" } ],
           "id": 4, "subnet": "2001:db8:4::/64"  } ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
      "loggers": [
            {
                "name": "kea-dhcp6",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "debuglevel": 0,
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea6-shared-network-json:

------------------------
kea6/shared-network.json
------------------------

.. code-block::
    :linenos:

    // This is an example configuration file for DHCPv6 server in Kea.
    // It demonstrates an advanced feature called shared network. Typically, for
    // each physical link there is one IPv6 subnet that the server is expected
    // to manage. However, in some cases there is a need to configure more subnets
    // in the same physical location. This may sound odd, as IPv6 is not expected
    // to run out of addresses. However, due to vast address space some deployments
    // experiment with various addressing schemes and later find out that the
    // initial proposal was not best and way to migrate to something else.
    {
        "Dhcp6": {
            // Kea is told to listen on eth0 interface only.
            "interfaces-config": {
                "interfaces": [ "eth0" ]
            },

            // You also need to tell where to store lease information.
            // memfile is the backend that is easiest to set up.
            "lease-database": {
                "type": "memfile",
                "lfc-interval": 3600
            },

            // It is likely that in your network you'll have a mix of regular,
            // "plain" subnets and shared networks. It is perfectly valid to mix
            // them in the same config file.

            // This is regular subnet. It's not part of any shared-network.
            "subnet6": [
                {
                    "id": 1,
                    "pools": [ { "pool": "2001:db8:2::/80" } ],
                    "subnet": "2001:db8:2::/64",
                    "interface": "eth0"
                }
            ],

            // Hhe shared networks definition starts here. shared-networks can
            // contain a list of shared networks. There are many parameters
            // that can be specified here, so this example may be overwhelming
            // at first, but the only mandatory parameter for each shared
            // network is name. It must be unique. Typically, each shared
            // network also needs to have at least two subnets to be functional,
            // but if you really want to, you can define a degraded shared
            // network that has 1 or even 0 subnets. This may come in handy
            // when migrating between regular subnets and shared networks
            // or when debugging a problem. It is not recommended to use
            // 1 subnet per shared network, as there is extra processing
            // overhead for shared networks.
            "shared-networks": [
            {
                "interface": "eth1",

                // Similar to regular subnets, it is forbidden to define both
                // interface and interface-id at the same time. That's because
                // interface parameter expresses physical network interface
                // for links available locally and interface-id identifies
                // values inserted by relays, which are only used for
                // remote traffic. A shared network cannot be both direct
                // and relayed.
                // "interface-id": "content of the option",

                // Other parameters defined here will be inherited by the
                // subnets.
                "name": "frog",
                "option-data": [ ],
                "preferred-lifetime": 200,
                "rapid-commit": true,
                "rebind-timer": 150,
                "relay": {
                    "ip-addresses": [ "2001:db8::1" ]
                },
                "renew-timer": 100,

                // Specify whether the server should look up global reservations.
                "reservations-global": false,

                // Specify whether the server should look up in-subnet reservations.
                "reservations-in-subnet": true,

                // Specify whether the server can assume that all reserved addresses
                // are out-of-pool.
                // Ignored when reservations-in-subnet is false.
                // If specified, it is inherited by "subnet6" levels.
                "reservations-out-of-pool": false,

                // List of subnets belonging to this particular shared-network
                // start here.
                "subnet6": [

                    // This is the first subnet.
                    {
                        "preferred-lifetime": 30,
                        "rapid-commit": false,
                        "rebind-timer": 20,
                        // It is possible to override some values here.
                        "relay": {
                            "ip-addresses": [ "2001:db8:1::123" ]
                        },
                        "renew-timer": 10,
                        // Specify whether the server should look up global reservations.
                        "reservations-global": false,
                        // Specify whether the server should look up in-subnet reservations.
                        "reservations-in-subnet": true,
                        // Specify whether the server can assume that all reserved addresses
                        // are out-of-pool.
                        // Ignored when reservations-in-subnet is false.
                        "reservations-out-of-pool": false,
                        "id": 2,
                        "subnet": "2001:db8:1::/64",
                        "pools": [ { "pool": "2001:db8:1:0:abcd::/80" } ],
                        "valid-lifetime": 40
                    },

                    // This is the second subnet.
                    {
                        "preferred-lifetime": 30,
                        "pools": [ { "pool": "3000:db8::/64" } ],
                        "rapid-commit": false,
                        "rebind-timer": 20,
                        "relay": {
                            "ip-addresses": [ "3000::1" ]
                        },
                        "renew-timer": 10,
                        // Specify whether the server should look up global reservations.
                        "reservations-global": false,
                        // Specify whether the server should look up in-subnet reservations.
                        "reservations-in-subnet": true,
                        // Specify whether the server can assume that all reserved addresses
                        // are out-of-pool.
                        // Ignored when reservations-in-subnet is false.
                        "reservations-out-of-pool": false,
                        "id": 3,
                        "subnet": "3000::/16",
                        "valid-lifetime": 40
                    }
                ],
                "valid-lifetime": 300
            } ]
        }
    }

.. _config-example-kea6-simple-json:

----------------
kea6/simple.json
----------------

.. code-block::
    :linenos:

    // This is an example configuration file for DHCPv6 server in Kea.
    // It's a basic scenario with one IPv6 subnet configured. It is
    // assumed that one subnet (2001:db8:1::/64 is available directly
    // over eth0 interface.

    { "Dhcp6":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // We need to specify the database used to store leases. As of
    // June 2022, three database backends are supported: MySQL,
    // PostgreSQL and the in-memory database, Memfile.
    // We'll use memfile because it doesn't require any prior set up.
      "lease-database": {
          "type": "memfile",
          "lfc-interval": 3600
      },

    // Addresses will be assigned with preferred and valid lifetimes
    // being 3000 and 4000, respectively. Client is told to start
    // renewing after 1000 seconds. If the server does not respond
    // after 2000 seconds since the lease was granted, client is supposed
    // to start REBIND procedure (emergency renewal that allows switching
    // to a different server).
      "preferred-lifetime": 3000,
      "valid-lifetime": 4000,
      "renew-timer": 1000,
      "rebind-timer": 2000,

    // The following list defines subnets. Each subnet consists of at
    // least subnet and pool entries.
      "subnet6": [
        {
          "id": 1,
          "pools": [ { "pool": "2001:db8:1::/80" } ],
          "subnet": "2001:db8:1::/64",
          "interface": "eth0"
        }
      ],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout. Alternatively, you can specify stderr here, a filename
    // or 'syslog', which will store output messages via syslog.
        "loggers": [
            {
                "name": "kea-dhcp6",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "debuglevel": 0,
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea6-softwire46-json:

--------------------
kea6/softwire46.json
--------------------

.. code-block::
    :linenos:

    // This is an example configuration file for DHCPv6 server in Kea.
    // It demonstrates how user can specify values for Softwire options
    // defined in RFC 7598 for Lightweight 4over6 architecture.

    { "Dhcp6":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // Let's use a Memfile backend to store leases.
      "lease-database": {
        "type": "memfile"
      },

    // Addresses will be assigned with preferred and valid lifetimes
    // being 3000 and 4000, respectively. Client is told to start
    // renewing after 1000 seconds. If the server does not respond
    // after 2000 seconds since the lease was granted, client is supposed
    // to start REBIND procedure (emergency renewal that allows switching
    // to a different server).
      "preferred-lifetime": 3000,
      "valid-lifetime": 4000,
      "renew-timer": 1000,
      "rebind-timer": 2000,

    // The following list defines subnets. Each subnet consists of at
    // least subnet and pool entries.
      "subnet6": [
        {
          "id": 1,
          "pools": [ { "pool": "2001:db8:1::/80" } ],
          "subnet": "2001:db8:1::/64",
          "interface": "eth0",
    // Include MAP-E Container option for hosts connected to this subnet.
          "option-data": [
            {
                "name": "s46-cont-mape"
            }
          ],
    // Send host specific softwire options.
          "reservations": [
            {
                "duid": "01:02:03:04:05:06:07:08:09:0A",
                "option-data": [
    // These two options will be included in the MAP-E Container
                  {
                    "space": "s46-cont-mape-options",
                    "name": "s46-rule",
                    "data": "1, 0, 24, 192.0.2.0, 2001:db8:1::/64"
                  },
                  {
                    "space": "s46-cont-mape-options",
                    "name": "s46-br",
                    "data": "2001:db8:cafe::1"
                  },
    // This option will be included in the S46 Rule option. It includes
    // PSID/PSID length value in a user friendly form. The PSID length
    // specifies the number of bits on which PSID is coded. The PSID
    // value 3 is a 4th value that is coded on these 4 bits: "0011b".
                  {
                    "space": "s46-rule-options",
                    "name": "s46-portparams",
                    "data": "0, 3/4"
                  }
                ]
            }
          ]
        }
      ],

    // The following configures logging. Kea will log all debug messages
    // to /var/log/kea/kea-debug.log file.
        "loggers": [
            {
                "name": "kea-dhcp6",
                "output-options": [
                    {
                        "output": "/var/log/kea/kea-debug.log"
                    }
                ],
                "debuglevel": 99,
                "severity": "DEBUG"
            }
        ]
    }

    }

.. _config-example-kea6-stateless-json:

-------------------
kea6/stateless.json
-------------------

.. code-block::
    :linenos:

    // A very simply stateless configuration that provides information about DNS
    // servers to all clients, regardless of their point of attachment.
    //
    // It is also possible to specify options on a per subnet basis
    // in the same way as in stateful mode.
    //

    {
    "Dhcp6": {
        "interfaces-config": {
            "interfaces": [ "eth0" ]
        },

    // This is the list of options that will be granted to all clients that ask.
        "option-data": [ {
            "name": "dns-servers",
            "data": "2001:db8::1, 2001:db8::2"
        } ],

    // Kea 0.9.1 requires lease-database to be specified, even it is not used.
    // In stateless mode, only options are granted, not addresses or
    // prefixes, so there will be no leases (unless stateless and stateful
    // mode is used together).
        "lease-database": {
            "type": "memfile",
            "lfc-interval": 3600
        }
    }
    }

.. _config-example-kea6-tee-times-json:

-------------------
kea6/tee-times.json
-------------------

.. code-block::
    :linenos:

    // This is an example configuration file for DHCPv6 server in Kea.
    // It's a basic scenario with three IPv6 subnets use different
    // methods for determining T1 and T2 values.

    { "Dhcp6":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // We need to specify the database used to store leases. As of
    // June 2022, three database backends are supported: MySQL,
    // PostgreSQL and the in-memory database, Memfile.
    // We'll use memfile because it doesn't require any prior set up.
      "lease-database": {
        "type": "memfile"
      },

    // Addresses will be assigned with preferred and valid lifetimes
    // being 3000 and 4000, respectively.  By default calculate-tee-times
    // is true with values of .5 and .8 for t1-percent and t2-percent
    // respectively.  Since some of our subnets will use calculated values and
    // we must NOT specify global values for renew-timer and rebind-timer.
      "preferred-lifetime": 3000,
      "valid-lifetime": 4000,

    // The following list defines subnets. Each subnet consists of at
    // least subnet and pool entries.
      "subnet6": [
      {
            //  This subnet use default calculation
            "id": 1,
            "subnet": "2001:db8:1::/64",
            "pools": [ { "pool": "2001:db8:1::/80" } ]
      },
      {
            // This subnet will use explicit values. Explicit
            // values override calculation.
           "id": 2,
           "subnet": "2001:db8:2::/64",
           "pools": [ { "pool": "2001:db8:2::/80" } ],
           "renew-timer":  1000,
           "rebind-timer": 2000
      },
      {
            // This subnet will use custom percents
           "id": 3,
           "subnet": "2001:db8:3::/64",
           "pools": [ { "pool": "2001:db8:3::/80" } ],
           "t1-percent": .45,
           "t2-percent": .7
      }],

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp6",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "debuglevel": 0,
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-kea6-with-ddns-json:

-------------------
kea6/with-ddns.json
-------------------

.. code-block::
    :linenos:

    // This is an example configuration file for DHCPv6 server in Kea.
    // It's a basic scenario with one IPv6 subnet configured. It is
    // assumed that one subnet (2001:db8:1::/64 is available directly
    // over eth0 interface.

    { "Dhcp6":

    {
    // Kea is told to listen on eth0 interface only.
      "interfaces-config": {
        "interfaces": [ "eth0" ]
      },

    // We need to specify the database used to store leases. As of
    // June 2022, three database backends are supported: MySQL,
    // PostgreSQL and the in-memory database, Memfile.
    // We'll use memfile because it doesn't require any prior set up.
      "lease-database": {
          "type": "memfile",
          "lfc-interval": 3600
      },

    // Addresses will be assigned with preferred and valid lifetimes
    // being 3000 and 4000, respectively. Client is told to start
    // renewing after 1000 seconds. If the server does not respond
    // after 2000 seconds since the lease was granted, client is supposed
    // to start REBIND procedure (emergency renewal that allows switching
    // to a different server).
      "preferred-lifetime": 3000,
      "valid-lifetime": 4000,
      "renew-timer": 1000,
      "rebind-timer": 2000,

    // The following list defines subnets. Each subnet consists of at
    // least subnet and pool entries.
      "subnet6": [
        {
          "pools": [ { "pool": "2001:db8:1::/80" } ],
          "id": 1,
          "subnet": "2001:db8:1::/64",
          "interface": "eth0"
        }
      ],

    // Enable connectivity with kea-dhcp-ddns
    // (Required for dynamic DNS updates)
      "dhcp-ddns" : {
            "enable-updates" : true,
            "server-ip" : "3001::1",
            "server-port" : 3432,
            "sender-ip" : "3001::2",
            "sender-port" : 3433,
            "max-queue-size" : 2048,
            "ncr-protocol" : "UDP",
            "ncr-format" : "JSON"
      },


    // Enable DDNS updates and configure DDNS update behavior
      "ddns-send-updates" : true,
      "ddns-override-no-update" : true,
      "ddns-override-client-update" : true,
      "ddns-replace-client-name" : "when-present",
      "ddns-generated-prefix" : "test.prefix",
      "ddns-qualifying-suffix" : "test.suffix.",
      "ddns-update-on-renew" : false,
      "ddns-conflict-resolution-mode": "check-with-dhcid",
      "ddns-ttl-percent" : 0.75,
      "hostname-char-set": "[^A-Za-z0-9.-]",
      "hostname-char-replacement": "x",

    // The following configures logging. It assumes that messages with at
    // least informational level (info, warn, error and fatal) should be
    // logged to stdout.
        "loggers": [
            {
                "name": "kea-dhcp6",
                "output-options": [
                    {
                        "output": "stdout"
                    }
                ],
                "debuglevel": 0,
                "severity": "INFO"
            }
        ]
    }

    }

.. _config-example-netconf:

=======
netconf
=======

.. _config-example-netconf-comments-json:

---------------------
netconf/comments.json
---------------------

.. code-block::
    :linenos:

    // This is a example of a configuration for Netconf.
    // It uses embedded (i.e., which will be included in configuration objects
    // and not stripped by at lexical analysis) comments.

    {
        "Netconf":
        {
            // Global scope
            "comment": "The Netconf Agent",

            // In servers
            "managed-servers":
            {
                "dhcp4":
                {
                    "comment": "the model is mandatory",
                    "model": "kea-dhcp4-server",
                    // In control socket.
                    "control-socket":
                    {
                        "comment": "using unix/local socket",
                        "socket-type": "unix",
                        "socket-name": "kea4-ctrl-socket"
                    }
                }
            },

            // In loggers
            "loggers": [
                {
                    "comment": "A logger",
                    "name": "kea-netconf"
                }
            ]
        }
    }

.. _config-example-netconf-kea-dhcp6-operations:

----------------------------
netconf/kea-dhcp6-operations
----------------------------

.. _config-example-netconf-kea-dhcp6-operations-boot-json:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
netconf/kea-dhcp6-operations/boot.json
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. code-block::
    :linenos:

    {
        "Dhcp6": {
            "control-socket": {
                "socket-type": "unix",
                "socket-name": "kea6-ctrl-socket"
            }
        }
    }

.. _config-example-netconf-kea-dhcp6-operations-netconf-json:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
netconf/kea-dhcp6-operations/netconf.json
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. code-block::
    :linenos:

    {
        "Netconf":
        {
            "managed-servers":
            {
                "dhcp6":
                {
                    "control-socket":
                    {
                        "socket-type": "unix",
                        "socket-name": "kea6-ctrl-socket"
                    }
                }
            },

            "loggers":
            [
                {
                    "name": "kea-netconf",
                    "output-options":
                    [
                        {
                            "output": "stderr"
                        }
                    ],
                    "severity": "DEBUG",
                    "debuglevel": 99
                }
            ]
        }
    }

.. _config-example-netconf-simple-dhcp4-json:

-------------------------
netconf/simple-dhcp4.json
-------------------------

.. code-block::
    :linenos:

    // This is a simple example of a configuration for Netconf that handles
    // DHCPv4 configuration. This example provides YANG interface for
    // DHCPv4 server only.
    {
        "Netconf":
        {
            // Three flags control netconf (default values are true):
            // - "boot-update" about the YANG configuration load when
            //   netconf boots.
            // - "subscribe-changes" about the subscription to notifications
            //   when the running YANG module is changed.
            // - "validate-changes" allows to validate changes or not.
            "boot-update": true,
            "subscribe-changes": true,
            "validate-changes": true,

            // This map specifies how each server is managed:
            // the YANG model to use and the control channel.
            "managed-servers":
            {
                // This is how Netconf can communicate with the DHCPv4 server.
                "dhcp4":
                {
                    // Eventually, the kea-netconf will be able to handle multiple
                    // models. However, for the time being the only choice for
                    // DHCPv4 server is kea-dhcp4-server model.
                    "model": "kea-dhcp4-server",

                    // The three control flags can be defined in this scope too
                    // and takes precedence over global and default values.
                    // boot-update determines whether the initial configuration
                    // should be retrieved from netconf during kea-netconf startup.
                    // You almost always want to set this to yes.
                    "boot-update": true,

                    // This flag control whether the kea-netconf daemon should
                    // subscribe to any changes. If set to true, kea-netconf will
                    // monitor sysrepo and will pick up any changes that may be
                    // introduced, either using netconf clients or sysrepocfg.
                    "subscribe-changes": true,

                    // This parameters specifies whether kea-netconf will attempt
                    // to verify if the upcoming NETCONF configuration is sane. The
                    // verification is done by calling config-test. Depending on
                    // Kea response, the new configuration is accepted or rejected.
                    "validate-changes": false,

                    // Currently three control channel types are supported:
                    // - "stdout" which output the configuration on the standard
                    //   output (this is mainly for testing purposes, but you can
                    //   use simple script (such as curl or socat) to pass that
                    //   information to the server.
                    // - "unix" which uses the local control channel supported by
                    //   "dhcp4" and "dhcp6" servers ("d2" support is coming in Kea 1.5)
                    // - "http" (not yet supported?).
                    "control-socket":
                    {
                        "socket-type": "unix",
                        "socket-name": "kea4-ctrl-socket"
                    },

                    // Comment is optional. You can put some notes here.
                    "comment": "Kea DHCPv4 server serving network on floor 13"
                }

            },

            // Netconf is able to load hook libraries that augment its operation.
            // The primary functionality is the ability to add new commands.

            // Uncomment this section to load a hook library.

            // "hooks-libraries": [
            //    // Hook libraries list may contain more than one library.
            //    {
            //        // The only necessary parameter is the library filename.
            //        "library": "netconf-commands.so",

            //        // Some libraries may support parameters. Make sure you
            //        // type this section carefully, as the server does not validate
            //        // it (because the format is library-specific).
            //        "parameters": {
            //            "param1": "foo"
            //        }
            //    }
            // ]

            // Similar to other Kea components, Netconf also uses logging.
            "loggers": [
                {
                    "name": "kea-netconf",
                    "output-options": [
                        {
                            // "output": "/var/log/kea/kea-netconf.log",
                            "output": "stdout",
                            // Several additional parameters are possible in addition
                            // to the typical output. Flush determines whether logger
                            // flushes output to a file. Maxsize determines maximum
                            // filesize before the file is rotated. maxver
                            // specifies the maximum number of rotated files being
                            // kept.
                            "flush": true,
                            "maxsize": 204800,
                            "maxver": 4,
                             // We use pattern to specify custom log message layout
                            "pattern": "%d{%y.%m.%d %H:%M:%S.%q} %-5p [%c/%i] %m\n"
                        }
                    ],
                    // You can change the severity to DEBUG, INFO, WARN, ERROR or
                    // CRIT. For DEBUG level, you can also additionally specify
                    // debuglevel (0-99, higher = more verbose). All configurations
                    // are logged on DEBUG/55.
                    "severity": "INFO",
                    "debuglevel": 0
                }
            ]
        }
    }

.. _config-example-netconf-simple-dhcp6-json:

-------------------------
netconf/simple-dhcp6.json
-------------------------

.. code-block::
    :linenos:

    // This is a simple example of a configuration for Netconf that handles
    // DHCPv6 configuration. This example provides YANG interface for
    // DHCPv6 server only.
    {
        "Netconf":
        {
            // Three flags control netconf (default values are true):
            // - "boot-update" about the YANG configuration load when
            //   netconf boots.
            // - "subscribe-changes" about the subscription to notifications
            //   when the running YANG module is changed.
            // - "validate-changes" allows to validate changes or not.
            "boot-update": true,
            "subscribe-changes": true,
            "validate-changes": true,

            // This map specifies how each server is managed:
            // the YANG model to use and the control channel.
            "managed-servers":
            {
                // This is how Netconf can communicate with the DHCPv6 server.
                "dhcp6":
                {
                    // Eventually, the kea-netconf will be able to handle multiple
                    // models. However, for the time being the choices for
                    // DHCPv6 server are kea-dhcp6-server and
                    // ietf-dhcpv6-server models but only the first is usable.
                    "model": "kea-dhcp6-server",

                    // The three control flags can be defined in this scope too
                    // and takes precedence over global and default values.
                    // boot-update determines whether the initial configuration
                    // should be retrieved from netconf during kea-netconf startup.
                    // You almost always want to set this to yes.
                    "boot-update": true,

                    // This flag control whether the kea-netconf daemon should
                    // subscribe to any changes. If set to true, kea-netconf will
                    // monitor sysrepo and will pick up any changes that may be
                    // introduced, either using netconf clients or sysrepocfg.
                    "subscribe-changes": true,

                    // This parameters specifies whether kea-netconf will attempt
                    // to verify if the upcoming NETCONF configuration is sane. The
                    // verification is done by calling config-test. Depending on
                    // Kea response, the new configuration is accepted or rejected.
                    "validate-changes": false,

                    // Currently three control channel types are supported:
                    // - "stdout" which output the configuration on the standard
                    //   output (this is mainly for testing purposes, but you can
                    //   use simple script (such as curl or socat) to pass that
                    //   information to the server.
                    // - "unix" which uses the local control channel supported by
                    //   "dhcp4" and "dhcp6" servers ("d2" support is coming in Kea 1.5)
                    // - "http" (not yet supported?).
                    "control-socket":
                    {
                        "socket-type": "unix",
                        "socket-name": "kea6-ctrl-socket"
                    },

                    // Comment is optional. You can put some notes here.
                    "comment": "Kea DHCPv6 server serving network on floor 13"
                }

            },

            // Netconf is able to load hook libraries that augment its operation.
            // The primary functionality is the ability to add new commands.

            // Uncomment this section to load a hook library.

            // "hooks-libraries": [
            //    // Hook libraries list may contain more than one library.
            //    {
            //        // The only necessary parameter is the library filename.
            //        "library": "netconf-commands.so",

            //        // Some libraries may support parameters. Make sure you
            //        // type this section carefully, as the server does not validate
            //        // it (because the format is library-specific).
            //        "parameters": {
            //            "param1": "foo"
            //        }
            //    }
            // ]

            // Similar to other Kea components, Netconf also uses logging.
            "loggers": [
                {
                    "name": "kea-netconf",
                    "output-options": [
                        {
                            // "output": "/var/log/kea/kea-netconf.log",
                            "output": "stdout",
                            // Several additional parameters are possible in addition
                            // to the typical output. Flush determines whether logger
                            // flushes output to a file. Maxsize determines maximum
                            // filesize before the file is rotated. maxver
                            // specifies the maximum number of rotated files being
                            // kept.
                            "flush": true,
                            "maxsize": 204800,
                            "maxver": 4,
                            // We use pattern to specify custom log message layout
                            "pattern": "%d{%y.%m.%d %H:%M:%S.%q} %-5p [%c/%i] %m\n"

                        }
                    ],
                    // You can change the severity to DEBUG, INFO, WARN, ERROR or
                    // CRIT. For DEBUG level, you can also additionally specify
                    // debuglevel (0-99, higher = more verbose). All configurations
                    // are logged on DEBUG/55.
                    "severity": "INFO",
                    "debuglevel": 0
                }
            ]
        }
    }
