diff --git a/board/aarch64/bananapi-bpi-r3/rootfs/usr/share/product/bananapi,bpi-r3/etc/factory-config.cfg b/board/aarch64/bananapi-bpi-r3/rootfs/usr/share/product/bananapi,bpi-r3/etc/factory-config.cfg index aa8740c3a..eda410f60 100644 --- a/board/aarch64/bananapi-bpi-r3/rootfs/usr/share/product/bananapi,bpi-r3/etc/factory-config.cfg +++ b/board/aarch64/bananapi-bpi-r3/rootfs/usr/share/product/bananapi,bpi-r3/etc/factory-config.cfg @@ -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 diff --git a/board/aarch64/friendlyarm-nanopi-r2s/rootfs/usr/share/product/friendlyarm,nanopi-r2s/etc/factory-config.cfg b/board/aarch64/friendlyarm-nanopi-r2s/rootfs/usr/share/product/friendlyarm,nanopi-r2s/etc/factory-config.cfg index f4511ef18..527a9f352 100644 --- a/board/aarch64/friendlyarm-nanopi-r2s/rootfs/usr/share/product/friendlyarm,nanopi-r2s/etc/factory-config.cfg +++ b/board/aarch64/friendlyarm-nanopi-r2s/rootfs/usr/share/product/friendlyarm,nanopi-r2s/etc/factory-config.cfg @@ -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 diff --git a/board/aarch64/raspberrypi-rpi64/rootfs/usr/share/product/raspberrypi,4-model-b/etc/factory-config.cfg b/board/aarch64/raspberrypi-rpi64/rootfs/usr/share/product/raspberrypi,4-model-b/etc/factory-config.cfg index 42ae38cc6..3d9c69bab 100644 --- a/board/aarch64/raspberrypi-rpi64/rootfs/usr/share/product/raspberrypi,4-model-b/etc/factory-config.cfg +++ b/board/aarch64/raspberrypi-rpi64/rootfs/usr/share/product/raspberrypi,4-model-b/etc/factory-config.cfg @@ -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 diff --git a/board/common/rootfs/etc/fstab b/board/common/rootfs/etc/fstab index fc5850c79..d84206d61 100644 --- a/board/common/rootfs/etc/fstab +++ b/board/common/rootfs/etc/fstab @@ -15,9 +15,9 @@ cfgfs /config configfs nofail,noauto 0 0 # The chosen backing storage for the overlays placed on /cfg, /etc, # /home, /root, and /var, are determined dynamically by /usr/libexec/infix/mnt # depending on the available devices. -mnttmp /mnt/tmp tmpfs defaults 0 0 -LABEL=aux /mnt/aux auto noatime,nodiratime,noauto,commit=30,errors=remount-ro 0 0 -LABEL=var /mnt/var auto noatime,nodiratime,noauto,commit=30,errors=remount-ro 0 0 -LABEL=cfg /mnt/cfg auto noatime,nodiratime,noauto,commit=30,errors=remount-ro 0 0 -hostfs /mnt/host 9p cache=none,msize=16384,noauto 0 0 -/usr/libexec/infix/mnt# /cfg helper none 0 0 +mnttmp /mnt/tmp tmpfs defaults 0 0 +LABEL=aux /mnt/aux ext2 noatime,nodiratime,noauto,errors=remount-ro 0 0 +LABEL=var /mnt/var ext4 noatime,nodiratime,noauto,commit=30,errors=remount-ro 0 0 +LABEL=cfg /mnt/cfg ext4 noatime,nodiratime,noauto,commit=30,errors=remount-ro 0 0 +hostfs /mnt/host 9p cache=none,msize=16384,noauto 0 0 +/usr/libexec/infix/mnt# /cfg helper none 0 0 diff --git a/board/common/rootfs/usr/libexec/infix/mnt b/board/common/rootfs/usr/libexec/infix/mnt index d46af0c64..4421613f3 100755 --- a/board/common/rootfs/usr/libexec/infix/mnt +++ b/board/common/rootfs/usr/libexec/infix/mnt @@ -44,12 +44,15 @@ check_factory() factory_reset() { find /sys/class/leds/ -type l -exec sh -c 'echo 100 > $0/brightness' {} \; - logger $opt -p user.crit -t "$nm" "Resetting to factory defaults." + print_start "Resetting to factory defaults." + logger $opt -p user.notice -t "$nm" "Resetting to factory defaults." rm -rf /mnt/cfg/* /mnt/var/* - - logger $opt -p user.crit -t "$nm" "Factory reset complete." sync + + logger $opt -p user.notice -t "$nm" "Factory reset complete." + print_end 0 "Factory reset complete." + print_restore } is_mmc() @@ -105,15 +108,18 @@ find_partition_by_label() esac disk="/dev/$devname" + + # + # 1. Try GPT/MBR partition label using sgdisk + # result=$(sgdisk -p "$disk" 2>/dev/null | awk -v label="$label" -v devname="$devname" ' - /^ *[0-9]/ { + /^ *[0-9]/ { if ($7 == label) { - if (devname ~ /^(mmcblk|nvme|loop)/) { - print devname "p" $1 - } else { - print devname $1 - } - exit 0 + if (devname ~ /^(mmcblk|nvme|loop)/) + print devname "p" $1; + else + print devname $1; + exit 0; } } ') @@ -122,7 +128,30 @@ find_partition_by_label() echo "$result" return 0 fi + + # + # 2. Fallback: Check if the whole disk is an ext4/ext2/ext3 filesystem + # + + # Check for ext4/ext2/ext3 magic number (0xEF53) at offset 1080 (1024+56). + magic_number=$(dd if="$disk" bs=1 skip=1080 count=2 2>/dev/null | od -t x2 -A n | tr -d ' \n') + + # Check for both Little-Endian ('53ef') and Big-Endian ('ef53') interpretations of 0xEF53. + # This supports bi-endian architectures like MIPS that may run in BE mode, + # as well as the LE mode which is standard for RISC-V and ext filesystems. + if [ "$magic_number" = "ef53" ] || [ "$magic_number" = "53ef" ]; then + + # Read the volume label from offset 1144 (1024+120) + fslabel=$(dd if="$disk" bs=1 skip=1144 count=16 2>/dev/null | tr -d '\000') + logger $opt -p user.notice -t "$nm" "Found label $fslabel on disk $disk ..." + + if [ "$fslabel" = "$label" ]; then + echo "$devname" + return 0 + fi + fi done + return 1 } @@ -273,6 +302,9 @@ mount_rw() # If something is already setup, leave it be. mountpoint -q "/$1" && return 0 + # If partition doesn't exist (var is optional), signal caller. + find_partition_by_label "$1" >/dev/null || return 1 + # Check if /var has been resized to fill the sdcard/eMMC if [ "$1" = "var" ] && is_mmc; then if [ -f /mnt/aux/resized ] || [ -f /mnt/aux/resized.failed ]; then @@ -289,8 +321,10 @@ mount_rw() # TODO: Also look for UBI partitions - # - tune2fs -c 0 -i 0 LABEL="$1" 2>/dev/null + # Disable periodic fsck, yet keeping safety checks on ext4 + if grep "LABEL=$label" /etc/fstab |grep -q ext4; then + tune2fs -c 0 -i 0 LABEL="$1" 2>/dev/null + fi mount LABEL="$1" 2>/dev/null && return 0 return 1 diff --git a/doc/ChangeLog.md b/doc/ChangeLog.md index 49569077e..9a006a10b 100644 --- a/doc/ChangeLog.md +++ b/doc/ChangeLog.md @@ -8,6 +8,12 @@ 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 +- The `enabled` nore for IPv4 autoconf (ZeroConf) has been dropped, `autoconf` + is now a presence container. Configuration automatically migrated on upgrade - 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 diff --git a/doc/networking.md b/doc/networking.md index b6db43fd7..64e0d7d5b 100644 --- a/doc/networking.md +++ b/doc/networking.md @@ -996,7 +996,7 @@ default. admin@example:/> configure admin@example:/config/> edit interface eth0 ipv4 admin@example:/config/interface/eth0/ipv4/> set address 10.0.1.1 prefix-length 24 - admin@example:/config/interface/eth0/ipv4/> set autoconf enabled true + admin@example:/config/interface/eth0/ipv4/> set autoconf admin@example:/config/interface/eth0/ipv4/> diff +interfaces { + interface eth0 { @@ -1004,9 +1004,7 @@ default. + address 10.0.1.1 { + prefix-length 24; + } - + autoconf { - + enabled true; - + } + + autoconf; + } + } +} @@ -1022,15 +1020,18 @@ default. ipv6 ::1/128 (static) admin@example:/> -As shown, the link-local IPv4 address is configured with `set autconf -enabled true`. The resulting address (169.254.1.3/16) is of type -*random* ([ietf-ip.yang][2]). +As shown, the link-local IPv4 address is configured with `set autoconf`. +The presence of the `autoconf` container enables IPv4 link-local address +assignment. The resulting address (169.254.1.3/16) is of type *random* +([ietf-ip.yang][2]). The IPv4LL client also supports a `request-address` setting which can be used to "seed" the client's starting address. If the address is free it will be used, otherwise it falls back to the default algorithm. - admin@example:/config/interface/eth0/ipv4/> set autoconf request-address 169.254.1.2 + admin@example:/config/interface/eth0/ipv4/> edit autoconf + admin@example:/config/interface/eth0/ipv4/autoconf/> set request-address 169.254.1.2 + admin@example:/config/interface/eth0/ipv4/autoconf/> leave #### Use of DHCP for IPv4 address assignment @@ -1038,9 +1039,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 +1054,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) diff --git a/doc/scripting-sysrepocfg.md b/doc/scripting-sysrepocfg.md index 312fd6ab4..078a2e537 100644 --- a/doc/scripting-sysrepocfg.md +++ b/doc/scripting-sysrepocfg.md @@ -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,41 +189,27 @@ 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 - } -} -~$ scp file.json admin@example.local:/tmp/file.json -~$ ssh admin@example.local 'sysrepocfg -E /tmp/file.json -fjson -d running' -~$ -``` - -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": [ + "ietf-interfaces:interfaces": { + "interface": [ { - "if-name": "e0" + "name": "e0", + "ietf-ip:ipv4": {} } ] } } -admin@example:~$ +~$ scp file.json admin@example.local:/tmp/file.json +~$ ssh admin@example.local 'sysrepocfg -E /tmp/file.json -fjson -d running' +~$ ``` -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 diff --git a/package/confd/confd.mk b/package/confd/confd.mk index 96024a1f0..ed74875bf 100644 --- a/package/confd/confd.mk +++ b/package/confd/confd.mk @@ -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 diff --git a/src/confd/bin/gen-interfaces b/src/confd/bin/gen-interfaces index cad922c23..19d343855 100755 --- a/src/confd/bin/gen-interfaces +++ b/src/confd/bin/gen-interfaces @@ -169,9 +169,23 @@ if [ -n "$bridge" ]; then "name": "$bridge", "type": "infix-if-type:bridge", "ietf-ip:ipv4": { - "infix-ip:autoconf": { - "enabled": $ipv4 - } +EOF + if [ "$ipv4" = "true" ]; then + cat < "$temp" && mv "$temp" "$file" diff --git a/src/confd/share/migrate/1.6/20-autoconf-to-presence.sh b/src/confd/share/migrate/1.6/20-autoconf-to-presence.sh new file mode 100755 index 000000000..988a43522 --- /dev/null +++ b/src/confd/share/migrate/1.6/20-autoconf-to-presence.sh @@ -0,0 +1,26 @@ +#!/bin/sh +# Migrate IPv4 autoconf from enabled leaf to presence container +# Remove the "enabled" leaf, keeping the container only if it was enabled + +file=$1 +temp=${file}.tmp + +jq ' +if .["ietf-interfaces:interfaces"] then + .["ietf-interfaces:interfaces"].interface |= map( + if .["ietf-ip:ipv4"]?."infix-ip:autoconf" then + if .["ietf-ip:ipv4"]."infix-ip:autoconf".enabled == false then + # Remove autoconf container if it was disabled + .["ietf-ip:ipv4"] |= del(."infix-ip:autoconf") + else + # Keep autoconf but remove the enabled leaf + .["ietf-ip:ipv4"]."infix-ip:autoconf" |= del(.enabled) + end + else + . + end + ) +else + . +end +' "$file" > "$temp" && mv "$temp" "$file" diff --git a/src/confd/share/migrate/1.6/Makefile.am b/src/confd/share/migrate/1.6/Makefile.am new file mode 100644 index 000000000..c3a250a5a --- /dev/null +++ b/src/confd/share/migrate/1.6/Makefile.am @@ -0,0 +1,3 @@ +migratedir = $(pkgdatadir)/migrate/1.6 +dist_migrate_DATA = 10-dhcp-client-to-ipv4.sh \ + 20-autoconf-to-presence.sh diff --git a/src/confd/share/migrate/Makefile.am b/src/confd/share/migrate/Makefile.am index 63b1adf73..c5d75c31b 100644 --- a/src/confd/share/migrate/Makefile.am +++ b/src/confd/share/migrate/Makefile.am @@ -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 diff --git a/src/confd/src/core.c b/src/confd/src/core.c index 8ba0ba985..9b29b4883 100644 --- a/src/confd/src/core.c +++ b/src/confd/src/core.c @@ -8,8 +8,8 @@ struct confd confd; -int core_startup_save(sr_session_ctx_t *session, uint32_t sub_id, const char *module, - const char *xpath, sr_event_t event, unsigned request_id, void *priv) +static int core_startup_save(sr_session_ctx_t *session, uint32_t sub_id, const char *module, + const char *xpath, sr_event_t event, unsigned request_id, void *priv) { sr_event_t last_event = -1; static unsigned int last_request = -1; @@ -221,8 +221,10 @@ static int change_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *mod goto free_diff; /* infix-containers */ +#ifdef CONTAINERS if ((rc = infix_containers_change(session, config, diff, event, confd))) goto free_diff; +#endif /* ietf-hardware */ if ((rc = ietf_hardware_change(session, config, diff, event, confd))) @@ -258,16 +260,21 @@ static int change_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *mod AUDIT("The new configuration has been applied."); } + free_diff: - lyd_free_tree(diff); - return rc; + lyd_free_tree(diff); + return rc; } -static inline int subscribe_module(char *model, struct confd *confd, int flags) { - return sr_module_change_subscribe(confd->session, model, "//.", change_cb, confd, - CB_PRIO_PRIMARY, SR_SUBSCR_CHANGE_ALL_MODULES | SR_SUBSCR_DEFAULT | flags, &confd->sub) && +static inline int subscribe_module(char *model, struct confd *confd, int flags) +{ + ERROR("core: subscribing to models"); + return sr_module_change_subscribe(confd->session, model, "//.", change_cb, confd, + CB_PRIO_PRIMARY, SR_SUBSCR_CHANGE_ALL_MODULES | + SR_SUBSCR_DEFAULT | flags, &confd->sub) && sr_module_change_subscribe(confd->startup, model, "//.", core_startup_save, NULL, - CB_PRIO_PASSIVE, SR_SUBSCR_PASSIVE | SR_SUBSCR_CHANGE_ALL_MODULES, &confd->sub); + CB_PRIO_PASSIVE, SR_SUBSCR_CHANGE_ALL_MODULES | + SR_SUBSCR_PASSIVE, &confd->sub); } int sr_plugin_init_cb(sr_session_ctx_t *session, void **priv) @@ -385,9 +392,11 @@ int sr_plugin_init_cb(sr_session_ctx_t *session, void **priv) rc = ietf_system_rpc_init(&confd); if (rc) goto err; +#ifdef CONTAINERS rc = infix_containers_rpc_init(&confd); if (rc) goto err; +#endif rc = infix_dhcp_server_rpc_init(&confd); if (rc) goto err; diff --git a/src/confd/src/core.h b/src/confd/src/core.h index 0317f83ec..d7c2f2e0d 100644 --- a/src/confd/src/core.h +++ b/src/confd/src/core.h @@ -135,7 +135,6 @@ struct confd { struct dagger netdag; }; -int core_startup_save (sr_session_ctx_t *, uint32_t, const char *, const char *, sr_event_t, unsigned, void *); static inline int register_change(sr_session_ctx_t *session, const char *module, const char *xpath, int flags, sr_module_change_cb cb, void *arg, sr_subscription_ctx_t **sub) diff --git a/src/confd/src/ietf-ip.c b/src/confd/src/ietf-ip.c index a428967b1..adcf9cb86 100644 --- a/src/confd/src/ietf-ip.c +++ b/src/confd/src/ietf-ip.c @@ -94,7 +94,7 @@ int netdag_gen_ipv4_autoconf(struct dagger *net, struct lyd_node *cif, * for various reasons: was bridge port, ipv4 was disabled... */ zcip = lydx_get_child(ipconf, "autoconf"); - if (zcip && lydx_is_enabled(zcip, "enabled")) { + if (zcip) { struct lyd_node *node; const char *addr; int diff = 0; @@ -105,9 +105,8 @@ int netdag_gen_ipv4_autoconf(struct dagger *net, struct lyd_node *cif, if (node) { const struct lyd_node *tmp; - tmp = lydx_get_child(node, "enabled"); - if (tmp) - diff++; + /* presence container created or deleted */ + diff++; tmp = lydx_get_child(node, "request-address"); if (tmp) diff++; diff --git a/src/confd/src/ietf-keystore.c b/src/confd/src/ietf-keystore.c index a87303ee5..fa1d786fe 100644 --- a/src/confd/src/ietf-keystore.c +++ b/src/confd/src/ietf-keystore.c @@ -51,89 +51,122 @@ static char *filerd(const char *fn, size_t len) return buf; } -int ietf_keystore_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd) +static int gen_hostkey(const char *name, struct lyd_node *change) { - struct lyd_node *changes, *change; - sr_val_t *list = NULL; + const char *private_key, *public_key; int rc = SR_ERR_OK; + + private_key = lydx_get_cattr(change, "cleartext-private-key"); + public_key = lydx_get_cattr(change, "public-key"); + + if (mkdir(SSH_HOSTKEYS_NEXT, 0600) && (errno != EEXIST)) { + ERRNO("Failed creating %s", SSH_HOSTKEYS_NEXT); + rc = SR_ERR_INTERNAL; + } + + if (systemf("/usr/libexec/infix/mksshkey %s %s %s %s", name, SSH_HOSTKEYS_NEXT, public_key, private_key)) + rc = SR_ERR_INTERNAL; + + return rc; +} + +static int keystore_update(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff) +{ + const char *xpath = "/ietf-keystore:keystore/asymmetric-keys/asymmetric-key"; + sr_val_t *list = NULL; size_t count = 0; - if (diff && !lydx_find_xpathf(diff, XPATH_KEYSTORE_)) - return SR_ERR_OK; + int rc; - switch (event) { - case SR_EV_UPDATE: - rc = sr_get_items(session, "/ietf-keystore:keystore/asymmetric-keys/asymmetric-key", 0, 0, &list, &count); - if (rc != SR_ERR_OK) { - ERROR("Cannot find any asymmetric keys in configuration"); - return 0; + rc = sr_get_items(session, xpath, 0, 0, &list, &count); + if (rc != SR_ERR_OK) { + ERROR("Cannot find any asymmetric keys in configuration"); + return 0; + } + + for (size_t i = 0; i < count; i++) { + char *name = srx_get_str(session, "%s/name", list[i].xpath); + char *public_key_format, *private_key_format; + char *pub_key = NULL, *priv_key = NULL; + sr_val_t *entry = &list[i]; + + if (srx_isset(session, "%s/cleartext-private-key", entry->xpath) || + srx_isset(session, "%s/public-key", entry->xpath)) + continue; + + public_key_format = srx_get_str(session, "%s/public-key-format", entry->xpath); + if (!public_key_format) + continue; + + private_key_format = srx_get_str(session, "%s/private-key-format", entry->xpath); + if (!private_key_format) { + free(public_key_format); + continue; } + if (strcmp(private_key_format, "infix-crypto-types:rsa-private-key-format") || + strcmp(public_key_format, "infix-crypto-types:ssh-public-key-format")) + continue; - for (size_t i = 0; i < count; ++i) { - sr_val_t *entry = &list[i]; - - if (!srx_isset(session, "%s/cleartext-private-key", entry->xpath) && !srx_isset(session, "%s/public-key", entry->xpath)) { - char *private_key_format, *public_key_format; - - public_key_format = srx_get_str(session, "%s/public-key-format", entry->xpath); - if (!public_key_format) - continue; - private_key_format = srx_get_str(session, "%s/private-key-format", entry->xpath); - if (!private_key_format) { - free(public_key_format); - continue; - } - - if (!strcmp(private_key_format, "infix-crypto-types:rsa-private-key-format") && - !strcmp(public_key_format, "infix-crypto-types:ssh-public-key-format")) { - char *pub_key = NULL, *priv_key = NULL, *name; - - name = srx_get_str(session, "%s/name", entry->xpath); - NOTE("SSH key (%s) does not exist, generating...", name); - if (systemf("/usr/libexec/infix/mkkeys %s %s", SSH_PRIVATE_KEY, SSH_PUBLIC_KEY)) { - ERROR("Failed to generate SSH keys for %s", name); - goto next; - } - - priv_key = filerd(SSH_PRIVATE_KEY, filesz(SSH_PRIVATE_KEY)); - if (!priv_key) - goto next; - - pub_key = filerd(SSH_PUBLIC_KEY, filesz(SSH_PUBLIC_KEY)); - if (!pub_key) - goto next; - - rc = srx_set_str(session, priv_key, 0, "%s/cleartext-private-key", entry->xpath); - if (rc) { - ERROR("Failed setting private key for %s... rc: %d", name, rc); - goto next; - } - rc = srx_set_str(session, pub_key, 0, "%s/public-key", entry->xpath); - if (rc != SR_ERR_OK) { - ERROR("Failed setting public key for %s... rc: %d", name, rc); - goto next; - } - next: - if (erase(SSH_PRIVATE_KEY)) - ERRNO("Failed removing SSH server private key"); - if (erase(SSH_PUBLIC_KEY)) - ERRNO("Failed removing SSH server public key"); - - if (priv_key) - free(priv_key); - - if (pub_key) - free(pub_key); - - free(name); - } - free(public_key_format); - free(private_key_format); - } + NOTE("SSH key (%s) does not exist, generating...", name); + if (systemf("/usr/libexec/infix/mkkeys %s %s", SSH_PRIVATE_KEY, SSH_PUBLIC_KEY)) { + ERROR("Failed generating SSH keys for %s", name); + goto next; } - if (list) - sr_free_values(list, count); + priv_key = filerd(SSH_PRIVATE_KEY, filesz(SSH_PRIVATE_KEY)); + if (!priv_key) + goto next; + + pub_key = filerd(SSH_PUBLIC_KEY, filesz(SSH_PUBLIC_KEY)); + if (!pub_key) + goto next; + + rc = srx_set_str(session, priv_key, 0, "%s/cleartext-private-key", entry->xpath); + if (rc) { + ERROR("Failed setting private key for %s... rc: %d", name, rc); + goto next; + } + + rc = srx_set_str(session, pub_key, 0, "%s/public-key", entry->xpath); + if (rc != SR_ERR_OK) { + ERROR("Failed setting public key for %s... rc: %d", name, rc); + goto next; + } + next: + if (erase(SSH_PRIVATE_KEY)) + ERRNO("Failed removing SSH server private key"); + if (erase(SSH_PUBLIC_KEY)) + ERRNO("Failed removing SSH server public key"); + + if (priv_key) + free(priv_key); + + if (pub_key) + free(pub_key); + + free(name); + free(public_key_format); + free(private_key_format); + } + + if (list) + sr_free_values(list, count); + + return 0; +} + +int ietf_keystore_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, + sr_event_t event, struct confd *confd) +{ + struct lyd_node *changes, *change; + int rc = SR_ERR_OK; + + if (diff && !lydx_find_xpathf(diff, XPATH_KEYSTORE_)) + return SR_ERR_OK; + + switch (event) { + case SR_EV_UPDATE: + rc = keystore_update(session, config, diff); break; case SR_EV_CHANGE: case SR_EV_ENABLED: @@ -142,49 +175,35 @@ int ietf_keystore_change(sr_session_ctx_t *session, struct lyd_node *config, str rmrf(SSH_HOSTKEYS_NEXT); return SR_ERR_OK; case SR_EV_DONE: - if(fexist(SSH_HOSTKEYS_NEXT)) { - if(rmrf(SSH_HOSTKEYS)) { + if (fexist(SSH_HOSTKEYS_NEXT)) { + if (rmrf(SSH_HOSTKEYS)) ERRNO("Failed to remove old SSH hostkeys: %d", errno); - } - if (rename(SSH_HOSTKEYS_NEXT, SSH_HOSTKEYS)) ERRNO("Failed switching to new %s", SSH_HOSTKEYS); } return SR_ERR_OK; - default: return SR_ERR_OK; } changes = lydx_get_descendant(config, "keystore", "asymmetric-keys", "asymmetric-key", NULL); - LYX_LIST_FOR_EACH(changes, change, "asymmetric-key") { - const char *name, *private_key_type, *public_key_type; - const char *private_key, *public_key; + const char *name = lydx_get_cattr(change, "name"); + const char *type; - name = lydx_get_cattr(change, "name"); - private_key_type = lydx_get_cattr(change, "private-key-format"); - public_key_type = lydx_get_cattr(change, "public-key-format"); - - if (strcmp(private_key_type, "infix-crypto-types:rsa-private-key-format")) { - INFO("Private key %s is not of SSH type", name); + type = lydx_get_cattr(change, "private-key-format"); + if (strcmp(type, "infix-crypto-types:rsa-private-key-format")) { + INFO("Private key %s is not of SSH type (%s)", name, type); continue; } - if (strcmp(public_key_type, "infix-crypto-types:ssh-public-key-format")) { - INFO("Public key %s is not of SSH type", name); + type = lydx_get_cattr(change, "public-key-format"); + if (strcmp(type, "infix-crypto-types:ssh-public-key-format")) { + INFO("Public key %s is not of SSH type (%s)", name, type); continue; } - private_key = lydx_get_cattr(change, "cleartext-private-key"); - public_key = lydx_get_cattr(change, "public-key"); - - if (mkdir(SSH_HOSTKEYS_NEXT, 0600) && (errno != EEXIST)) { - ERRNO("Failed creating %s", SSH_HOSTKEYS_NEXT); - rc = SR_ERR_INTERNAL; - } - if(systemf("/usr/libexec/infix/mksshkey %s %s %s %s", name, SSH_HOSTKEYS_NEXT, public_key, private_key)) - rc = SR_ERR_INTERNAL; + gen_hostkey(name, change); } return rc; diff --git a/src/confd/src/infix-containers.c b/src/confd/src/infix-containers.c index e73f325c0..359ef320c 100644 --- a/src/confd/src/infix-containers.c +++ b/src/confd/src/infix-containers.c @@ -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; diff --git a/src/confd/src/infix-dhcp-client.c b/src/confd/src/infix-dhcp-client.c index 5310d6bfc..e43bd0318 100644 --- a/src/confd/src/infix-dhcp-client.c +++ b/src/confd/src/infix-dhcp-client.c @@ -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); + + dipv4 = lydx_get_descendant(lyd_child(diface), "ipv4", NULL); + if (!dipv4) + continue; + + ddhcp = lydx_get_descendant(lyd_child(dipv4), "dhcp", NULL); + if (!ddhcp) + continue; - if (lydx_get_op(dif) == LYDX_OP_DELETE) { + /* 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; diff --git a/src/confd/src/infix-dhcp-server.c b/src/confd/src/infix-dhcp-server.c index 2a5431749..ffff18407 100644 --- a/src/confd/src/infix-dhcp-server.c +++ b/src/confd/src/infix-dhcp-server.c @@ -300,9 +300,6 @@ int infix_dhcp_server_change(sr_session_ctx_t *session, struct lyd_node *config, int enabled = 0, added = 0, deleted = 0; sr_error_t err = 0; - if (!lydx_get_xpathf(diff, CFG_XPATH)) - return SR_ERR_OK; - switch (event) { case SR_EV_DONE: break; @@ -312,6 +309,9 @@ int infix_dhcp_server_change(sr_session_ctx_t *session, struct lyd_node *config, return SR_ERR_OK; } + if (!lydx_get_xpathf(diff, CFG_XPATH)) + return SR_ERR_OK; + global = lydx_get_descendant(config, "dhcp-server", NULL); enabled = lydx_is_enabled(global, "enabled"); diff --git a/src/confd/yang/confd.inc b/src/confd/yang/confd.inc index 03b03a70a..cb0056564 100644 --- a/src/confd/yang/confd.inc +++ b/src/confd/yang/confd.inc @@ -20,13 +20,13 @@ MODULES=( "ietf-hardware@2018-03-13.yang -e hardware-state -e hardware-sensor" "infix-hardware@2025-10-30.yang" "ieee802-dot1q-types@2022-10-29.yang" - "infix-ip@2024-09-16.yang" + "infix-ip@2025-11-02.yang" "infix-if-type@2025-02-12.yang" "infix-routing@2024-11-27.yang" "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" diff --git a/src/confd/yang/confd/infix-dhcp-client.yang b/src/confd/yang/confd/infix-dhcp-client.yang index 872e7af1b..9abe21fad 100644 --- a/src/confd/yang/confd/infix-dhcp-client.yang +++ b/src/confd/yang/confd/infix-dhcp-client.yang @@ -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; diff --git a/src/confd/yang/confd/infix-dhcp-client@2025-01-29.yang b/src/confd/yang/confd/infix-dhcp-client@2025-11-02.yang similarity index 100% rename from src/confd/yang/confd/infix-dhcp-client@2025-01-29.yang rename to src/confd/yang/confd/infix-dhcp-client@2025-11-02.yang diff --git a/src/confd/yang/confd/infix-ip.yang b/src/confd/yang/confd/infix-ip.yang index 88a1c93fc..094a972ae 100644 --- a/src/confd/yang/confd/infix-ip.yang +++ b/src/confd/yang/confd/infix-ip.yang @@ -18,6 +18,10 @@ module infix-ip { description "This module augments ietf-ip with Infix extensions and deviations."; + revision 2025-11-02 { + description "Change autoconf to presence container, removing enabled leaf."; + reference "Internal, issue #1109."; + } revision 2024-09-16 { description "Add support for IPv4LL request-address."; reference "Internal."; @@ -36,14 +40,10 @@ module infix-ip { */ augment "/if:interfaces/if:interface/ip:ipv4" { container autoconf { + presence "Enable IPv4 link-local address autoconfiguration for this interface."; description "Parameters to control the autoconfiguration of IPv4 address."; reference "RFC 3927: Dynamic Configuration of IPv4 Link-Local Addresses"; - leaf enabled { - description "Use a ZeroConf/IPv4LL agent to retrieve an 169.254/16 address."; - type boolean; - } - leaf request-address { description "Try to acquire the specified IP address, if available. diff --git a/src/confd/yang/confd/infix-ip@2024-09-16.yang b/src/confd/yang/confd/infix-ip@2025-11-02.yang similarity index 100% rename from src/confd/yang/confd/infix-ip@2024-09-16.yang rename to src/confd/yang/confd/infix-ip@2025-11-02.yang diff --git a/test/case/ietf_interfaces/ipv4_autoconf/test.py b/test/case/ietf_interfaces/ipv4_autoconf/test.py index a1e59f709..5555758ab 100755 --- a/test/case/ietf_interfaces/ipv4_autoconf/test.py +++ b/test/case/ietf_interfaces/ipv4_autoconf/test.py @@ -57,9 +57,7 @@ def no_linklocal(target, iface): "name": tport, "enabled": True, "ipv4": { - "autoconf": { - "enabled": True - } + "infix-ip:autoconf": {} } } ] @@ -79,8 +77,7 @@ def no_linklocal(target, iface): "name": tport, "enabled": True, "ipv4": { - "autoconf": { - "enabled": True, + "infix-ip:autoconf": { "request-address": "169.254.42.42" } } diff --git a/test/case/ietf_routing/route_pref_dhcp/test.py b/test/case/ietf_routing/route_pref_dhcp/test.py index d98b1ab6a..f9ba39e5f 100755 --- a/test/case/ietf_routing/route_pref_dhcp/test.py +++ b/test/case/ietf_routing/route_pref_dhcp/test.py @@ -17,7 +17,7 @@ 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 - } - ] - } } }) diff --git a/test/case/infix_dhcp/client_basic/test.py b/test/case/infix_dhcp/client_basic/test.py index afe0a3915..822b49fcd 100755 --- a/test/case/infix_dhcp/client_basic/test.py +++ b/test/case/infix_dhcp/client_basic/test.py @@ -24,13 +24,16 @@ 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)) diff --git a/test/case/infix_dhcp/client_default_gw/test.py b/test/case/infix_dhcp/client_default_gw/test.py index 2837b0c0c..7d16cd567 100755 --- a/test/case/infix_dhcp/client_default_gw/test.py +++ b/test/case/infix_dhcp/client_default_gw/test.py @@ -26,16 +26,20 @@ 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)) diff --git a/test/case/infix_dhcp/client_routes/test.py b/test/case/infix_dhcp/client_routes/test.py index 62d139cc1..26736d6d8 100755 --- a/test/case/infix_dhcp/client_routes/test.py +++ b/test/case/infix_dhcp/client_routes/test.py @@ -59,14 +59,18 @@ 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"} + ] + } + } }] } }) diff --git a/test/case/infix_dhcp/server_basic/test.py b/test/case/infix_dhcp/server_basic/test.py index 42ff3fb37..164f5f9b6 100755 --- a/test/case/infix_dhcp/server_basic/test.py +++ b/test/case/infix_dhcp/server_basic/test.py @@ -68,14 +68,18 @@ def verify_hostname(dut, hostname): }}) 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"} + ] + } + } }] } }, diff --git a/test/case/infix_dhcp/server_host/test.py b/test/case/infix_dhcp/server_host/test.py index 32f622d73..03187716a 100755 --- a/test/case/infix_dhcp/server_host/test.py +++ b/test/case/infix_dhcp/server_host/test.py @@ -116,15 +116,19 @@ "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 @@ "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} + ] + } + } }] } }, diff --git a/test/case/infix_dhcp/server_subnets/test.py b/test/case/infix_dhcp/server_subnets/test.py index d7b380e45..c4267d6cf 100755 --- a/test/case/infix_dhcp/server_subnets/test.py +++ b/test/case/infix_dhcp/server_subnets/test.py @@ -200,17 +200,21 @@ def has_system_servers(dut, dns, ntp=None): # 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 @@ def has_system_servers(dut, dns, ntp=None): }}) 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 @@ def has_system_servers(dut, dns, ntp=None): }}) 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} + ] + } + } }] } }, diff --git a/test/case/use_case/ospf_container/test.py b/test/case/use_case/ospf_container/test.py index 1568f8d99..1ae865e9e 100755 --- a/test/case/use_case/ospf_container/test.py +++ b/test/case/use_case/ospf_container/test.py @@ -212,7 +212,6 @@ def config_generic(target, router, ring1, ring2, link): "enabled": True, "forwarding": True, "infix-ip:autoconf": { - "enabled": True, "request-address": "169.254.1.1" } },