"subnet4": [
{
"subnet": "192.0.2.0/24",
- "option-data": [ {
+ "option-data": [
+ {
"name": "domain-name-servers",
"code": 6,
"data": "192.0.2.200,192.0.2.201",
"csv-format": true,
"space": "dhcp4"
- } ]
+ }
+ ]
}
]
}
"valid-lifetime": 4000,
- "subnet4": [ {
+ "subnet4": [
+ {
"subnet": "10.10.10.0/24",
"4o6-interface": "eno33554984",
"4o6-subnet": "2001:db8:1:1::/64",
"pools": [ { "pool": "10.10.10.100 - 10.10.10.199" } ]
- } ],
+ }
+ ],
"dhcp4o6-port": 6767,
- "loggers": [ {
+ "loggers": [
+ {
"name": "kea-dhcp4",
- "output_options": [ {
+ "output_options": [
+ {
"output": "/tmp/kea-dhcp4.log"
- } ],
+ }
+ ],
"severity": "DEBUG",
"debuglevel": 0
- } ]
+ }
+ ]
}
}
.. code-block:: json
{
- "subnet4": [ {
+ "subnet4": [
+ {
"subnet": "10.0.0.0/24",
"pools": [ { "pool": "10.0.0.10-10.0.0.100" } ],
"ddns-qualifying-suffix": "example.isc.org.",
"hostname": "alice-laptop"
}
]
- }],
+ }
+ ],
"dhcp-ddns": {
"enable-updates": true
}
.. code-block:: json
{
- "subnet4": [ {
+ "subnet4": [
+ {
"subnet": "10.0.0.0/24",
"pools": [ { "pool": "10.0.0.10-10.0.0.100" } ],
"reservations": [
"hw-address": "12:34:56:78:99:AA",
"hostname": "mark-desktop.example.org."
}
-
]
- }],
+ }
+ ],
"dhcp-ddns": {
"enable-updates": true
}
::
{
- "subnet4": [ {
+ "subnet4": [
+ {
"reservations": [
{
"hw-address": "aa:bb:cc:dd:ee:ff",
{
"name": "log-servers",
"data": "10.1.1.200,10.1.1.201"
- } ]
- } ]
- } ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
}
Vendor-specific options can be reserved in a similar manner:
::
{
- "subnet4": [ {
+ "subnet4": [
+ {
"reservations": [
{
"hw-address": "aa:bb:cc:dd:ee:ff",
"name": "tftp-servers",
"space": "vendor-4491",
"data": "10.1.1.202,10.1.1.203"
- } ]
- } ]
- } ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
}
Options defined at the host level have the highest priority. In other words,
::
{
- "subnet4": [ {
+ "subnet4": [
+ {
"reservations": [
{
"hw-address": "aa:bb:cc:dd:ee:ff",
"next-server": "10.1.1.2",
"server-hostname": "server-hostname.example.org",
"boot-file-name": "/tmp/bootfile.efi"
- } ]
- } ]
+ }
+ ]
+ }
+ ]
}
Note that those parameters can be specified in combination with other
]
}
],
- "subnet4": [ {
+ "subnet4": [
+ {
"subnet": "10.0.0.0/24",
"pools": [ { "pool": "10.0.0.10-10.0.0.100" } ],
"reservations": [
}
]
- } ]
+ }
+ ]
}
In some cases the host reservations can be used in conjunction with client
}
],
"valid-lifetime": 600,
- "subnet4": [ {
+ "subnet4": [
+ {
"subnet": "10.0.0.0/24",
# It is replaced by the "reservations-global",
# "reservations-in-subnet", and "reservations-out-of-pool"
# is false.
# "reservations-out-of-pool": false,
"pools": [ { "pool": "10.0.0.10-10.0.0.100" } ]
- } ]
+ }
+ ]
}
When using database backends, the global host reservations are
"subnet4": [
{
"subnet": "192.0.2.0/24",
- "reservations": [{
- "hw-address": "aa:bb:cc:dd:ee:fe",
- "client-classes": [ "reserved_class" ]
- }],
+ "reservations": [
+ {
+ "hw-address": "aa:bb:cc:dd:ee:fe",
+ "client-classes": [ "reserved_class" ]
+ }
+ ],
"pools": [
{
"pool": "192.0.2.10-192.0.2.20",
"test": "not member('reserved_class')"
}
],
- "reservations": [{
- "hw-address": "aa:bb:cc:dd:ee:fe",
- "client-classes": [ "reserved_class" ]
- }],
+ "reservations": [
+ {
+ "hw-address": "aa:bb:cc:dd:ee:fe",
+ "client-classes": [ "reserved_class" ]
+ }
+ ],
# It is replaced by the "reservations-global",
# "reservations-in-subnet", and "reservations-out-of-pool" parameters.
# Specify if the server should look up global reservations.
# is false, but if specified, it is inherited by "shared-networks"
# and "subnet4" levels.
# "reservations-out-of-pool": false,
- "shared-networks": [{
+ "shared-networks": [
+ {
"subnet4": [
{
"subnet": "192.0.2.0/24",
]
}
]
- }]
+ }
+ ]
}
This is similar to the example described in
{
"Dhcp4": {
- "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": "my-secret-lair-level-1",
"pools": [ { "pool": "192.0.2.100 - 192.0.2.199" } ]
}
]
- } ],
+ }
+ ],
# end of shared-networks
# It is likely that in the network there will be a mix of regular,
# This option is made available to all subnets in this shared
# network.
- "option-data": [ {
+ "option-data": [
+ {
"name": "log-servers",
"data": "1.2.3.4"
- } ],
+ }
+ ],
"subnet4": [
{
::
"Dhcp4": {
- "subnet4": [{
+ "subnet4": [
+ {
"subnet": "192.0.2.0/24",
- "pools": [{
+ "pools": [
+ {
"pool": "192.0.2.10 - 192.0.2.20",
# This is pool specific user context
"user-context": { "color": "red" }
- } ],
+ }
+ ],
# This is a subnet-specific user context. Any type
# of information can be entered here as long as it is valid JSON.
"devices-registered": 42,
"billing": false
}
- } ]
+ }
+ ]
}
Kea does not interpret or use the user-context information; it simply
"Dhcp4": {
"server-tag": "my DHCPv4 server",
"config-control": {
- "config-databases": [{
+ "config-databases": [
+ {
"type": "mysql",
"name": "kea",
"user": "kea",
"password": "kea",
"host": "192.0.2.1",
"port": 3302
- }],
+ }
+ ],
"config-fetch-wait-time": 20
},
- "hooks-libraries": [{
+ "hooks-libraries": [
+ {
"library": "/usr/local/lib/kea/hooks/libdhcp_mysql_cb.so"
}, {
"library": "/usr/local/lib/kea/hooks/libdhcp_cb_cmds.so"
- }]
+ }
+ ]
}
}
"Dhcp4": {
"server-tag": "my DHCPv4 server",
"config-control": {
- "config-databases": [{
+ "config-databases": [
+ {
"type": "postgresql",
"name": "kea",
"user": "kea",
"password": "kea",
"host": "192.0.2.1",
"port": 5432
- }],
+ }
+ ],
"config-fetch-wait-time": 20
},
- "hooks-libraries": [{
+ "hooks-libraries": [
+ {
"library": "/usr/local/lib/kea/hooks/libdhcp_pgsql_cb.so"
}, {
"library": "/usr/local/lib/kea/hooks/libdhcp_cb_cmds.so"
- }]
+ }
+ ]
}
}
"options": "0x00250006010203040506003500086464646464646464",
"remote-id": "010203040506",
"relay-id": "6464646464646464"
- }]
+ }
+ ]
}
}
"subnet6": [
{
"subnet": "2001:db8:1::/64",
- "reservations": [{
- "hw-address": "aa:bb:cc:dd:ee:fe",
- "client-classes": [ "reserved_class" ]
- }],
+ "reservations": [
+ {
+ "hw-address": "aa:bb:cc:dd:ee:fe",
+ "client-classes": [ "reserved_class" ]
+ }
+ ],
"pools": [
{
"pool": "2001:db8:1::10-2001:db8:1::20",
"test": "not member('reserved_class')"
}
],
- "reservations": [{
- "hw-address": "aa:bb:cc:dd:ee:fe",
- "client-classes": [ "reserved_class" ]
- }],
+ "reservations": [
+ {
+ "hw-address": "aa:bb:cc:dd:ee:fe",
+ "client-classes": [ "reserved_class" ]
+ }
+ ],
# It is replaced by the "reservations-global",
# "reservations-in-subnet", and "reservations-out-of-pool" parameters.
# Specify if the server should look up global reservations.
# is false, but if specified, it is inherited by "shared-networks"
# and "subnet6" levels.
# "reservations-out-of-pool": false,
- "shared-networks": [{
+ "shared-networks": [
+ {
"subnet6": [
{
"subnet": "2001:db8:1::/64",
]
}
]
- }]
+ }
+ ]
}
This is similar to the example described in the
{
"Dhcp6": {
- "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": "ipv6-lab-1",
"subnet6": [
{
"subnet": "2001:db8::/48",
- "pools": [{ "pool": "2001:db8::1 - 2001:db8::ffff" }]
+ "pools": [ { "pool": "2001:db8::1 - 2001:db8::ffff" } ]
},
{
"subnet": "3ffe:ffe::/64",
- "pools": [{ "pool": "3ffe:ffe::/64" }]
+ "pools": [ { "pool": "3ffe:ffe::/64" } ]
}
]
- } ],
+ }
+ ],
# end of shared-networks
# It is likely that in the network there will be a mix of regular,
"subnet6": [
{
"subnet": "2001:db9::/48",
- "pools": [{ "pool": "2001:db9::/64" }],
+ "pools": [ { "pool": "2001:db9::/64" } ],
"relay": {
"ip-addresses": [ "2001:db8:1:2::1" ]
}
#!/bin/bash
-work_file=`mktemp`
-for file in `find ./ | grep -v "\.git" | grep -v "_build" | grep -v "\/man\/" | grep "\.rst\|\.json" | sort`; do
+# Change directory to the root of the repository.
+script_path=$(cd "$(dirname "${0}")" && pwd)
+cd "${script_path}/.."
+# Parse parameters.
+if test ${#} -gt 0; then
+ files="${*}"
+else
+ files='doc src'
+fi
+
+# Get the files.
+files=$(find ${files} -type f \( -name '*.rst' -or -name '*.json' \) -and -not -path '/_build/*' -and -not -path '/man/*' | sort)
+work_file=$(mktemp)
+for file in $files; do
json=0
comment=0
line_num=0
echo "processing: $file"
- while IFS= read line; do
+ while IFS= read -r line; do
line_num=$((line_num+1))
- if [ $comment -eq 0 -a $json -eq 0 -a `echo "$line" | grep -e "^[A-Za-z]+\|^\s*\\\`" | wc -l` -eq 1 ]; then
+ if [ $comment -eq 0 -a $json -eq 0 -a $(echo "$line" | grep "^[A-Za-z]+\|^\s*\`" | wc -l) -eq 1 ]; then
# ignore line if it starts with 'A-Za-z' or spaces followed by '`'
continue
- elif [ $comment -eq 0 -a `echo "$line" | grep -e "\/\*" | grep -v -e "\*\/" | wc -l` -eq 1 ]; then
+ elif [ $comment -eq 0 -a $(echo "$line" | grep "/\*" | grep -v "\*/" | wc -l) -eq 1 ]; then
# if the line contains /* and it does not contain */ on the same line
comment=1
echo "" >> $work_file
continue
- elif [ $comment -eq 1 -a `echo "$line" | grep "\*\/" | wc -l` -eq 1 ]; then
+ elif [ $comment -eq 1 -a $(echo "$line" | grep "\*/" | wc -l) -eq 1 ]; then
# if the line contains */
comment=0
echo "" >> $work_file
continue
- elif [ $comment -eq 0 -a $json -eq 0 -a `echo "$line" | grep "^\s*{\|^\s*\".*{" | grep -v "}" | grep -v "key\|pre" | wc -l` -eq 1 ]; then
- # if this is not a commend and the line starts with spaces followed by '{' or by '"' followed by "{"
+ elif [ $comment -eq 0 -a $json -eq 0 -a $(echo "$line" | grep "^\s*{\|^\s*\".*{" | grep -v "}" | grep -v "key\|pre" | wc -l) -eq 1 ]; then
+ # if this is not a comment and the line starts with spaces followed by '{' or by '"' followed by "{"
# ignore dns config:
# key "key.four.example.com." {
# algorithm hmac-sha224;
# secret "bZEG7Ow8OgAUPfLWV3aAUQ==";
# };
# ignore detailed html:
- # .. raw:: html
+ # .. raw:: html
# <details><summary>Expand here!</summary>
# <pre>{
# ...
# </details><br>
json=1
# ignore any map name before top level map
- line=`echo "$line" | sed "s/.*{/{/g"`
+ line=$(echo "$line" | sed "s/.*{/{/g")
echo "" > $work_file
- elif [ $comment -eq 0 -a $json -eq 1 -a `echo "$line" | grep -e "^\s*[A-Za-z]\|^\s*\\\`" | wc -l` -eq 1 ]; then
+ elif [ $comment -eq 0 -a $json -eq 1 -a $(echo "$line" | grep "^\s*[A-Za-z]\|^\s*\`" | wc -l) -eq 1 ]; then
# if the line is not a comment and the line starts with spaces followed by 'A-Za-z' or followed by "`" and the parser is processing a json structure
json=0
cat $work_file | jq . > /dev/null
fi
fi
if [ $comment -eq 0 -a $json -eq 1 ]; then
- if [ `echo "$line" | grep -e "^\s*\.\.\s" | wc -l` -eq 1 ]; then
+ if [ $(echo "$line" | grep "^\s*\.\.\s" | wc -l) -eq 1 ]; then
echo "" >> $work_file
else
# if file is .json the following replace in line are done:
# 8. replace ', ... ' with ' '
# 9. replace ' <DATA>' with ' "placeholder": "value"'
# 10. replace ' <DATA>' with ' "placeholder"'
- if [ `echo "$file" | grep "\.json" | wc -l` -eq 0 ]; then
+ if [ $(echo "$file" | grep "\.json" | wc -l) -eq 0 ]; then
echo "$line" | cut -d "#" -f 1 | sed "s/\/\/ .*//g" | sed "s/<?.*?>//g" | sed "s/\[ <\([-A-Za-z0-9 ]*\)> \]/\[ \"<\1>\" \]/g" | sed "s/ <\(.*\)>:/ \"<\1>\":/g" | sed "s/: <\(.*\)>/: \"<\1>\"/g" | sed "s/ \.\.\./ \"placeholder\": \"value\"/g" | sed "s/, \.\.\. / /g" | sed "s/ <\(.*\)>/ \"placeholder\": \"value\"/g" | sed "s/ <\(.*\)>/ \"placeholder\"/g" >> $work_file
else
# if file is .rst the following replace in line are done: