Kea lease allocation, client classification and option assignment
Created: 2025-11-11 Tue 10:28
"Dhcp4": {
"option-data": [{
"name": "domain-name-servers",
"code": 6,
"space": "dhcp4",
"csv-format": true,
"data": "192.0.2.1, 192.0.2.2"
},
...
]}
code, space and
csv-format can be omitted
"Dhcp4": {
"option-data": [{
"name": "domain-name-servers",
"data": "192.0.2.1, 192.0.2.2"
},
...
]}
[...]
"subnet4": [ {
"subnet": "192.0.2.0/24",
"pools": [ { "pool": "192.0.2.100 - 192.0.2.200" } ],
"option-data": [{
"name": "routers",
"data": "192.0.2.1" },
{
"name": "domain-name",
"data": "a.example.com" }
]},
[...]
"client-classes": [{
"name": "Zimbutsio-Server",
"test": "option[vendor-class-identifier].text == 'Zimbutsio'",
"option-data": [ {
"name": "log-servers",
"data": "192.0.2.42"
}]
}],
[...]
{
"Dhcp4": {
"option-def": [{
"name": "my-message",
"code": 234,
"type": "string",
"array": false,
"record-types": "",
"space": "dhcp4",
"encapsulate": "" }],
"option-data": [{
"name": "my-message",
"space": "dhcp4",
"csv-format": true,
"data": "Hello World" }],
[...]
"Dhcp4:" {
# This specifies global reservations. They will apply to all subnets that
# have global reservations enabled.
"reservations": [
{ "hw-address": "aa:bb:cc:dd:ee:ff", "hostname": "hw-host-dynamic" },
{ "hw-address": "01:02:03:04:05:06", "hostname": "hw-host-fixed", "ip-address": "192.0.1.77" }, # risky!
{ "circuit-id": "'office042'", "hostname": "circuit-id-host" },
[...]
| Command | Description |
|---|---|
| reservation-add | add a new reservation to the Kea DB |
| reservation-get-all | get all reservation information (can be huge) |
| reservation-get | get information on a single reservation (by address or identifier) |
| reservation-get-page | get all reservation information from a subnet by pages (used for GUI display) |
| reservation-get-by-hostname | get the reservation information for one host by its hostname |
| reservation-get-by-id | get the reservation information for one host by its identifier (global, since 1.9.0) |
| reservation-del | delete a reservation from the database |
$ cat reservation-add.json
{
"command": "reservation-add",
"service": [ "dhcp6" ],
"arguments": {
"reservation": {
"duid": "01:02:03:04:05:06:07:08:09:0A",
"hostname": "foo.example.com",
"ip-addresses": [ "2001:db8:1::1" ],
"option-data": [{
"data": "4491",
"name": "vendor-opts"
},{
"data": "3000:1::234",
"name": "tftp-servers",
"space": "vendor-4491"
}],
"subnet-id": 1
}
}
}
curl command can be used to send the request towards the Kea
API
$ curl -s -X POST -H "Content-Type: application/json" \
-d @reservation-add.json http://127.0.0.1:8000/ | jq
[
{
"result": 0,
"text": "Host added."
}
]
$ cat reservation-get-all.json
{
"service": [
"dhcp6"
],
"command": "reservation-get-all",
"arguments": {
"subnet-id": 1
}
}
$ curl -s -X POST -H "Content-Type: application/json" \
-d @reservation-get-all.json http://127.0.0.1:8000/ | jq
[...]
"subnet4": [
{
"subnet": "10.0.0.0/24",
"pools": [ { "pool": "10.0.0.10-10.0.0.200" } ],
"reservations": [{
"hw-address": "01:02:03:04:05:06",
"client-classes": [ "windows", "staff" ]
}]
}],
[...]
reservation-mode configuration parameter
"Dhcp4": {
"subnet4": [{
"subnet": "192.0.2.0/24",
"reservation-mode": "disabled",
...
}]
}
| reservation-mode | description |
|---|---|
| all | Reservations can be on global, subnet or inside pool scope, all checks enabled (default) |
| out-of-pool | Reservations in subnets are always outside the pool |
| global | Only global reservations allowed, not subnet/pool reservations |
| disabled(*) | Host reservation support is disabled, no checks for collisions |
hw-addressduidclient-idcircuit-idflex-idhost-reservation-identifiers takes a list of
identifier types that Kea will check
"host-reservation-identifiers": [ "circuit-id", "hw-address" ],
"subnet4": [{
"subnet": "192.0.2.0/24",
...
}]
[...]
"shared-networks": [
{
"name": "kea-lab01",
"relay": { "ip-address": "192.0.2.1" },
"subnet4": [{
"subnet": "192.0.2.0/24",
"option-data": [
{ "name": "routers", "data": "192.0.2.1" }],
"pools": [{ "pool": "192.0.2.20 - 192.0.2.190" }]
}, {
"subnet": "10.0.0.0/24",
"option-data": [
{ "name": "routers", "data": "10.0.0.1" }],
"pools": [{ "pool": "10.0.0.10 - 10.0.0.200" }]
}]
],
[...]
VENDOR_CLASS_ and
the result is interpreted as a class
docsis3.0, so the packet belongs to class
VENDOR_CLASS_docsis3.0
"shared-networks": [
{
"name": "kea-net01",
"relay": { "ip-address": "192.0.2.1" },
"subnet4": [
{
"subnet": "192.0.2.0/24",
"client-class": "VENDOR_CLASS_windowsCE", # <-- Windows CE Clients will get
# an IP from this subnet
"option-data": [{
"name": "routers", "data": "192.0.2.1" }],
"pools": [{
"pool": "192.0.2.60 - 192.0.2.220" }]
},
{
"subnet": "10.0.0.0/24",
"client-class": "VENDOR_CLASS_fedoraLinux", # <-- Fedora-Linux Clients will
# get an IP from this subnet
"option-data": [
[...]
KNOWN classUNKNOWN class
{
"client-classes": [{
"name": "dependent-class",
"test": "member('KNOWN')",
"only-if-required": true
}]
}
"Dhcp4": {
"client-classes": [
{ "name": "windows",
"test": "substring(option[60].hex,0,3) == 'win'",
"option-data": [{
"name": "domain-name", "data": "win.example.com" }]
},
{ "name": "other",
"test": "not(substring(option[60].hex,0,3) == 'win')",
"option-data": [{
"name": "domain-name", "data": "other.example.com" }]
}
],
[...]
"shared-networks": [
{
"name": "kea-lab01",
"relay": { "ip-address": "192.0.2.1" },
"subnet4": [
{
"subnet": "192.0.2.0/24",
"client-class": "windows", # <-- all Windows Clients will
# get IP addresses from this subnet
"option-data": [{
"name": "routers", "data": "192.0.2.1" }],
"pools": [{
"pool": "192.0.2.60 - 192.0.2.250" }]
},
{
"subnet": "10.0.0.0/24",
"client-class": "other", # <-- non Windows Clients will
# get IP addresses from this subnet
"option-data": [
[...]
"client-classes": [
{
"name": "Apple-Computer",
"test": "match('5c-1b-f4|a8-5b-b7|58-55-95|00-19-b8',hexstring(substring(pkt4.mac, 0, 3), '-'))"
},
[...]
[kea-server]# systemctl stop kea-dhcp4 [kea-server]# kea-dhcp4 -d -c /etc/kea/kea-dhcp4.conf
kea-dhcp4.eval or
kea-dhcp6.eval debug logger in the Kea configuration file
"Logging": {
"loggers": [ {
"name": "kea-dhcp4.eval",
"output_options": [ {
"output": "/var/log/kea-dhcp4-eval.log"
} ],
"severity": "DEBUG",
"debuglevel": 55
} ]
}
[kea-server]# tail -f /var/log/kea-dhcp4-eval.log