confd: relocate /dhcp-client to /interfaces/interface/ipv4/dhcp

Please note, this change drops not only the global enabled flag, but also the
per-interface enabled flag, converting it to a presence container.  The name
of the container is also shortened from dhcp-client -> dhcp.  A pattern that
expected to be reused also for the DHCPv6 client.

Fixes #1109

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg
2025-11-02 14:11:53 +01:00
parent 331f60be64
commit d53a35b867
24 changed files with 328 additions and 302 deletions
@@ -99,7 +99,20 @@
{
"name": "wan",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {}
"ietf-ip:ipv6": {},
"ietf-ip:ipv4": {
"infix-dhcp-client:dhcp": {
"option": [
{"id": "ntp-server"},
{"id": "broadcast"},
{"id": "domain"},
{"id": "hostname"},
{"id": "dns-server"},
{"id": "router"},
{"id": "netmask"}
]
}
}
},
{
"name": "wifi0",
@@ -221,36 +234,6 @@
},
"infix-system:motd-banner": "Li0tLS0tLS0uCnwgIC4gLiAgfCBJbmZpeCBPUyDigJQgSW1tdXRhYmxlLkZyaWVuZGx5LlNlY3VyZQp8LS4gdiAuLXwgaHR0cHM6Ly9rZXJuZWxraXQub3JnCictJy0tLSctJwo="
},
"infix-dhcp-client:dhcp-client": {
"client-if": [
{
"if-name": "wan",
"option": [
{
"id": "ntp-server"
},
{
"id": "broadcast"
},
{
"id": "domain"
},
{
"id": "hostname"
},
{
"id": "dns-server"
},
{
"id": "router"
},
{
"id": "netmask"
}
]
}
]
},
"infix-dhcp-server:dhcp-server": {
"option": [
{
@@ -311,7 +294,7 @@
]
},
"infix-meta:meta": {
"version": "1.5"
"version": "1.6"
},
"infix-services:mdns": {
"enabled": true
@@ -58,7 +58,20 @@
{
"name": "wan",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {}
"ietf-ip:ipv6": {},
"ietf-ip:ipv4": {
"infix-dhcp-client:dhcp": {
"option": [
{"id": "ntp-server"},
{"id": "broadcast"},
{"id": "domain"},
{"id": "hostname"},
{"id": "dns-server"},
{"id": "router"},
{"id": "netmask"}
]
}
}
}
]
},
@@ -172,36 +185,6 @@
},
"infix-system:motd-banner": "Li0tLS0tLS0uCnwgIC4gLiAgfCBJbmZpeCBPUyDigJQgSW1tdXRhYmxlLkZyaWVuZGx5LlNlY3VyZQp8LS4gdiAuLXwgaHR0cHM6Ly9rZXJuZWxraXQub3JnCictJy0tLSctJwo="
},
"infix-dhcp-client:dhcp-client": {
"client-if": [
{
"if-name": "wan",
"option": [
{
"id": "ntp-server"
},
{
"id": "broadcast"
},
{
"id": "domain"
},
{
"id": "hostname"
},
{
"id": "dns-server"
},
{
"id": "router"
},
{
"id": "netmask"
}
]
}
]
},
"infix-dhcp-server:dhcp-server": {
"option": [
{
@@ -262,7 +245,7 @@
]
},
"infix-meta:meta": {
"version": "1.5"
"version": "1.6"
},
"infix-services:mdns": {
"enabled": true
@@ -37,7 +37,20 @@
},
{
"name": "eth0",
"type": "infix-if-type:ethernet"
"type": "infix-if-type:ethernet",
"ietf-ip:ipv4": {
"infix-dhcp-client:dhcp": {
"option": [
{"id": "netmask"},
{"id": "broadcast"},
{"id": "router"},
{"id": "domain"},
{"id": "hostname"},
{"id": "dns-server"},
{"id": "ntp-server"}
]
}
}
},
{
"name": "wifi0",
@@ -157,38 +170,8 @@
},
"infix-system:motd-banner": "Li0tLS0tLS0uCnwgIC4gLiAgfCBJbmZpeCBPUyDigJQgSW1tdXRhYmxlLkZyaWVuZGx5LlNlY3VyZQp8LS4gdiAuLXwgaHR0cHM6Ly9rZXJuZWxraXQub3JnCictJy0tLSctJwo="
},
"infix-dhcp-client:dhcp-client": {
"client-if": [
{
"if-name": "eth0",
"option": [
{
"id": "netmask"
},
{
"id": "broadcast"
},
{
"id": "router"
},
{
"id": "domain"
},
{
"id": "hostname"
},
{
"id": "dns-server"
},
{
"id": "ntp-server"
}
]
}
]
},
"infix-meta:meta": {
"version": "1.5"
"version": "1.6"
},
"infix-services:mdns": {
"enabled": true
+4
View File
@@ -8,6 +8,10 @@ All notable changes to the project are documented in this file.
### Changes
- The DHCP client configuration has moved from `/infix-dhcp-client:dhcp-client`
to `/interfaces/interface[name]/ipv4/infix-dhcp-client:dhcp`, issue #1109.
The configuration is automatically migrated on upgrade. The DHCP client is
now enabled using a presence container instead of a separate `enabled` leaf
- Improvements to `sdcard.img` generation, useful for developers mostly:
- The NanoPi R2S bootloader is now automatically built and uploaded to
the [`latest-boot` release][lastest-boot] tag
+28 -3
View File
@@ -1038,9 +1038,9 @@ will be used, otherwise it falls back to the default algorithm.
![Using DHCP for IPv4 address assignment](img/ip-address-example-ipv4-dhcp.svg)
admin@example:/> configure
admin@example:/config/> edit dhcp-client
admin@example:/config/dhcp-client/> set client-if eth0
admin@example:/config/dhcp-client/> leave
admin@example:/config/> edit interface eth0 ipv4
admin@example:/config/interface/eth0/ipv4/> set dhcp
admin@example:/config/interface/eth0/ipv4/> leave
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
eth0 ethernet UP 02:00:00:00:00:00
@@ -1053,6 +1053,31 @@ will be used, otherwise it falls back to the default algorithm.
The resulting address (10.1.2.100/24) is of type *dhcp*.
To configure DHCP client options, such as sending a specific hostname to the
server, you can specify options with values:
```
admin@example:/> configure
admin@example:/config/> edit interface eth0 ipv4 dhcp
admin@example:/config/interface/eth0/ipv4/dhcp/> set option hostname value myhost
admin@example:/config/interface/eth0/ipv4/dhcp/> show
option hostname {
value myhost;
}
admin@example:/config/interface/eth0/ipv4/dhcp/> leave
admin@example:/>
```
> [!TIP]
> The special value `auto` can be used with the hostname option to
> automatically use the configured system hostname.
Other useful DHCP options include:
- `client-id` - Send a specific client identifier to the server
- `route-preference` - Set the administrative distance for DHCP-learned routes (default: 5)
For advanced usage with vendor-specific options, see the YANG model.
#### Disabling IPv6 link-local address(es)
+16 -28
View File
@@ -173,11 +173,13 @@ Enabling DHCPv4 client on interface *e0*, with current default options.
```
~$ cat /tmp/file.json
{
"infix-dhcp-client:dhcp-client": {
"enabled": true,
"client-if": [
"ietf-interfaces:interfaces": {
"interface": [
{
"if-name": "e0"
"name": "e0",
"ietf-ip:ipv4": {
"infix-dhcp-client:dhcp": {}
}
}
]
}
@@ -187,13 +189,18 @@ Enabling DHCPv4 client on interface *e0*, with current default options.
~$
```
Disabling DHCPv4 client.
Disabling DHCPv4 client on interface *e0* (remove the dhcp container).
```
~$ cat /tmp/file.json
{
"infix-dhcp-client:dhcp-client": {
"enabled": false
"ietf-interfaces:interfaces": {
"interface": [
{
"name": "e0",
"ietf-ip:ipv4": {}
}
]
}
}
~$ scp file.json admin@example.local:/tmp/file.json
@@ -201,27 +208,8 @@ Disabling DHCPv4 client.
~$
```
Configuration for client interface *e0* remains, but does not apply as
DHCPv4 is disabled.
```
admin@example:~$ sysrepocfg -X -fjson -d running -x "/infix-dhcp-client:dhcp-client"
{
"infix-dhcp-client:dhcp-client": {
"enabled": false,
"client-if": [
{
"if-name": "e0"
}
]
}
}
admin@example:~$
```
To fully remove the DHCPv4 client configuration or a specific
*client-if* with sysrepocfg, one would need to read out the full
configuration, remove relevant parts and read back.
To fully remove the DHCPv4 client configuration, remove the `infix-dhcp-client:dhcp`
container from the interface's ipv4 configuration.
## Enable/Disable IPv6
+1 -1
View File
@@ -4,7 +4,7 @@
#
################################################################################
CONFD_VERSION = 1.5
CONFD_VERSION = 1.6
CONFD_SITE_METHOD = local
CONFD_SITE = $(BR2_EXTERNAL_INFIX_PATH)/src/confd
CONFD_LICENSE = BSD-3-Clause
+8 -12
View File
@@ -172,6 +172,14 @@ if [ -n "$bridge" ]; then
"infix-ip:autoconf": {
"enabled": $ipv4
}
EOF
if [ "$dhcp" = "true" ]; then
cat <<EOF
,
"infix-dhcp-client:dhcp": {}
EOF
fi
cat <<EOF
},
"ietf-ip:ipv6": {
"enabled": true,
@@ -195,18 +203,6 @@ $(for iface in $ifaces; do gen_iface_json "$iface"; done)
$(for iface in $ports; do gen_iface_json "$iface" "$bridge"; done)
]
EOF
if [ "$dhcp" = "true" ] && [ -n "$bridge" ]; then
cat <<EOF
},
"infix-dhcp-client:dhcp-client": {
"enabled": true,
"client-if": [
{
"if-name": "$bridge"
}
]
EOF
fi
cat <<EOF
}
}
+2 -1
View File
@@ -1,6 +1,6 @@
AC_PREREQ(2.61)
# confd version is same as system YANG model version, step on breaking changes
AC_INIT([confd], [1.5], [https://github.com/kernelkit/infix/issues])
AC_INIT([confd], [1.6], [https://github.com/kernelkit/infix/issues])
AM_INIT_AUTOMAKE(1.11 foreign subdir-objects)
AM_SILENT_RULES(yes)
@@ -19,6 +19,7 @@ AC_CONFIG_FILES([
share/migrate/1.3/Makefile
share/migrate/1.4/Makefile
share/migrate/1.5/Makefile
share/migrate/1.6/Makefile
yang/Makefile
yang/confd/Makefile
yang/test-mode/Makefile
+38
View File
@@ -0,0 +1,38 @@
#!/bin/sh
# Migrate DHCP client configuration from standalone model to ietf-ip augment
# From: /infix-dhcp-client:dhcp-client/client-if[if-name]
# To: /ietf-interfaces:interfaces/interface[name]/ipv4/infix-dhcp-client:dhcp
file=$1
temp=${file}.tmp
jq '
if .["infix-dhcp-client:dhcp-client"] then
.["infix-dhcp-client:dhcp-client"]."client-if" as $clients |
($clients // [] | map({
key: ."if-name",
value: {
"infix-dhcp-client:dhcp": (
. | del(."if-name") | del(.enabled)
)
}
}) | from_entries) as $dhcp_configs |
if .["ietf-interfaces:interfaces"] then
.["ietf-interfaces:interfaces"].interface |= map(
if $dhcp_configs[.name] then
.["ietf-ip:ipv4"] += $dhcp_configs[.name]
else
.
end
)
else
.
end |
del(.["infix-dhcp-client:dhcp-client"])
else
.
end
' "$file" > "$temp" && mv "$temp" "$file"
+2
View File
@@ -0,0 +1,2 @@
migratedir = $(pkgdatadir)/migrate/1.6
dist_migrate_DATA = 10-dhcp-client-to-ipv4.sh
+1 -1
View File
@@ -1,2 +1,2 @@
SUBDIRS = 1.0 1.1 1.2 1.3 1.4 1.5
SUBDIRS = 1.0 1.1 1.2 1.3 1.4 1.5 1.6
migratedir = $(pkgdatadir)/migrate
+1
View File
@@ -356,6 +356,7 @@ int infix_containers_change(sr_session_ctx_t *session, struct lyd_node *config,
if (diff && !lydx_get_xpathf(diff, CFG_XPATH))
return SR_ERR_OK;
switch (event) {
case SR_EV_DONE:
break;
+37 -33
View File
@@ -14,7 +14,7 @@
#include "core.h"
#define ARPING_MSEC 1000
#define MODULE "infix-dhcp-client"
#define XPATH "/infix-dhcp-client:dhcp-client"
#define XPATH "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/infix-dhcp-client:dhcp"
#define CACHE_TEMPLATE "/var/lib/misc/%s.cache"
static char *ip_cache(const char *ifname, char *str, size_t len)
@@ -278,57 +278,61 @@ static void del(const char *ifname)
systemf("initctl -bfq delete dhcp-client-%s", ifname);
}
int infix_dhcp_client_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
int infix_dhcp_client_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff,
sr_event_t event, struct confd *confd)
{
struct lyd_node *global, *cifs, *difs, *cif, *dif;
struct lyd_node *ifaces, *difaces, *iface, *diface, *ipv4, *dhcp, *ddhcp;
sr_error_t err = 0;
int ena = 0;
switch (event) {
case SR_EV_DONE:
break;
case SR_EV_CHANGE:
case SR_EV_ABORT:
default:
if (event != SR_EV_DONE)
return SR_ERR_OK;
}
global = lydx_get_descendant(config, "dhcp-client", NULL);
ena = lydx_is_enabled(global, "enabled");
ifaces = lydx_get_descendant(config, "interfaces", "interface", NULL);
difaces = lydx_get_descendant(diff, "interfaces", "interface", NULL);
cifs = lydx_get_descendant(config, "dhcp-client", "client-if", NULL);
difs = lydx_get_descendant(diff, "dhcp-client", "client-if", NULL);
/* find the modified interfaces */
LYX_LIST_FOR_EACH(difaces, diface, "interface") {
const char *ifname = lydx_get_cattr(diface, "name");
struct lyd_node *dipv4;
char *out;
/* find the modified one, delete or recreate only that */
LYX_LIST_FOR_EACH(difs, dif, "client-if") {
const char *ifname = lydx_get_cattr(dif, "if-name");
lyd_print_mem(&out, diface, LYD_JSON,
LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL);
if (lydx_get_op(dif) == LYDX_OP_DELETE) {
dipv4 = lydx_get_descendant(lyd_child(diface), "ipv4", NULL);
if (!dipv4)
continue;
ddhcp = lydx_get_descendant(lyd_child(dipv4), "dhcp", NULL);
if (!ddhcp)
continue;
/* Check if dhcp container was deleted */
if (lydx_get_op(ddhcp) == LYDX_OP_DELETE) {
del(ifname);
continue;
}
LYX_LIST_FOR_EACH(cifs, cif, "client-if") {
if (strcmp(ifname, lydx_get_cattr(cif, "if-name")))
/* Find corresponding interface in config to check if dhcp is present */
LYX_LIST_FOR_EACH(ifaces, iface, "interface") {
if (strcmp(ifname, lydx_get_cattr(iface, "name")))
continue;
if (!ena || !lydx_is_enabled(cif, "enabled"))
ipv4 = lydx_get_descendant(lyd_child(iface), "ipv4", NULL);
if (!ipv4) {
del(ifname);
break;
}
dhcp = lydx_get_descendant(lyd_child(ipv4), "dhcp", NULL);
if (!dhcp)
del(ifname);
else
add(ifname, cif);
add(ifname, dhcp);
break;
}
}
if (!ena) {
LYX_LIST_FOR_EACH(cifs, cif, "client-if") {
const char *ifname = lydx_get_cattr(cif, "if-name");
INFO("DHCP client globally disabled, stopping client on %s ...", ifname);
del(ifname);
}
}
return err;
}
@@ -368,7 +372,7 @@ static int cand(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
return SR_ERR_OK;
}
err = sr_dup_changes_iter(session, XPATH "/client-if//*", &iter);
err = sr_dup_changes_iter(session, XPATH "//*", &iter);
if (err)
return err;
+1 -1
View File
@@ -26,7 +26,7 @@ MODULES=(
"ieee802-dot1ab-lldp@2022-03-15.yang"
"infix-lldp@2025-05-05.yang"
"infix-dhcp-common@2025-01-29.yang"
"infix-dhcp-client@2025-01-29.yang"
"infix-dhcp-client@2025-11-02.yang"
"infix-dhcp-server@2025-10-28.yang"
"infix-firewall@2025-04-26.yang"
"infix-firewall-services@2025-04-26.yang"
+15 -24
View File
@@ -6,6 +6,9 @@ module infix-dhcp-client {
import ietf-interfaces {
prefix if;
}
import ietf-ip {
prefix ip;
}
import infix-dhcp-common {
prefix dhcp;
}
@@ -13,6 +16,14 @@ module infix-dhcp-client {
contact "kernelkit@googlegroups.com";
description "This module implements a DHCPv4 client";
revision 2025-11-02 {
description "Migrate DHCP client to ietf-ip augment.
- Relocate from /dhcp-client to /interfaces/interface/ipv4/dhcp
- Presence container instead of enabled leaf, matching autoconf
- Drop client-if list wrapper, not needed anymore
- Drop global enabled flag";
reference "internal, issue #1109";
}
revision 2025-01-29 {
description "Consolidate DHCP options between client and server models.
- Rename option attribute 'name' -> 'id'
@@ -51,30 +62,10 @@ module infix-dhcp-client {
* Data Nodes
*/
container dhcp-client {
description "DHCPv4 client configuration";
leaf enabled {
type boolean;
default "true";
description "Globally enables the DHCP client function.";
}
list client-if {
description "List of interfaces requesting DHCPv4 configuration.";
key "if-name";
leaf if-name {
type if:interface-ref;
mandatory true;
description "Name of the interface.";
}
leaf enabled {
type boolean;
default "true";
description "Enable DHCP client for this interface.";
}
augment "/if:interfaces/if:interface/ip:ipv4" {
container dhcp {
presence "Enable DHCP client for this interface.";
description "DHCPv4 client configuration";
leaf client-id {
type string;
+15 -23
View File
@@ -17,7 +17,7 @@ import infamy.dhcp
from infamy.util import until, parallel
from infamy.netns import IsolatedMacVlans
def configure_interface(name, ip=None, prefix_length=None, forwarding=True):
def configure_interface(name, ip=None, prefix_length=None, forwarding=True, dhcp=False):
interface_config = {
"name": name,
"enabled": True,
@@ -28,6 +28,19 @@ def configure_interface(name, ip=None, prefix_length=None, forwarding=True):
}
if ip and prefix_length:
interface_config["ipv4"]["address"].append({"ip": ip, "prefix-length": prefix_length})
if dhcp:
interface_config["ipv4"]["infix-dhcp-client:dhcp"] = {
"option": [
{"id": "broadcast"},
{"id": "dns-server"},
{"id": "domain"},
{"id": "hostname"},
{"id": "ntp-server"},
{"id": "router"},
{"id": "netmask"}
],
"route-preference": 5
}
return interface_config
def config_target1(target, data1, data2, link):
@@ -35,7 +48,7 @@ def config_target1(target, data1, data2, link):
"ietf-interfaces": {
"interfaces": {
"interface": [
configure_interface(data1),
configure_interface(data1, dhcp=True),
configure_interface(data2, "192.168.30.1", 24),
configure_interface(link, "192.168.50.1", 24)
]
@@ -61,27 +74,6 @@ def config_target1(target, data1, data2, link):
]
}
}
},
"infix-dhcp-client": {
"dhcp-client": {
"enabled": True,
"client-if": [
{
"if-name": data1,
"enabled": True,
"option": [
{"id": "broadcast"},
{"id": "dns-server"},
{"id": "domain"},
{"id": "hostname"},
{"id": "ntp-server"},
{"id": "router"},
{"id": "netmask"}
],
"route-preference": 5
}
]
}
}
})
+7 -4
View File
@@ -24,13 +24,16 @@ with infamy.Test() as test:
with infamy.dhcp.Server(netns, ip=ADDRESS):
_, port = env.ltop.xlate("client", "data")
config = {
"dhcp-client": {
"client-if": [{
"if-name": f"{port}"
"interfaces": {
"interface": [{
"name": f"{port}",
"ipv4": {
"infix-dhcp-client:dhcp": {}
}
}]
}
}
client.put_config_dict("infix-dhcp-client", config)
client.put_config_dict("ietf-interfaces", config)
with test.step("Verify client lease for 10.0.0.42"):
until(lambda: iface.address_exist(client, port, ADDRESS))
+11 -7
View File
@@ -26,16 +26,20 @@ with infamy.Test() as test:
with infamy.dhcp.Server(netns, router=ROUTER):
_, port = env.ltop.xlate("client", "data")
config = {
"dhcp-client": {
"client-if": [{
"if-name": f"{port}",
"option": [
{"id": "router"}
]
"interfaces": {
"interface": [{
"name": f"{port}",
"ipv4": {
"infix-dhcp-client:dhcp": {
"option": [
{"id": "router"}
]
}
}
}]
}
}
client.put_config_dict("infix-dhcp-client", config)
client.put_config_dict("ietf-interfaces", config)
with test.step("Verify DHCP client has default route via 192.168.0.254"):
until(lambda: route.ipv4_route_exist(client, "0.0.0.0/0", ROUTER))
+12 -8
View File
@@ -59,14 +59,18 @@ with infamy.Test() as test:
with test.step("Enabling DHCP client, allow option 3 and 121"):
_, port = env.ltop.xlate("client", "data")
client.put_config_dict("infix-dhcp-client", {
"dhcp-client": {
"client-if": [{
"if-name": f"{port}",
"option": [
{"id": "router"},
{"id": "classless-static-route"}
]
client.put_config_dict("ietf-interfaces", {
"interfaces": {
"interface": [{
"name": f"{port}",
"ipv4": {
"infix-dhcp-client:dhcp": {
"option": [
{"id": "router"},
{"id": "classless-static-route"}
]
}
}
}]
}
})
+12 -8
View File
@@ -68,14 +68,18 @@ with infamy.Test() as test:
}})
client.put_config_dicts({
"infix-dhcp-client": {
"dhcp-client": {
"client-if": [{
"if-name": client["link"],
"option": [
{"id": "hostname"},
{"id": "domain"}
]
"ietf-interfaces": {
"interfaces": {
"interface": [{
"name": client["link"],
"ipv4": {
"infix-dhcp-client:dhcp": {
"option": [
{"id": "hostname"},
{"id": "domain"}
]
}
}
}]
}
},
+27 -19
View File
@@ -116,15 +116,19 @@ with infamy.Test() as test:
"ietf-system": {
"system": {"hostname": HOSTNM1}
},
"infix-dhcp-client": {
"dhcp-client": {
"client-if": [{
"if-name": client1["link"],
"option": [
{"id": "router"},
{"id": "client-id", "hex": HOSTCID1},
{"id": 121}
]
"ietf-interfaces": {
"interfaces": {
"interface": [{
"name": client1["link"],
"ipv4": {
"infix-dhcp-client:dhcp": {
"option": [
{"id": "router"},
{"id": "client-id", "hex": HOSTCID1},
{"id": 121}
]
}
}
}]
}
},
@@ -134,16 +138,20 @@ with infamy.Test() as test:
"ietf-system": {
"system": {"hostname": HOSTNM2}
},
"infix-dhcp-client": {
"dhcp-client": {
"client-if": [{
"if-name": client2["link"],
"client-id": HOSTCID2,
"option": [
{"id": "router"},
{"id": "hostname"},
{"id": 121}
]
"ietf-interfaces": {
"interfaces": {
"interface": [{
"name": client2["link"],
"ipv4": {
"infix-dhcp-client:dhcp": {
"client-id": HOSTCID2,
"option": [
{"id": "router"},
{"id": "hostname"},
{"id": 121}
]
}
}
}]
}
},
+45 -33
View File
@@ -200,17 +200,21 @@ with infamy.Test() as test:
# the server is behaving correctly.
client1.put_config_dicts({
"infix-dhcp-client": {
"dhcp-client": {
"client-if": [{
"if-name": client1["server"],
"option": [
{"id": "hostname", "value": "auto"},
{"id": "router"},
{"id": "dns-server"},
{"id": "ntp-server"},
{"id": 121}
]
"ietf-interfaces": {
"interfaces": {
"interface": [{
"name": client1["server"],
"ipv4": {
"infix-dhcp-client:dhcp": {
"option": [
{"id": "hostname", "value": "auto"},
{"id": "router"},
{"id": "dns-server"},
{"id": "ntp-server"},
{"id": 121}
]
}
}
}]
}
},
@@ -222,17 +226,21 @@ with infamy.Test() as test:
}})
client2.put_config_dicts({
"infix-dhcp-client": {
"dhcp-client": {
"client-if": [{
"if-name": client2["server"],
"option": [
{"id": "hostname", "value": "auto"},
{"id": "router"},
{"id": "dns-server"},
{"id": "ntp-server"},
{"id": 121}
]
"ietf-interfaces": {
"interfaces": {
"interface": [{
"name": client2["server"],
"ipv4": {
"infix-dhcp-client:dhcp": {
"option": [
{"id": "hostname", "value": "auto"},
{"id": "router"},
{"id": "dns-server"},
{"id": "ntp-server"},
{"id": 121}
]
}
}
}]
}
},
@@ -244,17 +252,21 @@ with infamy.Test() as test:
}})
client3.put_config_dicts({
"infix-dhcp-client": {
"dhcp-client": {
"client-if": [{
"if-name": client3["server"],
"option": [
{"id": "hostname", "value": "auto"},
{"id": "router"},
{"id": "dns-server"},
{"id": "ntp-server"},
{"id": 121}
]
"ietf-interfaces": {
"interfaces": {
"interface": [{
"name": client3["server"],
"ipv4": {
"infix-dhcp-client:dhcp": {
"option": [
{"id": "hostname", "value": "auto"},
{"id": "router"},
{"id": "dns-server"},
{"id": "ntp-server"},
{"id": 121}
]
}
}
}]
}
},