mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-23 09:23:02 +02:00
Compare commits
31
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
226ea49e7c | ||
|
|
cb633a78d6 | ||
|
|
d2e55eadf8 | ||
|
|
70d51420c9 | ||
|
|
1e80b20856 | ||
|
|
918353dcc7 | ||
|
|
d53a35b867 | ||
|
|
331f60be64 | ||
|
|
4b3ee0fa5e | ||
|
|
06a4995a13 | ||
|
|
45efa9484e | ||
|
|
b9e53e5721 | ||
|
|
1a0dbec571 | ||
|
|
151d04a2dd | ||
|
|
10ef03c971 | ||
|
|
f4fb2f4f84 | ||
|
|
c3b1c28551 | ||
|
|
97d4068f68 | ||
|
|
38bd71614f | ||
|
|
8ffb15773d | ||
|
|
7b26f096fa | ||
|
|
f82534d828 | ||
|
|
ed2355833e | ||
|
|
089b160029 | ||
|
|
a280960d47 | ||
|
|
98b30d7d45 | ||
|
|
5cdcf1f4fe | ||
|
|
da29771398 | ||
|
|
021e864a6f | ||
|
|
9aba65e14b | ||
|
|
489487be16 |
@@ -16,11 +16,12 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
defconfig:
|
||||
- fireant_boot
|
||||
- cn9130_crb_boot
|
||||
- aarch64_qemu_boot
|
||||
- rpi4_boot
|
||||
- bpi_r3_boot
|
||||
- cn9130_crb_boot
|
||||
- fireant_boot
|
||||
- nanopi_r2s_boot
|
||||
- rpi64_boot
|
||||
env:
|
||||
MAKEFLAGS: -j5
|
||||
steps:
|
||||
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
run: |
|
||||
case "${{ inputs.board }}" in
|
||||
raspberrypi-rpi64)
|
||||
echo "BOOTLOADER=rpi4_boot" >> $GITHUB_ENV
|
||||
echo "BOOTLOADER=rpi64_boot" >> $GITHUB_ENV
|
||||
echo "TARGET=aarch64" >> $GITHUB_ENV
|
||||
;;
|
||||
bananapi-bpi-r3)
|
||||
|
||||
@@ -25,6 +25,7 @@ jobs:
|
||||
- name: Fetch kernel.org and check for 6.12 release
|
||||
id: check
|
||||
run: |
|
||||
set -e -o pipefail
|
||||
# Fetch the kernel.org frontpage and extract 6.12 version
|
||||
CURRENT_VERSION=$(curl -s https://www.kernel.org/ | grep -oP '6\.12\.\d+' | head -n1)
|
||||
|
||||
@@ -56,6 +57,7 @@ jobs:
|
||||
- name: Set up git credentials
|
||||
if: steps.check.outputs.new_release == 'true'
|
||||
run: |
|
||||
set -e -o pipefail
|
||||
git config --global user.email "ael-bot@users.noreply.github.com"
|
||||
git config --global user.name "ael-bot"
|
||||
|
||||
@@ -68,6 +70,7 @@ jobs:
|
||||
env:
|
||||
GIT_TERMINAL_PROMPT: 0
|
||||
run: |
|
||||
set -e -o pipefail
|
||||
./utils/kernel-upgrade.sh linux
|
||||
|
||||
- name: Create pull request
|
||||
|
||||
@@ -4,16 +4,23 @@ image cfg.ext4 {
|
||||
size = 128M
|
||||
ext4 {
|
||||
label = "cfg"
|
||||
use-mke2fs = true
|
||||
features = "uninit_bg"
|
||||
extraargs = "-m 0 -i 4096"
|
||||
}
|
||||
}
|
||||
|
||||
# The /var partition will be expanded automatically at first boot
|
||||
# to use the full size of the SD-card or eMMC media.
|
||||
image var.ext4 {
|
||||
empty = true
|
||||
temporary = true
|
||||
size = 1G
|
||||
size = 128M
|
||||
ext4 {
|
||||
label = "var"
|
||||
use-mke2fs = true
|
||||
features = "uninit_bg"
|
||||
extraargs = "-m 0 -i 4096"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-32
@@ -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
|
||||
|
||||
@@ -5,17 +5,24 @@ image cfg.ext4 {
|
||||
|
||||
ext4 {
|
||||
label = "cfg"
|
||||
use-mke2fs = true
|
||||
features = "uninit_bg"
|
||||
extraargs = "-m 0 -i 4096"
|
||||
}
|
||||
}
|
||||
|
||||
# The /var partition will be expanded automatically at first boot
|
||||
# to use the full size of the SD-card or eMMC media.
|
||||
image var.ext4 {
|
||||
empty = true
|
||||
temporary = true
|
||||
size = 512M
|
||||
size = 128M
|
||||
|
||||
ext4 {
|
||||
label = "var"
|
||||
use-mke2fs = true
|
||||
use-mke2fs = true
|
||||
features = "uninit_bg"
|
||||
extraargs = "-m 0 -i 4096"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-32
@@ -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
|
||||
|
||||
@@ -51,9 +51,9 @@ admin@example:/>
|
||||
|
||||
### Pre-built images
|
||||
|
||||
Pre-built SD card images are available here: [infix-rpi4-sdcard.img][sdcard]
|
||||
Pre-built SD card images are available here: [infix-rpi64-sdcard.img][sdcard]
|
||||
|
||||
[0]: https://www.raspberrypi.com/products/raspberry-pi-touch-display/
|
||||
[1]: https://github.com/kernelkit/infix/releases/download/latest-boot/infix-rpi4-sdcard.img
|
||||
[1]: https://github.com/kernelkit/infix/releases/download/latest-boot/infix-rpi64-sdcard.img
|
||||
[2]: https://kernelkit.org/infix/latest/container/#content-mounts
|
||||
[3]: https://kernelkit.org/infix/latest/scripting-restconf/
|
||||
|
||||
@@ -15,21 +15,28 @@ image cfg.ext4 {
|
||||
|
||||
ext4 {
|
||||
label = "cfg"
|
||||
use-mke2fs = true
|
||||
features = "uninit_bg"
|
||||
extraargs = "-m 0 -i 4096"
|
||||
}
|
||||
}
|
||||
|
||||
# The /var partition will be expanded automatically at first boot
|
||||
# to use the full size of the SD-card or eMMC media.
|
||||
image var.ext4 {
|
||||
empty = true
|
||||
temporary = true
|
||||
size = 512M
|
||||
size = 128M
|
||||
|
||||
ext4 {
|
||||
label = "var"
|
||||
use-mke2fs = true
|
||||
use-mke2fs = true
|
||||
features = "uninit_bg"
|
||||
extraargs = "-m 0 -i 4096"
|
||||
}
|
||||
}
|
||||
|
||||
image #INFIX_ID##VERSION#-rpi4-sdcard.img {
|
||||
image #INFIX_ID##VERSION#-rpi64-sdcard.img {
|
||||
hdimage {
|
||||
partition-table-type = "hybrid"
|
||||
}
|
||||
|
||||
+15
-32
@@ -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
|
||||
|
||||
@@ -11,7 +11,8 @@ image aux.ext4 {
|
||||
ext4 {
|
||||
label = "aux"
|
||||
use-mke2fs = true
|
||||
features = "^metadata_csum,^metadata_csum_seed"
|
||||
features = "^metadata_csum,^metadata_csum_seed,uninit_bg"
|
||||
extraargs = "-m 0 -i 4096"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 0 0
|
||||
LABEL=var /mnt/var auto noatime,nodiratime,noauto 0 0
|
||||
LABEL=cfg /mnt/cfg auto noatime,nodiratime,noauto 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
|
||||
|
||||
@@ -19,6 +19,7 @@ set -e
|
||||
|
||||
nm=$(basename "$0")
|
||||
err=0
|
||||
mmc=""
|
||||
opt="-k"
|
||||
|
||||
# External button or bootloader changed kernel command line
|
||||
@@ -43,27 +44,35 @@ 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()
|
||||
{
|
||||
[ -n "$mmc" ] && return $mmc
|
||||
|
||||
# Check if primary or secondary partition (our rootfs) is on MMC
|
||||
for label in primary secondary; do
|
||||
devname=$(find_partition_by_label "$label" 2>/dev/null)
|
||||
if [ -n "$devname" ]; then
|
||||
case "$devname" in
|
||||
mmcblk*)
|
||||
mmc=0
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
done
|
||||
|
||||
mmc=1
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -89,18 +98,28 @@ find_partition_by_label()
|
||||
|
||||
for diskpath in /sys/class/block/*; do
|
||||
devname=$(basename "$diskpath")
|
||||
|
||||
# Skip partitions, only check whole disks
|
||||
[ -f "$diskpath/partition" ] && continue
|
||||
|
||||
# Skip ram, loop, and other virtual devices
|
||||
case "$devname" in
|
||||
ram*|loop*|nullb*|dm-*) continue ;;
|
||||
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;
|
||||
}
|
||||
}
|
||||
')
|
||||
@@ -109,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
|
||||
}
|
||||
|
||||
@@ -133,7 +175,7 @@ status()
|
||||
|
||||
print_start()
|
||||
{
|
||||
printf '\r%s%s' "$(status 3)" "$*" > /dev/console
|
||||
printf '\r\033[K%s%s' "$(status 3)" "$*" > /dev/console
|
||||
}
|
||||
|
||||
print_end()
|
||||
@@ -146,6 +188,12 @@ print_end()
|
||||
fi
|
||||
}
|
||||
|
||||
# Restore Finit's original progress message so its [ OK ] appears correctly
|
||||
print_restore()
|
||||
{
|
||||
print_start "Mounting filesystems from /etc/fstab"
|
||||
}
|
||||
|
||||
# Helper to log resize error and create failure marker (stage 1)
|
||||
resize_err()
|
||||
{
|
||||
@@ -245,9 +293,7 @@ resize_filesystem()
|
||||
mv /mnt/aux/resized.pending /mnt/aux/resized
|
||||
sync
|
||||
|
||||
# Restore Finit's original progress message so its [ OK ] appears correctly
|
||||
print_start "Mounting filesystems from /etc/fstab"
|
||||
|
||||
print_restore
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -256,18 +302,29 @@ 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
|
||||
# 3. Already done
|
||||
:
|
||||
elif [ -f /mnt/aux/resized.pending ]; then
|
||||
# 2. After reboot we can resize ext4
|
||||
resize_filesystem "$1"
|
||||
else
|
||||
# 1. Start with resizing the var partition to the end of the media
|
||||
resize_partition "$1"
|
||||
fi
|
||||
fi
|
||||
|
||||
# TODO: Also look for UBI partitions
|
||||
|
||||
# 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
|
||||
|
||||
@@ -124,6 +124,7 @@ BR2_PACKAGE_MG=y
|
||||
BR2_PACKAGE_NANO=y
|
||||
BR2_TARGET_ROOTFS_SQUASHFS=y
|
||||
# BR2_TARGET_ROOTFS_TAR is not set
|
||||
BR2_PACKAGE_HOST_BMAP_TOOLS=y
|
||||
BR2_PACKAGE_HOST_E2FSPROGS=y
|
||||
BR2_PACKAGE_HOST_ENVIRONMENT_SETUP=y
|
||||
BR2_PACKAGE_HOST_GENEXT2FS=y
|
||||
|
||||
@@ -100,6 +100,7 @@ BR2_PACKAGE_MG=y
|
||||
BR2_PACKAGE_NANO=y
|
||||
BR2_TARGET_ROOTFS_SQUASHFS=y
|
||||
# BR2_TARGET_ROOTFS_TAR is not set
|
||||
BR2_PACKAGE_HOST_BMAP_TOOLS=y
|
||||
BR2_PACKAGE_HOST_E2FSPROGS=y
|
||||
BR2_PACKAGE_HOST_ENVIRONMENT_SETUP=y
|
||||
BR2_PACKAGE_HOST_GENEXT2FS=y
|
||||
@@ -114,8 +115,11 @@ INFIX_HOME="https://github.com/kernelkit/infix/"
|
||||
INFIX_DOC="https://kernelkit.org/infix/"
|
||||
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
|
||||
BR2_PACKAGE_ALDER_ALDER=y
|
||||
BR2_PACKAGE_BANANAPI_BPI_R3=y
|
||||
BR2_PACKAGE_FRIENDLYARM_NANOPI_R2S=y
|
||||
BR2_PACKAGE_MARVELL_CN9130_CRB=y
|
||||
BR2_PACKAGE_MARVELL_ESPRESSOBIN=y
|
||||
BR2_PACKAGE_RASPBERRYPI_RPI64=y
|
||||
BR2_PACKAGE_STYX_DCP_SC_28P=y
|
||||
BR2_PACKAGE_CONFD=y
|
||||
BR2_PACKAGE_CONFD_TEST_MODE=y
|
||||
|
||||
@@ -20,7 +20,7 @@ BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y
|
||||
BR2_TARGET_UBOOT_CUSTOM_VERSION=y
|
||||
BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2023.07.02"
|
||||
BR2_TARGET_UBOOT_BOARD_DEFCONFIG="qemu_arm64"
|
||||
BR2_TARGET_UBOOT_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_INFIX_PATH)/board/common/uboot/extras.config $(BR2_EXTERNAL_INFIX_PATH)/board/aarch64/qemu/uboot/extras.config"
|
||||
BR2_TARGET_UBOOT_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_INFIX_PATH)/board/common/uboot/extras.config $(BR2_EXTERNAL_INFIX_PATH)/board/aarch64/qemu-uboot/extras.config"
|
||||
BR2_TARGET_UBOOT_FORMAT_DTB=y
|
||||
BR2_PACKAGE_HOST_GENIMAGE=y
|
||||
BR2_PACKAGE_HOST_RAUC=y
|
||||
|
||||
@@ -30,9 +30,9 @@ BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y
|
||||
BR2_TARGET_UBOOT_CUSTOM_VERSION=y
|
||||
BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2023.07.02"
|
||||
BR2_TARGET_UBOOT_BOARD_DEFCONFIG="mvebu_crb_cn9130"
|
||||
BR2_TARGET_UBOOT_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_INFIX_PATH)/board/common/uboot/extras.config $(BR2_EXTERNAL_INFIX_PATH)/board/aarch64/cn9130-crb/uboot/extras.config"
|
||||
BR2_TARGET_UBOOT_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_INFIX_PATH)/board/common/uboot/extras.config $(BR2_EXTERNAL_INFIX_PATH)/board/aarch64/marvell-cn9130-crb/uboot/extras.config"
|
||||
BR2_TARGET_UBOOT_FORMAT_DTB=y
|
||||
BR2_TARGET_UBOOT_CUSTOM_DTS_PATH="$(BR2_EXTERNAL_INFIX_PATH)/board/aarch64/cn9130-crb/uboot/cn9130-crb-env.dtsi"
|
||||
BR2_TARGET_UBOOT_CUSTOM_DTS_PATH="$(BR2_EXTERNAL_INFIX_PATH)/board/aarch64/marvell-cn9130-crb/uboot/cn9130-crb-env.dtsi"
|
||||
BR2_PACKAGE_HOST_GENIMAGE=y
|
||||
BR2_PACKAGE_HOST_RAUC=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS=y
|
||||
|
||||
@@ -164,6 +164,7 @@ BR2_TARGET_UBOOT_FORMAT_CUSTOM_NAME="u-boot.itb"
|
||||
BR2_TARGET_UBOOT_SPL=y
|
||||
BR2_TARGET_UBOOT_SPL_NAME="spl/u-boot-spl.bin.normal.out"
|
||||
BR2_TARGET_UBOOT_CUSTOM_DTS_PATH="$(BR2_EXTERNAL_INFIX_PATH)/board/riscv64/visionfive2/uboot/visionfive2-env.dtsi"
|
||||
BR2_PACKAGE_HOST_BMAP_TOOLS=y
|
||||
BR2_PACKAGE_HOST_GENIMAGE=y
|
||||
BR2_PACKAGE_HOST_RAUC=y
|
||||
BR2_PACKAGE_HOST_UBOOT_TOOLS=y
|
||||
|
||||
@@ -18,8 +18,8 @@ BR2_PACKAGE_RPI_FIRMWARE_VARIANT_PI=y
|
||||
BR2_PACKAGE_RPI_FIRMWARE_VARIANT_PI_X=y
|
||||
BR2_PACKAGE_RPI_FIRMWARE_VARIANT_PI4=y
|
||||
BR2_PACKAGE_RPI_FIRMWARE_VARIANT_PI4_X=y
|
||||
BR2_PACKAGE_RPI_FIRMWARE_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/src/board/raspberry-pi64/config.txt"
|
||||
BR2_PACKAGE_RPI_FIRMWARE_CMDLINE_FILE="${BR2_EXTERNAL_INFIX_PATH}/src/board/raspberry-pi64/cmdline.txt"
|
||||
BR2_PACKAGE_RPI_FIRMWARE_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/raspberrypi-rpi64/config.txt"
|
||||
BR2_PACKAGE_RPI_FIRMWARE_CMDLINE_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/raspberrypi-rpi64/cmdline.txt"
|
||||
# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set
|
||||
# BR2_TARGET_ROOTFS_TAR is not set
|
||||
BR2_TARGET_UBOOT=y
|
||||
@@ -27,12 +27,12 @@ BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y
|
||||
BR2_TARGET_UBOOT_CUSTOM_VERSION=y
|
||||
BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2025.01"
|
||||
BR2_TARGET_UBOOT_BOARD_DEFCONFIG="rpi_arm64"
|
||||
BR2_TARGET_UBOOT_CONFIG_FRAGMENT_FILES="${BR2_EXTERNAL_INFIX_PATH}/board/common/uboot/extras.config ${BR2_EXTERNAL_INFIX_PATH}/src/board/raspberry-pi64/uboot/extras.config"
|
||||
BR2_TARGET_UBOOT_CONFIG_FRAGMENT_FILES="${BR2_EXTERNAL_INFIX_PATH}/board/common/uboot/extras.config ${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/raspberrypi-rpi64/uboot/extras.config"
|
||||
BR2_TARGET_UBOOT_NEEDS_DTC=y
|
||||
BR2_TARGET_UBOOT_FORMAT_DTB=y
|
||||
BR2_TARGET_UBOOT_FORMAT_CUSTOM=y
|
||||
BR2_TARGET_UBOOT_FORMAT_CUSTOM_NAME="arch/arm/dts/infix-key.dtbo arch/arm/dts/rpi-env.dtbo"
|
||||
BR2_TARGET_UBOOT_CUSTOM_DTS_PATH="${BR2_EXTERNAL_INFIX_PATH}/src/board/raspberry-pi64/uboot/rpi-env.dtso"
|
||||
BR2_TARGET_UBOOT_CUSTOM_DTS_PATH="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/raspberrypi-rpi64/uboot/rpi-env.dtso"
|
||||
BR2_PACKAGE_HOST_BMAP_TOOLS=y
|
||||
BR2_PACKAGE_HOST_GENIMAGE=y
|
||||
BR2_PACKAGE_HOST_RAUC=y
|
||||
+27
-1
@@ -3,6 +3,31 @@ Change Log
|
||||
|
||||
All notable changes to the project are documented in this file.
|
||||
|
||||
[v25.11.0][UNRELEASED]
|
||||
-------------------------
|
||||
|
||||
### 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
|
||||
- The `utils/mkimage.sh` script now supports fetching the bootloader
|
||||
- The raspberrypi-rpi64 board's bootloader is now aptly named rpi64
|
||||
|
||||
### Fixes
|
||||
|
||||
- Fix #855: User admin sometimes fails to be added to `wheel` group
|
||||
- Fix serious regression in boot time, introduced in v25.10, delays the
|
||||
boot step "Mounting filesystems ..." with up to 30 seconds!
|
||||
|
||||
[lastest-boot]: https://github.com/kernelkit/infix/releases/latest-boot
|
||||
|
||||
[v25.10.0][] - 2025-10-31
|
||||
-------------------------
|
||||
|
||||
@@ -1725,7 +1750,8 @@ Supported YANG models in addition to those used by sysrepo and netopeer:
|
||||
- N/A
|
||||
|
||||
[buildroot]: https://buildroot.org/
|
||||
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v25.09.0...HEAD
|
||||
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v25.10.0...HEAD
|
||||
[v25.11.0]: https://github.com/kernelkit/infix/compare/v25.10.0...v26.11.0
|
||||
[v25.10.0]: https://github.com/kernelkit/infix/compare/v25.09.0...v26.10.0
|
||||
[v25.09.0]: https://github.com/kernelkit/infix/compare/v25.08.0...v26.09.0
|
||||
[v25.08.0]: https://github.com/kernelkit/infix/compare/v25.06.1...v26.08.0
|
||||
|
||||
+37
-11
@@ -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.
|
||||

|
||||
|
||||
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)
|
||||
|
||||
|
||||
+16
-28
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 <<EOF
|
||||
"infix-ip:autoconf": {}
|
||||
EOF
|
||||
if [ "$dhcp" = "true" ]; then
|
||||
cat <<EOF
|
||||
,
|
||||
"infix-dhcp-client:dhcp": {}
|
||||
EOF
|
||||
fi
|
||||
elif [ "$dhcp" = "true" ]; then
|
||||
cat <<EOF
|
||||
"infix-dhcp-client:dhcp": {}
|
||||
EOF
|
||||
fi
|
||||
cat <<EOF
|
||||
},
|
||||
"ietf-ip:ipv6": {
|
||||
"enabled": true,
|
||||
@@ -195,18 +209,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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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"
|
||||
+26
@@ -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"
|
||||
@@ -0,0 +1,3 @@
|
||||
migratedir = $(pkgdatadir)/migrate/1.6
|
||||
dist_migrate_DATA = 10-dhcp-client-to-ipv4.sh \
|
||||
20-autoconf-to-presence.sh
|
||||
@@ -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
|
||||
|
||||
+347
-97
@@ -1,21 +1,23 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
|
||||
#include <srx/srx_val.h>
|
||||
#include <srx/common.h>
|
||||
#include <srx/lyx.h>
|
||||
#include "core.h"
|
||||
|
||||
struct confd confd;
|
||||
|
||||
|
||||
uint32_t core_hook_prio(void)
|
||||
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)
|
||||
{
|
||||
static uint32_t hook_prio = CB_PRIO_PASSIVE;
|
||||
sr_event_t last_event = -1;
|
||||
static unsigned int last_request = -1;
|
||||
if (last_event == event && last_request == request_id)
|
||||
return SR_ERR_OK;
|
||||
last_event = event;
|
||||
last_request = request_id;
|
||||
|
||||
return hook_prio--;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
/* skip in bootstrap, triggered by load script to initialize startup datastore */
|
||||
if (systemf("runlevel >/dev/null 2>&1"))
|
||||
return SR_ERR_OK;
|
||||
@@ -26,70 +28,253 @@ int core_startup_save(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
static const char *ev2str(sr_event_t ev)
|
||||
static confd_dependency_t add_dependencies(struct lyd_node **diff, const char *xpath, const char *value)
|
||||
{
|
||||
switch (ev) {
|
||||
case SR_EV_UPDATE: return "UPDATE";
|
||||
case SR_EV_CHANGE: return "CHANGE";
|
||||
case SR_EV_DONE: return "DONE";
|
||||
case SR_EV_ABORT: return "ABORT";
|
||||
case SR_EV_ENABLED: return "ENABLED";
|
||||
case SR_EV_RPC: return "ABORT";
|
||||
default:
|
||||
break;
|
||||
struct lyd_node *new_node = NULL;
|
||||
struct lyd_node *target = NULL;
|
||||
struct lyd_node *root = NULL;
|
||||
int rc;
|
||||
|
||||
if (!lydx_get_xpathf(*diff, "%s", xpath)) {
|
||||
/* Create the path, potentially creating a new tree */
|
||||
rc = lyd_new_path(NULL, LYD_CTX(*diff), xpath, value, LYD_NEW_PATH_UPDATE, &new_node);
|
||||
if (rc != LY_SUCCESS || !new_node) {
|
||||
ERROR("lyd_new_path failed with rc=%d", rc);
|
||||
return CONFD_DEP_ERROR;
|
||||
}
|
||||
|
||||
root = new_node;
|
||||
while (root->parent)
|
||||
root = lyd_parent(root);
|
||||
|
||||
rc = lyd_merge_siblings(diff, root, LYD_MERGE_DESTRUCT);
|
||||
if (rc != LY_SUCCESS) {
|
||||
ERROR("lyd_merge_siblings failed with rc=%d", rc);
|
||||
lyd_free_tree(root);
|
||||
return CONFD_DEP_ERROR;
|
||||
}
|
||||
|
||||
target = lydx_get_xpathf(*diff, "%s", xpath);
|
||||
if (target) {
|
||||
lyd_new_meta(LYD_CTX(target), target, NULL,
|
||||
"yang:operation", "replace", false, NULL);
|
||||
} else {
|
||||
return CONFD_DEP_ERROR;
|
||||
}
|
||||
|
||||
return CONFD_DEP_ADDED;
|
||||
}
|
||||
|
||||
return "UNKNOWN";
|
||||
return CONFD_DEP_DONE;
|
||||
}
|
||||
|
||||
int core_pre_hook(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 confd_dependency_t handle_dependencies(struct lyd_node **diff, struct lyd_node *config)
|
||||
{
|
||||
return 0;
|
||||
struct lyd_node *dkeys, *dkey, *hostname;
|
||||
confd_dependency_t result = CONFD_DEP_DONE;
|
||||
const char *key_name;
|
||||
|
||||
dkeys = lydx_get_descendant(*diff, "keystore", "symmetric-keys", "symmetric-key", NULL);
|
||||
|
||||
LYX_LIST_FOR_EACH(dkeys, dkey, "symmetric-key") {
|
||||
struct ly_set *ifaces;
|
||||
uint32_t i;
|
||||
|
||||
key_name = lydx_get_cattr(dkey, "name");
|
||||
ifaces = lydx_find_xpathf(config, "/ietf-interfaces:interfaces/interface[infix-interfaces:wifi/secret='%s']", key_name);
|
||||
if (ifaces && ifaces->count > 0) {
|
||||
for (i = 0; i < ifaces->count; i++) {
|
||||
struct lyd_node *iface = ifaces->dnodes[i];
|
||||
const char *ifname;
|
||||
char xpath[256];
|
||||
ifname = lydx_get_cattr(iface, "name");
|
||||
snprintf(xpath, sizeof(xpath), "/ietf-interfaces:interfaces/interface[name='%s']/infix-interfaces:wifi/secret", ifname);
|
||||
result = add_dependencies(diff, xpath, key_name);
|
||||
if (result == CONFD_DEP_ERROR) {
|
||||
ERROR("Failed to add wifi node to diff for interface %s", ifname);
|
||||
ly_set_free(ifaces, NULL);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
ly_set_free(ifaces, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
dkeys = lydx_get_descendant(*diff, "keystore", "asymmetric-keys", "asymmetric-key", NULL);
|
||||
LYX_LIST_FOR_EACH(dkeys, dkey, "asymmetric-key") {
|
||||
struct ly_set *hostkeys;
|
||||
uint32_t i;
|
||||
|
||||
key_name = lydx_get_cattr(dkey, "name");
|
||||
hostkeys = lydx_find_xpathf(config, "/infix-services:ssh/hostkey[.='%s']", key_name);
|
||||
if (hostkeys && hostkeys->count > 0) {
|
||||
for (i = 0; i < hostkeys->count; i++) {
|
||||
char xpath[256];
|
||||
snprintf(xpath, sizeof(xpath), "/infix-services:ssh/hostkey[.='%s']", key_name);
|
||||
result = add_dependencies(diff, xpath, key_name);
|
||||
if (result == CONFD_DEP_ERROR) {
|
||||
ERROR("Failed to add ssh hostkey to diff for key %s", key_name);
|
||||
ly_set_free(hostkeys, NULL);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
ly_set_free(hostkeys, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
hostname = lydx_get_xpathf(*diff, "/ietf-system:system/hostname");
|
||||
if (hostname) {
|
||||
struct lyd_node *mdns, *dhcp_server;
|
||||
|
||||
dhcp_server = lydx_get_xpathf(config, "/infix-dhcp-server:dhcp-server/enabled");
|
||||
if(dhcp_server && lydx_is_enabled(dhcp_server, "enabled")) {
|
||||
result = add_dependencies(diff, "/infix-dhcp-server:dhcp-server/enabled", "true");
|
||||
if (result == CONFD_DEP_ERROR) {
|
||||
ERROR("Failed to add dhcp-server to diff on hostname change");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
mdns = lydx_get_xpathf(config, "/infix-services:mdns");
|
||||
if (mdns && lydx_is_enabled(mdns, "enabled")) {
|
||||
result = add_dependencies(diff, "/infix-services:mdns/enabled", "true");
|
||||
if (result == CONFD_DEP_ERROR) {
|
||||
ERROR("Failed to add mdns to diff on hostname change");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run on UPDATE to see how many modules have changes in the inbound changeset
|
||||
* Run on DONE, after the last module callback has run, to activate changes.
|
||||
* For details, see https://github.com/sysrepo/sysrepo/issues/2188
|
||||
*/
|
||||
int core_post_hook(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 change_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *module_name,
|
||||
const char *xpath, sr_event_t event, uint32_t request_id, void *_confd)
|
||||
{
|
||||
static size_t num_changes = 0;
|
||||
struct lyd_node *diff = NULL, *config = NULL;
|
||||
static sr_event_t last_event = -1;
|
||||
struct confd *confd = _confd;
|
||||
static uint32_t last_request = 0;
|
||||
confd_dependency_t result;
|
||||
sr_data_t *cfg = NULL;
|
||||
int rc = SR_ERR_OK;
|
||||
int max_dep = 10;
|
||||
|
||||
switch (event) {
|
||||
case SR_EV_CHANGE:
|
||||
num_changes++;
|
||||
if (request_id == last_request && last_event == event)
|
||||
return SR_ERR_OK;
|
||||
case SR_EV_ABORT:
|
||||
num_changes = 0;
|
||||
return SR_ERR_OK;
|
||||
case SR_EV_DONE:
|
||||
num_changes--;
|
||||
if (num_changes > 0)
|
||||
last_request = request_id;
|
||||
last_event = event;
|
||||
|
||||
if (event == SR_EV_CHANGE || event == SR_EV_DONE) {
|
||||
rc = srx_get_diff(session, &diff);
|
||||
if (rc != SR_ERR_OK) {
|
||||
ERROR("Failed to get diff: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
rc = sr_get_data(session, "//.", 0, 0, 0, &cfg);
|
||||
if (rc || !cfg)
|
||||
goto free_diff;
|
||||
|
||||
config = cfg->tree;
|
||||
while ((result = handle_dependencies(&diff, config)) != CONFD_DEP_DONE) {
|
||||
if (max_dep == 0) {
|
||||
ERROR("Max dependency depth reached");
|
||||
return SR_ERR_INTERNAL;
|
||||
}
|
||||
if (result == CONFD_DEP_ERROR) {
|
||||
ERROR("Failed to add dependencies");
|
||||
return SR_ERR_INTERNAL;
|
||||
}
|
||||
max_dep--;
|
||||
}
|
||||
#if 0
|
||||
/* Debug: print diff to file */
|
||||
FILE *f = fopen("/tmp/confd-diff.json", "w");
|
||||
if (f) {
|
||||
lyd_print_file(f, diff, LYD_JSON, LYD_PRINT_WITHSIBLINGS);
|
||||
fclose(f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ietf-interfaces */
|
||||
if ((rc = ietf_interfaces_change(session, config, diff, event, confd)))
|
||||
goto free_diff;
|
||||
|
||||
/* infix-dhcp-client*/
|
||||
if ((rc = infix_dhcp_client_change(session, config, diff, event, confd)))
|
||||
goto free_diff;
|
||||
|
||||
/* ietf-keystore */
|
||||
if ((rc = ietf_keystore_change(session, config, diff, event, confd)))
|
||||
goto free_diff;
|
||||
|
||||
/* infix-services */
|
||||
if ((rc = infix_services_change(session, config, diff, event, confd)))
|
||||
goto free_diff;
|
||||
|
||||
/* ietf-syslog*/
|
||||
if ((rc = ietf_syslog_change(session, config, diff, event, confd)))
|
||||
goto free_diff;
|
||||
|
||||
/* ietf-system */
|
||||
if ((rc = ietf_system_change(session, config, diff, event, confd)))
|
||||
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)))
|
||||
goto free_diff;
|
||||
|
||||
/* ietf-routing */
|
||||
if ((rc = ietf_routing_change(session, config, diff, event, confd)))
|
||||
goto free_diff;
|
||||
|
||||
/* infix-dhcp-server */
|
||||
if ((rc = infix_dhcp_server_change(session, config, diff, event, confd)))
|
||||
goto free_diff;
|
||||
|
||||
/* infix-firewall */
|
||||
if ((rc = infix_firewall_change(session, config, diff, event, confd)))
|
||||
goto free_diff;
|
||||
|
||||
if (cfg)
|
||||
sr_release_data(cfg);
|
||||
|
||||
if (event == SR_EV_DONE) {
|
||||
/* skip reload in bootstrap, implicit reload in runlevel change */
|
||||
if (systemf("runlevel >/dev/null 2>&1")) {
|
||||
/* trigger any tasks waiting for confd to have applied *-config */
|
||||
system("initctl -nbq cond set bootstrap");
|
||||
return SR_ERR_OK;
|
||||
break;
|
||||
default:
|
||||
ERROR("core_post_hook() should not be called with event %s", ev2str(event));
|
||||
return SR_ERR_SYS;
|
||||
}
|
||||
|
||||
if (systemf("initctl -b reload")) {
|
||||
EMERG("initctl reload: failed applying new configuration!");
|
||||
return SR_ERR_SYS;
|
||||
}
|
||||
|
||||
AUDIT("The new configuration has been applied.");
|
||||
}
|
||||
|
||||
/* skip reload in bootstrap, implicit reload in runlevel change */
|
||||
if (systemf("runlevel >/dev/null 2>&1")) {
|
||||
/* trigger any tasks waiting for confd to have applied *-config */
|
||||
system("initctl -nbq cond set bootstrap");
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
free_diff:
|
||||
lyd_free_tree(diff);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (systemf("initctl -b reload")) {
|
||||
EMERG("initctl reload: failed applying new configuration!");
|
||||
return SR_ERR_SYS;
|
||||
}
|
||||
|
||||
AUDIT("The new configuration has been applied.");
|
||||
|
||||
return SR_ERR_OK;
|
||||
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_CHANGE_ALL_MODULES |
|
||||
SR_SUBSCR_PASSIVE, &confd->sub);
|
||||
}
|
||||
|
||||
int sr_plugin_init_cb(sr_session_ctx_t *session, void **priv)
|
||||
@@ -136,56 +321,121 @@ int sr_plugin_init_cb(sr_session_ctx_t *session, void **priv)
|
||||
*/
|
||||
confd.ifquirks = json_load_file("/etc/product/interface-quirks.json", 0, NULL);
|
||||
|
||||
rc = ietf_interfaces_init(&confd);
|
||||
rc = subscribe_module("ietf-interfaces", &confd, 0);
|
||||
if (rc) {
|
||||
ERROR("Failed to subscribe to ietf-interfaces");
|
||||
goto err;
|
||||
}
|
||||
rc = subscribe_module("ietf-netconf-acm", &confd, 0);
|
||||
if (rc) {
|
||||
ERROR("Failed to subscribe to ietf-netconf-acm");
|
||||
goto err;
|
||||
}
|
||||
rc = subscribe_module("infix-dhcp-client", &confd, 0);
|
||||
if (rc) {
|
||||
ERROR("Failed to subscribe to infix-dhcp-client");
|
||||
goto err;
|
||||
}
|
||||
rc = subscribe_module("ietf-keystore", &confd, SR_SUBSCR_UPDATE);
|
||||
if (rc) {
|
||||
ERROR("Failed to subscribe to ietf-keystore");
|
||||
goto err;
|
||||
}
|
||||
rc = subscribe_module("infix-services", &confd, 0);
|
||||
if (rc) {
|
||||
ERROR("Failed to subscribe to infix-services");
|
||||
goto err;
|
||||
}
|
||||
rc = subscribe_module("ietf-system", &confd, 0);
|
||||
if (rc) {
|
||||
ERROR("Failed to subscribe to ietf-system");
|
||||
goto err;
|
||||
}
|
||||
rc = subscribe_module("ieee802-dot1ab-lldp", &confd, 0);
|
||||
if (rc) {
|
||||
ERROR("Failed to subscribe to ieee802-dot1ab-lldp");
|
||||
goto err;
|
||||
}
|
||||
#ifdef CONTAINERS
|
||||
rc = subscribe_module("infix-containers", &confd, 0);
|
||||
if (rc) {
|
||||
ERROR("Failed to subscribe to infix-containers");
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
rc = subscribe_module("infix-dhcp-server", &confd, 0);
|
||||
if (rc) {
|
||||
ERROR("Failed to subscribe to infix-dhcp-server");
|
||||
goto err;
|
||||
}
|
||||
rc = subscribe_module("ietf-routing", &confd, 0);
|
||||
if (rc) {
|
||||
ERROR("Failed to subscribe to ietf-routing");
|
||||
goto err;
|
||||
}
|
||||
rc = subscribe_module("ietf-hardware", &confd, 0);
|
||||
if (rc) {
|
||||
ERROR("Failed to subscribe to ietf-hardware");
|
||||
goto err;
|
||||
}
|
||||
rc = subscribe_module("infix-firewall", &confd, 0);
|
||||
if (rc) {
|
||||
ERROR("Failed to subscribe to infix-firewall");
|
||||
goto err;
|
||||
}
|
||||
rc = subscribe_module("infix-meta", &confd, SR_SUBSCR_UPDATE);
|
||||
if (rc) {
|
||||
ERROR("Failed to subscribe to infix-meta");
|
||||
goto err;
|
||||
}
|
||||
|
||||
rc = ietf_system_rpc_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
rc = ietf_keystore_init(&confd);
|
||||
#ifdef CONTAINERS
|
||||
rc = infix_containers_rpc_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
rc = ietf_syslog_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
rc = ietf_system_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
rc = infix_containers_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
rc = infix_dhcp_client_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
rc = infix_dhcp_server_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
rc = infix_factory_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
rc = ietf_factory_default_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
rc = ietf_routing_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
rc = infix_meta_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
rc = infix_system_sw_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
rc = infix_services_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
rc = ietf_hardware_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
rc = infix_firewall_init(&confd);
|
||||
#endif
|
||||
rc = infix_dhcp_server_rpc_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
rc = infix_factory_rpc_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
rc = ietf_factory_default_rpc_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
rc = infix_firewall_rpc_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
rc = infix_system_sw_rpc_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
/* Candidate infer configurations */
|
||||
rc = ietf_hardware_candidate_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
rc = infix_firewall_candidate_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
rc = infix_dhcp_server_candidate_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
rc = infix_dhcp_client_candidate_init(&confd);
|
||||
if (rc)
|
||||
goto err;
|
||||
/* YOUR_INIT GOES HERE */
|
||||
|
||||
return SR_ERR_OK;
|
||||
|
||||
err:
|
||||
ERROR("init failed: %s", sr_strerror(rc));
|
||||
if (confd.root)
|
||||
|
||||
+39
-50
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <jansson.h>
|
||||
|
||||
#include <srx/lyx.h>
|
||||
#include <srx/common.h>
|
||||
#include <srx/helpers.h>
|
||||
#include <srx/systemv.h>
|
||||
@@ -100,6 +101,11 @@ static inline char *xpath_base(const char *xpath)
|
||||
|
||||
return path;
|
||||
}
|
||||
typedef enum {
|
||||
CONFD_DEP_DONE = 0,
|
||||
CONFD_DEP_ADDED = 1,
|
||||
CONFD_DEP_ERROR = 2
|
||||
} confd_dependency_t;
|
||||
|
||||
#define REGISTER_CHANGE(s,m,x,f,c,a,u) \
|
||||
if ((rc = register_change(s, m, x, f, c, a, u))) \
|
||||
@@ -129,47 +135,17 @@ struct confd {
|
||||
struct dagger netdag;
|
||||
};
|
||||
|
||||
uint32_t core_hook_prio (void);
|
||||
int core_pre_hook (sr_session_ctx_t *, uint32_t, const char *, const char *, sr_event_t, unsigned, void *);
|
||||
int core_post_hook (sr_session_ctx_t *, uint32_t, const char *, const char *, sr_event_t, unsigned, void *);
|
||||
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)
|
||||
{
|
||||
struct confd *ptr = (struct confd *)arg;
|
||||
bool need_core_hooks;
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* For standard subscribtions we hook into the callback chain
|
||||
* for all modules to figure out, per changeset, which of the
|
||||
* callbacks is the last one. This is where we want to call the
|
||||
* global commit-done hook for candidate -> running changes and
|
||||
* the startup-save hook for running -> startup copying.
|
||||
*/
|
||||
|
||||
need_core_hooks = !(flags & SR_SUBSCR_UPDATE);
|
||||
|
||||
if (need_core_hooks) {
|
||||
sr_module_change_subscribe(ptr->session, module, xpath, core_pre_hook, NULL,
|
||||
0, SR_SUBSCR_PASSIVE, sub);
|
||||
}
|
||||
|
||||
rc = sr_module_change_subscribe(session, module, xpath, cb, arg,
|
||||
int rc = sr_module_change_subscribe(session, module, xpath, cb, arg,
|
||||
CB_PRIO_PRIMARY, flags | SR_SUBSCR_DEFAULT, sub);
|
||||
if (rc) {
|
||||
ERROR("failed subscribing to changes of %s: %s", xpath, sr_strerror(rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (need_core_hooks) {
|
||||
sr_module_change_subscribe(ptr->session, module, xpath, core_post_hook, NULL,
|
||||
core_hook_prio(), SR_SUBSCR_PASSIVE, sub);
|
||||
sr_module_change_subscribe(ptr->startup, module, xpath, core_startup_save, NULL,
|
||||
core_hook_prio(), SR_SUBSCR_PASSIVE, sub);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -206,57 +182,70 @@ static inline int register_rpc(sr_session_ctx_t *session, const char *xpath,
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* ietf-interfaces.c */
|
||||
int ietf_interfaces_init(struct confd *confd);
|
||||
int ietf_interfaces_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
|
||||
int ietf_interfaces_cand_init(struct confd *confd);
|
||||
|
||||
/* ietf-syslog.c */
|
||||
int ietf_syslog_init(struct confd *confd);
|
||||
int ietf_syslog_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
|
||||
|
||||
/* ietf-system.c */
|
||||
int ietf_system_init (struct confd *confd);
|
||||
int ietf_system_rpc_init (struct confd *confd);
|
||||
int hostnamefmt (struct confd *confd, const char *fmt, char *hostnm, size_t hostlen, char *domain, size_t domlen);
|
||||
int ietf_system_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
|
||||
|
||||
/* infix-containers.c */
|
||||
#ifdef CONTAINERS
|
||||
int infix_containers_init(struct confd *confd);
|
||||
int infix_containers_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
|
||||
int infix_containers_rpc_init(struct confd *confd);
|
||||
#else
|
||||
static inline int infix_containers_init(struct confd *confd) { return 0; }
|
||||
static inline int infix_containers_rpc_init(struct confd *confd) { return 0; }
|
||||
static inline int infix_containers_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd) { return 0; }
|
||||
#endif
|
||||
|
||||
/* infix-dhcp-common.c */
|
||||
int dhcp_option_lookup(const struct lyd_node *id);
|
||||
|
||||
/* infix-dhcp-client.c */
|
||||
int infix_dhcp_client_init(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);
|
||||
int infix_dhcp_client_candidate_init(struct confd *confd);
|
||||
|
||||
/* infix-dhcp-server.c */
|
||||
int infix_dhcp_server_init(struct confd *confd);
|
||||
|
||||
/* ietf-factory-default */
|
||||
int ietf_factory_default_init(struct confd *confd);
|
||||
int infix_dhcp_server_candidate_init(struct confd *confd);
|
||||
int infix_dhcp_server_rpc_init(struct confd *confd);
|
||||
int infix_dhcp_server_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
|
||||
|
||||
/* ietf-routing */
|
||||
int ietf_routing_init(struct confd *confd);
|
||||
int ietf_routing_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
|
||||
|
||||
/* infix-factory.c */
|
||||
int infix_factory_init(struct confd *confd);
|
||||
int infix_factory_rpc_init(struct confd *confd);
|
||||
|
||||
/* infix-factory.c */
|
||||
int infix_meta_init(struct confd *confd);
|
||||
/* ietf-factory-default */
|
||||
int ietf_factory_default_rpc_init(struct confd *confd);
|
||||
|
||||
/* infix-meta.c */
|
||||
int infix_meta_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
|
||||
|
||||
/* infix-system-software.c */
|
||||
int infix_system_sw_init(struct confd *confd);
|
||||
int infix_system_sw_rpc_init(struct confd *confd);
|
||||
|
||||
/* infix-services.c */
|
||||
int infix_services_init(struct confd *confd);
|
||||
int infix_services_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
|
||||
|
||||
/* ietf-hardware.c */
|
||||
int ietf_hardware_init(struct confd *confd);
|
||||
int ietf_hardware_candidate_init(struct confd *confd);
|
||||
int ietf_hardware_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
|
||||
|
||||
/* ietf-keystore.c */
|
||||
int ietf_keystore_init(struct confd *confd);
|
||||
#define SSH_HOSTKEYS "/etc/ssh/hostkeys"
|
||||
#define SSH_HOSTKEYS_NEXT SSH_HOSTKEYS"+"
|
||||
int ietf_keystore_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
|
||||
|
||||
/* infix-firewall.c */
|
||||
int infix_firewall_init(struct confd *confd);
|
||||
int infix_firewall_rpc_init(struct confd *confd);
|
||||
int infix_firewall_candidate_init(struct confd *confd);
|
||||
int infix_firewall_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
|
||||
|
||||
#endif /* CONFD_CORE_H_ */
|
||||
|
||||
@@ -16,7 +16,7 @@ static int factory_reset(sr_session_ctx_t *session, uint32_t sub_id, const char
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ietf_factory_default_init(struct confd *confd)
|
||||
int ietf_factory_default_rpc_init(struct confd *confd)
|
||||
{
|
||||
int rc;
|
||||
|
||||
|
||||
@@ -185,26 +185,15 @@ static int hardware_cand(sr_session_ctx_t *session, uint32_t sub_id, const char
|
||||
return err;
|
||||
}
|
||||
|
||||
static int change_hardware(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
const char *xpath, sr_event_t event, unsigned request_id, void *priv)
|
||||
int ietf_hardware_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
struct lyd_node *diff, *difs = NULL, *dif = NULL, *cifs = NULL, *cif = NULL;
|
||||
sr_data_t *cfg;
|
||||
struct lyd_node *difs = NULL, *dif = NULL, *cifs = NULL, *cif = NULL;
|
||||
int rc = SR_ERR_OK;
|
||||
struct confd *confd = (struct confd *)priv;
|
||||
|
||||
if (event != SR_EV_DONE)
|
||||
if (event != SR_EV_DONE || !lydx_find_xpathf(diff, XPATH_BASE_))
|
||||
return SR_ERR_OK;
|
||||
|
||||
rc = sr_get_data(session, XPATH_BASE_ "//.", 0, 0, 0, &cfg);
|
||||
if (rc || !cfg)
|
||||
goto err;
|
||||
|
||||
rc = srx_get_diff(session, &diff);
|
||||
if (rc)
|
||||
goto err_release_data;
|
||||
|
||||
cifs = lydx_get_descendant(cfg->tree, "hardware", "component", NULL);
|
||||
cifs = lydx_get_descendant(config, "hardware", "component", NULL);
|
||||
difs = lydx_get_descendant(diff, "hardware", "component", NULL);
|
||||
|
||||
LYX_LIST_FOR_EACH(difs, dif, "component") {
|
||||
@@ -218,7 +207,7 @@ static int change_hardware(sr_session_ctx_t *session, uint32_t sub_id, const cha
|
||||
if (op == LYDX_OP_DELETE) {
|
||||
if (usb_authorize(confd->root, name, 0)) {
|
||||
rc = SR_ERR_INTERNAL;
|
||||
goto err_release_diff;
|
||||
goto err;;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -235,23 +224,18 @@ static int change_hardware(sr_session_ctx_t *session, uint32_t sub_id, const cha
|
||||
admin_state = lydx_get_cattr(state, "admin-state");
|
||||
if (usb_authorize(confd->root, name, !strcmp(admin_state, "unlocked"))) {
|
||||
rc = SR_ERR_INTERNAL;
|
||||
goto err_release_diff;
|
||||
goto err;;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err_release_diff:
|
||||
lyd_free_tree(diff);
|
||||
err_release_data:
|
||||
sr_release_data(cfg);
|
||||
err:
|
||||
return rc;
|
||||
}
|
||||
int ietf_hardware_init(struct confd *confd)
|
||||
int ietf_hardware_candidate_init(struct confd *confd)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
REGISTER_CHANGE(confd->session, "ietf-hardware", XPATH_BASE_, 0, change_hardware, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->cand, "ietf-hardware", XPATH_BASE_,
|
||||
SR_SUBSCR_UPDATE, hardware_cand, confd, &confd->sub);
|
||||
|
||||
|
||||
@@ -787,12 +787,9 @@ static sr_error_t ifchange_post(sr_session_ctx_t *session, struct dagger *net,
|
||||
return err ? SR_ERR_INTERNAL : SR_ERR_OK;
|
||||
}
|
||||
|
||||
static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
|
||||
int ietf_interfaces_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
struct lyd_node *diff, *cifs, *difs, *cif, *dif;
|
||||
struct confd *confd = _confd;
|
||||
sr_data_t *cfg;
|
||||
struct lyd_node *cifs, *difs, *cif, *dif;
|
||||
sr_error_t err;
|
||||
|
||||
switch (event) {
|
||||
@@ -814,19 +811,11 @@ static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *modu
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = sr_get_data(session, "//.", 0, 0, 0, &cfg);
|
||||
if (err || !cfg)
|
||||
goto err_abandon;
|
||||
|
||||
err = srx_get_diff(session, (struct lyd_node **)&diff);
|
||||
if (err)
|
||||
goto err_release_data;
|
||||
|
||||
cifs = lydx_get_descendant(cfg->tree, "interfaces", "interface", NULL);
|
||||
cifs = lydx_get_descendant(config, "interfaces", "interface", NULL);
|
||||
difs = lydx_get_descendant(diff, "interfaces", "interface", NULL);
|
||||
err = netdag_init(session, &confd->netdag, cifs, difs);
|
||||
if (err)
|
||||
goto err_free_diff;
|
||||
goto err_out;
|
||||
|
||||
LYX_LIST_FOR_EACH(difs, dif, "interface") {
|
||||
LYX_LIST_FOR_EACH(cifs, cif, "interface")
|
||||
@@ -840,71 +829,9 @@ static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *modu
|
||||
}
|
||||
|
||||
err = err ? : ifchange_post(session, &confd->netdag, cifs, difs);
|
||||
|
||||
err_free_diff:
|
||||
lyd_free_tree(diff);
|
||||
err_release_data:
|
||||
sr_release_data(cfg);
|
||||
err_abandon:
|
||||
if (err)
|
||||
dagger_abandon(&confd->netdag);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int keystorecb(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
|
||||
{
|
||||
const struct lyd_node *diff;
|
||||
const char *secret_name;
|
||||
struct confd *confd = _confd;
|
||||
struct lyd_node *interfaces, *interface, *dkeys, *dkey, *wifi;
|
||||
sr_data_t *cfg = NULL;
|
||||
int err = SR_ERR_OK;
|
||||
|
||||
switch (event) {
|
||||
case SR_EV_CHANGE:
|
||||
break;
|
||||
default:
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
err = sr_get_data(session, "/interfaces/interface", 0, 0, 0, &cfg);
|
||||
if (err || !cfg)
|
||||
return err;
|
||||
|
||||
diff = sr_get_change_diff(session);
|
||||
if (!diff)
|
||||
goto cleanup;
|
||||
|
||||
interfaces = lydx_get_descendant(cfg->tree, "interfaces", "interface", NULL);
|
||||
dkeys = lydx_get_descendant((struct lyd_node*) diff, "keystore", "symmetric-keys", "symmetric-key", NULL);
|
||||
|
||||
LYX_LIST_FOR_EACH(dkeys, dkey, "symmetric-key") {
|
||||
secret_name = lydx_get_cattr(dkey, "name");
|
||||
if (!secret_name)
|
||||
continue;
|
||||
|
||||
LYX_LIST_FOR_EACH(interfaces, interface, "interface") {
|
||||
const char *name;
|
||||
|
||||
if (iftype_from_iface(interface) != IFT_WIFI)
|
||||
continue;
|
||||
|
||||
wifi = lydx_get_child(interface, "wifi");
|
||||
if (!wifi)
|
||||
continue;
|
||||
|
||||
name = lydx_get_cattr(wifi, "secret");
|
||||
if (!name || strcmp(name, secret_name))
|
||||
continue;
|
||||
wifi_gen(NULL, interface, &confd->netdag);
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (cfg)
|
||||
sr_release_data(cfg);
|
||||
err_out:
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -974,18 +901,16 @@ int ietf_interfaces_get_all_l3(const struct lyd_node *tree, char ***ifaces)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ietf_interfaces_init(struct confd *confd)
|
||||
int ietf_interfaces_cand_init(struct confd *confd)
|
||||
{
|
||||
int rc;
|
||||
int rc = SR_ERR_OK;
|
||||
|
||||
REGISTER_CHANGE(confd->session, "ietf-interfaces", "/ietf-interfaces:interfaces//.",
|
||||
SR_SUBSCR_CHANGE_ALL_MODULES, ifchange, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->session, "ietf-keystore", "//*",
|
||||
SR_SUBSCR_CHANGE_ALL_MODULES, keystorecb, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->cand, "ietf-interfaces", "/ietf-interfaces:interfaces//.",
|
||||
SR_SUBSCR_UPDATE, ifchange_cand, confd, &confd->sub);
|
||||
return SR_ERR_OK;
|
||||
fail:
|
||||
ERROR("failed, error %d: %s", rc, sr_strerror(rc));
|
||||
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
@@ -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++;
|
||||
|
||||
+141
-87
@@ -51,106 +51,160 @@ static char *filerd(const char *fn, size_t len)
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int change_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *module_name,
|
||||
const char *xpath, sr_event_t event, uint32_t request_id, void *_)
|
||||
static int gen_hostkey(const char *name, struct lyd_node *change)
|
||||
{
|
||||
int rc = SR_ERR_INTERNAL;
|
||||
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;
|
||||
int rc;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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:
|
||||
/* Check SSH (and NETCONF) default hostkey pair */
|
||||
rc = keystore_update(session, config, diff);
|
||||
break;
|
||||
case SR_EV_CHANGE:
|
||||
case SR_EV_ENABLED:
|
||||
break;
|
||||
case SR_EV_ABORT:
|
||||
rmrf(SSH_HOSTKEYS_NEXT);
|
||||
return SR_ERR_OK;
|
||||
case SR_EV_DONE:
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
changes = lydx_get_descendant(config, "keystore", "asymmetric-keys", "asymmetric-key", NULL);
|
||||
LYX_LIST_FOR_EACH(changes, change, "asymmetric-key") {
|
||||
const char *name = lydx_get_cattr(change, "name");
|
||||
const char *type;
|
||||
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
gen_hostkey(name, change);
|
||||
}
|
||||
if (list)
|
||||
sr_free_values(list, count);
|
||||
|
||||
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
int ietf_keystore_init(struct confd *confd)
|
||||
{
|
||||
int rc;
|
||||
|
||||
REGISTER_CHANGE(confd->session, "ietf-keystore", "/ietf-keystore:keystore//.",
|
||||
SR_SUBSCR_UPDATE, change_cb, confd, &confd->sub);
|
||||
return SR_ERR_OK;
|
||||
fail:
|
||||
if(rc)
|
||||
ERROR("%s failed: %s", __func__, sr_strerror(rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -244,17 +244,18 @@ static int parse_static_routes(sr_session_ctx_t *session, struct lyd_node *paren
|
||||
return num_routes;
|
||||
}
|
||||
|
||||
static int change_control_plane_protocols(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
const char *xpath, sr_event_t event, unsigned request_id, void *priv)
|
||||
int ietf_routing_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
int staticd_enabled = 0, ospfd_enabled = 0, bfdd_enabled = 0;
|
||||
struct lyd_node *cplane, *cplanes;
|
||||
bool ospfd_running, bfdd_running;
|
||||
struct lyd_node *cplane, *tmp;
|
||||
bool restart_zebra = false;
|
||||
int rc = SR_ERR_OK;
|
||||
sr_data_t *cfg;
|
||||
FILE *fp;
|
||||
|
||||
if (diff && !lydx_get_xpathf(diff, "/ietf-routing:routing"))
|
||||
return SR_ERR_OK;
|
||||
|
||||
switch (event) {
|
||||
case SR_EV_ENABLED: /* first time, on register. */
|
||||
case SR_EV_CHANGE: /* regular change (copy cand running) */
|
||||
@@ -351,27 +352,18 @@ static int change_control_plane_protocols(sr_session_ctx_t *session, uint32_t su
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
rc = sr_get_data(session, "/ietf-routing:routing/control-plane-protocols//.", 0, 0, 0, &cfg);
|
||||
if (rc || !cfg) {
|
||||
NOTE("No control-plane-protocols available.");
|
||||
goto err_close;
|
||||
}
|
||||
cplanes = lydx_get_descendant(config, "routing", "control-plane-protocols", "control-plane-protocol", NULL);
|
||||
LYX_LIST_FOR_EACH(cplanes, cplane, "control-plane-protocol") {
|
||||
const char *type;
|
||||
|
||||
LY_LIST_FOR(lyd_child(cfg->tree), tmp) {
|
||||
LY_LIST_FOR(lyd_child(tmp), cplane) {
|
||||
const char *type;
|
||||
|
||||
type = lydx_get_cattr(cplane, "type");
|
||||
if (!strcmp(type, "infix-routing:static")) {
|
||||
staticd_enabled = parse_static_routes(session, lydx_get_child(cplane, "static-routes"), fp);
|
||||
} else if (!strcmp(type, "infix-routing:ospfv2")) {
|
||||
parse_ospf(session, lydx_get_child(cplane, "ospf"));
|
||||
}
|
||||
type = lydx_get_cattr(cplane, "type");
|
||||
if (!strcmp(type, "infix-routing:static")) {
|
||||
staticd_enabled = parse_static_routes(session, lydx_get_child(cplane, "static-routes"), fp);
|
||||
} else if (!strcmp(type, "infix-routing:ospfv2")) {
|
||||
parse_ospf(session, lydx_get_child(cplane, "ospf"));
|
||||
}
|
||||
}
|
||||
sr_release_data(cfg);
|
||||
|
||||
err_close:
|
||||
fclose(fp);
|
||||
if (!staticd_enabled)
|
||||
(void)remove(STATICD_CONF_NEXT);
|
||||
@@ -379,16 +371,3 @@ err_close:
|
||||
err_abandon:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int ietf_routing_init(struct confd *confd)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
REGISTER_CHANGE(confd->session, "ietf-routing", "/ietf-routing:routing/control-plane-protocols",
|
||||
0, change_control_plane_protocols, confd, &confd->sub);
|
||||
|
||||
return SR_ERR_OK;
|
||||
fail:
|
||||
ERROR("Init routing failed: %s", sr_strerror(rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
+29
-41
@@ -218,13 +218,12 @@ static const char *getnm(struct lyd_node *node, char *xpath, size_t len)
|
||||
return name;
|
||||
}
|
||||
|
||||
static int file_change(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 file_change(sr_session_ctx_t *session, struct lyd_node *config,struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
struct lyd_node *files, *file, *tree;
|
||||
int err;
|
||||
|
||||
if (SR_EV_DONE != event)
|
||||
if (SR_EV_DONE != event || !lydx_get_xpathf(diff, XPATH_FILE_))
|
||||
return SR_ERR_OK;
|
||||
|
||||
err = srx_get_diff(session, &tree);
|
||||
@@ -253,21 +252,15 @@ static int file_change(sr_session_ctx_t *session, uint32_t sub_id, const char *m
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
static int remote_change(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 remote_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
struct lyd_node *remotes, *remote, *tree;
|
||||
int err;
|
||||
struct lyd_node *dremotes, *remote;
|
||||
|
||||
if (SR_EV_DONE != event)
|
||||
if (SR_EV_DONE != event || !lydx_get_xpathf(diff, XPATH_REMOTE_))
|
||||
return SR_ERR_OK;
|
||||
|
||||
err = srx_get_diff(session, &tree);
|
||||
if (err)
|
||||
return SR_ERR_OK;
|
||||
|
||||
remotes = lydx_get_descendant(tree, "syslog", "actions", "remote", "destination", NULL);
|
||||
LYX_LIST_FOR_EACH(remotes, remote, "destination") {
|
||||
dremotes = lydx_get_descendant(diff, "syslog", "actions", "remote", "destination", NULL);
|
||||
LYX_LIST_FOR_EACH(dremotes, remote, "destination") {
|
||||
struct lyd_node *node = lydx_get_child(remote, "name");
|
||||
enum lydx_op op = lydx_get_op(node);
|
||||
char path[512] = XPATH_REMOTE_;
|
||||
@@ -283,23 +276,22 @@ static int remote_change(sr_session_ctx_t *session, uint32_t sub_id, const char
|
||||
addr.address = srx_get_str(session, "%s/udp/address", path);
|
||||
srx_get_int(session, &addr.port, SR_UINT16_T, "%s/udp/port", path);
|
||||
|
||||
action(session, name, xpath, &addr);
|
||||
action(session, name, path, &addr);
|
||||
}
|
||||
}
|
||||
|
||||
srx_free_changes(tree);
|
||||
systemf("initctl -nbq touch sysklogd");
|
||||
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
static int rotate_change(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 rotate_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
char path[512] = XPATH_ROTATE_;
|
||||
char *sz, *cnt;
|
||||
FILE *fp;
|
||||
|
||||
if (SR_EV_DONE != event)
|
||||
if (SR_EV_DONE != event || !lydx_get_xpathf(diff, XPATH_ROTATE_))
|
||||
return SR_ERR_OK;
|
||||
|
||||
fp = fopen(SYSLOG_ROTATE, "w");
|
||||
@@ -308,13 +300,13 @@ static int rotate_change(sr_session_ctx_t *session, uint32_t sub_id, const char
|
||||
return SR_ERR_SYS;
|
||||
}
|
||||
|
||||
sz = srx_get_str(session, "%s/max-file-size", xpath);
|
||||
sz = srx_get_str(session, "%s/max-file-size", path);
|
||||
if (sz) {
|
||||
fprintf(fp, "rotate_size %sk\n", sz);
|
||||
free(sz);
|
||||
}
|
||||
|
||||
cnt = srx_get_str(session, "%s/number-of-files", xpath);
|
||||
cnt = srx_get_str(session, "%s/number-of-files", path);
|
||||
if (cnt) {
|
||||
fprintf(fp, "rotate_count %s\n", cnt);
|
||||
free(cnt);
|
||||
@@ -326,18 +318,18 @@ static int rotate_change(sr_session_ctx_t *session, uint32_t sub_id, const char
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
static int server_change(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 server_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
char path[512] = XPATH_SERVER_;
|
||||
sr_val_t *list = NULL;
|
||||
size_t count;
|
||||
FILE *fp;
|
||||
|
||||
if (SR_EV_DONE != event)
|
||||
if (SR_EV_DONE != event || !lydx_get_xpathf(diff, XPATH_SERVER_))
|
||||
return SR_ERR_OK;
|
||||
|
||||
if (!srx_enabled(session, "%s/enabled", xpath)) {
|
||||
if (remove(SYSLOG_SERVER))
|
||||
if (!srx_enabled(session, "%s/enabled", path)) {
|
||||
if (erase(SYSLOG_SERVER))
|
||||
ERRNO("failed disabling syslog server");
|
||||
goto done;
|
||||
}
|
||||
@@ -351,7 +343,7 @@ static int server_change(sr_session_ctx_t *session, uint32_t sub_id, const char
|
||||
/* Allow listening on port 514, or custom listen below */
|
||||
fprintf(fp, "secure_mode 0\n");
|
||||
|
||||
if (!srx_get_items(session, &list, &count, "%s/listen/udp", xpath)) {
|
||||
if (!srx_get_items(session, &list, &count, "%s/listen/udp", path)) {
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
sr_val_t *entry = &list[i];
|
||||
char *address, *port;
|
||||
@@ -373,21 +365,17 @@ done:
|
||||
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
int ietf_syslog_init(struct confd *confd)
|
||||
int ietf_syslog_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
int rc = SR_ERR_SYS;
|
||||
|
||||
if (!confd)
|
||||
goto fail;
|
||||
|
||||
REGISTER_CHANGE(confd->session, "ietf-syslog", XPATH_FILE_"//.", 0, file_change, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->session, "ietf-syslog", XPATH_REMOTE_"//.", 0, remote_change, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->session, "ietf-syslog", XPATH_ROTATE_"//.", 0, rotate_change, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->session, "ietf-syslog", XPATH_SERVER_"//.", 0, server_change, confd, &confd->sub);
|
||||
int rc = SR_ERR_OK;
|
||||
if ((rc = file_change(session, config, diff, event, confd)))
|
||||
return rc;
|
||||
if ((rc = remote_change(session, config, diff, event, confd)))
|
||||
return rc;
|
||||
if ((rc = rotate_change(session, config, diff, event, confd)))
|
||||
return rc;
|
||||
if ((rc = server_change(session, config, diff, event, confd)))
|
||||
return rc;
|
||||
|
||||
return SR_ERR_OK;
|
||||
fail:
|
||||
ERROR("%s failed: %s", __func__, sr_strerror(rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
+73
-55
@@ -21,12 +21,18 @@
|
||||
#include "base64.h"
|
||||
#include "core.h"
|
||||
|
||||
#define NACM_BASE_ "/ietf-netconf-acm:nacm"
|
||||
#define XPATH_BASE_ "/ietf-system:system"
|
||||
#define XPATH_AUTH_ XPATH_BASE_"/authentication"
|
||||
#define CLOCK_PATH_ "/ietf-system:system-state/clock"
|
||||
#define PLATFORM_PATH_ "/ietf-system:system-state/platform"
|
||||
#define PASSWORD_PATH "/ietf-system:system/authentication/user/password"
|
||||
#define NACM_BASE_ "/ietf-netconf-acm:nacm"
|
||||
#define XPATH_BASE_ "/ietf-system:system"
|
||||
#define XPATH_AUTH_ XPATH_BASE_"/authentication"
|
||||
#define XPATH_NTP_ XPATH_BASE_"/ntp"
|
||||
#define XPATH_DNS_ XPATH_BASE_"/dns-resolver"
|
||||
#define XPATH_HOSTNAME_ XPATH_BASE_"/hostname"
|
||||
#define XPATH_MOTD_BANNER_ XPATH_BASE_"/infix-system:motd-banner"
|
||||
#define XPATH_MOTD_ XPATH_BASE_"/infix-system:motd"
|
||||
#define XPATH_EDITOR_ XPATH_BASE_"/infix-system:text-editor"
|
||||
#define CLOCK_PATH_ "/ietf-system:system-state/clock"
|
||||
#define PLATFORM_PATH_ "/ietf-system:system-state/platform"
|
||||
#define PASSWORD_PATH "/ietf-system:system/authentication/user/password"
|
||||
|
||||
#define _PATH_PASSWD "/etc/passwd"
|
||||
#define _PATH_HOSTNAME "/etc/hostname"
|
||||
@@ -210,12 +216,13 @@ static int sys_reload_services(void)
|
||||
#define TIMEZONE_PREV TIMEZONE_CONF "-"
|
||||
#define TIMEZONE_NEXT TIMEZONE_CONF "+"
|
||||
|
||||
static int change_clock(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 change_clock(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
char *tz_utc_offset, *timezone;
|
||||
int rc = SR_ERR_OK;
|
||||
|
||||
if (diff && !lydx_get_xpathf(diff, XPATH_BASE_"/clock"))
|
||||
return SR_ERR_OK;
|
||||
switch (event) {
|
||||
case SR_EV_ENABLED: /* first time, on register. */
|
||||
case SR_EV_CHANGE: /* regular change (copy cand running) */
|
||||
@@ -280,8 +287,7 @@ err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int change_ntp(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
const char *_, sr_event_t event, unsigned request_id, void *priv)
|
||||
static int change_ntp(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
sr_change_iter_t *iter = NULL;
|
||||
int rc, err = SR_ERR_OK;
|
||||
@@ -289,6 +295,8 @@ static int change_ntp(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
|
||||
sr_val_t *val;
|
||||
size_t cnt;
|
||||
|
||||
if (diff && !lydx_get_xpathf(diff, XPATH_NTP_))
|
||||
return SR_ERR_OK;
|
||||
switch (event) {
|
||||
case SR_EV_ENABLED: /* first time, on register. */
|
||||
case SR_EV_CHANGE: /* regular change (copy cand running) */
|
||||
@@ -299,7 +307,7 @@ static int change_ntp(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
|
||||
return SR_ERR_OK;
|
||||
|
||||
case SR_EV_DONE:
|
||||
if (!srx_enabled(session, XPATH_BASE_"/ntp/enabled")) {
|
||||
if (!srx_enabled(session, XPATH_NTP_"/enabled")) {
|
||||
systemf("rm -rf /etc/chrony/conf.d/* /etc/chrony/sources.d/*");
|
||||
systemf("initctl -nbq disable chronyd");
|
||||
return SR_ERR_OK;
|
||||
@@ -411,8 +419,7 @@ static int change_ntp(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
|
||||
#define RESOLV_PREV RESOLV_CONF "-"
|
||||
#define RESOLV_NEXT RESOLV_CONF "+"
|
||||
|
||||
static int change_dns(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 change_dns(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
const char *fn = RESOLV_NEXT;
|
||||
int timeout = 0, attempts = 0;
|
||||
@@ -421,6 +428,9 @@ static int change_dns(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
|
||||
size_t cnt;
|
||||
FILE *fp;
|
||||
|
||||
if (diff && !lydx_get_xpathf(diff, XPATH_DNS_))
|
||||
return SR_ERR_OK;
|
||||
|
||||
switch (event) {
|
||||
case SR_EV_ENABLED: /* first time, on register. */
|
||||
case SR_EV_CHANGE: /* regular change (copy cand running) */
|
||||
@@ -453,8 +463,8 @@ static int change_dns(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
|
||||
return SR_ERR_SYS;
|
||||
}
|
||||
|
||||
SRX_GET_UINT8(session, timeout, XPATH_BASE_"/dns-resolver/options/timeout");
|
||||
SRX_GET_UINT8(session, attempts, XPATH_BASE_"/dns-resolver/options/attempts");
|
||||
SRX_GET_UINT8(session, timeout, XPATH_DNS_"/options/timeout");
|
||||
SRX_GET_UINT8(session, attempts, XPATH_DNS_"/dns-resolver/options/attempts");
|
||||
if (timeout || attempts) {
|
||||
fprintf(fp, "options");
|
||||
if (timeout)
|
||||
@@ -1288,11 +1298,10 @@ cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int change_auth(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 change_auth(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
struct confd *confd = (struct confd *)priv;
|
||||
|
||||
if (diff && !lydx_get_xpathf(diff, XPATH_AUTH_))
|
||||
return SR_ERR_OK;
|
||||
switch (event) {
|
||||
case SR_EV_UPDATE:
|
||||
return change_auth_ctp(confd, session);
|
||||
@@ -1307,14 +1316,13 @@ static int change_auth(sr_session_ctx_t *session, uint32_t sub_id, const char *m
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
static int change_nacm(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
const char *_, sr_event_t event, unsigned request_id, void *priv)
|
||||
static int change_nacm(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
sr_val_t *users = NULL;
|
||||
size_t user_count = 0;
|
||||
int rc;
|
||||
|
||||
if (event != SR_EV_DONE)
|
||||
if (event != SR_EV_DONE ||!lydx_get_xpathf(diff, NACM_BASE_))
|
||||
return SR_ERR_OK;
|
||||
|
||||
/* Fetch all users from ietf-system */
|
||||
@@ -1346,18 +1354,18 @@ cleanup:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int change_motd(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 change_motd(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
const char *fn = "/etc/motd";
|
||||
char *message;
|
||||
int rc = 0;
|
||||
|
||||
|
||||
/* Ignore all events except SR_EV_DONE */
|
||||
if (event != SR_EV_DONE)
|
||||
if (event != SR_EV_DONE || !lydx_get_xpathf(diff, XPATH_MOTD_))
|
||||
return SR_ERR_OK;
|
||||
|
||||
message = srx_get_str(session, "%s", xpath);
|
||||
message = srx_get_str(session, "%s", XPATH_MOTD_);
|
||||
if (message) {
|
||||
rc = writesf(message, "w", "%s", fn);
|
||||
free(message);
|
||||
@@ -1371,8 +1379,7 @@ static int change_motd(sr_session_ctx_t *session, uint32_t sub_id, const char *m
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
static int change_motd_banner(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 change_motd_banner(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
const char *fn = "/etc/motd";
|
||||
unsigned char *raw;
|
||||
@@ -1380,24 +1387,24 @@ static int change_motd_banner(sr_session_ctx_t *session, uint32_t sub_id, const
|
||||
int rc = 0;
|
||||
|
||||
/* Ignore all events except SR_EV_DONE */
|
||||
if (event != SR_EV_DONE)
|
||||
if (event != SR_EV_DONE || !lydx_get_xpathf(diff, XPATH_MOTD_BANNER_))
|
||||
return SR_ERR_OK;
|
||||
|
||||
legacy = srx_get_str(session, "/ietf-system:system/infix-system:motd");
|
||||
legacy = srx_get_str(session, XPATH_MOTD_);
|
||||
if (legacy) {
|
||||
NOTE("Legacy /system/motd exists, skipping %s", xpath);
|
||||
NOTE("Legacy /system/motd exists, skipping %s", XPATH_MOTD_BANNER_);
|
||||
free(legacy);
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
raw = (unsigned char *)srx_get_str(session, "%s", xpath);
|
||||
raw = (unsigned char *)srx_get_str(session, "%s", XPATH_BASE_"/infix-system:motd-banner");
|
||||
if (raw) {
|
||||
unsigned char *txt;
|
||||
size_t txt_len;
|
||||
|
||||
txt = base64_decode(raw, strlen((char *)raw), &txt_len);
|
||||
if (!txt) {
|
||||
ERRNO("failed base64 decoding of %s", xpath);
|
||||
ERRNO("failed base64 decoding of %s", XPATH_BASE_"/infix-system:motd-banner");
|
||||
rc = -1;
|
||||
} else {
|
||||
FILE *fp = fopen(fn, "w");
|
||||
@@ -1431,8 +1438,7 @@ static int change_motd_banner(sr_session_ctx_t *session, uint32_t sub_id, const
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
static int change_editor(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 change_editor(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
const char *alt = "/etc/alternatives/editor";
|
||||
struct { const char *editor, *path; } map[] = {
|
||||
@@ -1444,10 +1450,10 @@ static int change_editor(sr_session_ctx_t *session, uint32_t sub_id, const char
|
||||
int rc = 0;
|
||||
|
||||
/* Ignore all events except SR_EV_DONE */
|
||||
if (event != SR_EV_DONE)
|
||||
if (event != SR_EV_DONE || !lydx_get_xpathf(diff, XPATH_EDITOR_))
|
||||
return SR_ERR_OK;
|
||||
|
||||
editor = srx_get_str(session, "%s", xpath);
|
||||
editor = srx_get_str(session, "%s", XPATH_BASE_"/infix-system:text-editor");
|
||||
if (!editor)
|
||||
return SR_ERR_OK;
|
||||
|
||||
@@ -1550,20 +1556,18 @@ int hostnamefmt(struct confd *confd, const char *fmt, char *hostnm, size_t hostl
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int change_hostname(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 change_hostname(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
struct confd *confd = (struct confd *)priv;
|
||||
const char *hostip = "127.0.1.1";
|
||||
char hostnm[65], domain[65];
|
||||
char buf[256], *fmt;
|
||||
FILE *nfp, *fp;
|
||||
int err, fd;
|
||||
|
||||
if (event != SR_EV_DONE)
|
||||
if (event != SR_EV_DONE || !lydx_get_xpathf(diff, XPATH_HOSTNAME_))
|
||||
return SR_ERR_OK;
|
||||
|
||||
fmt = srx_get_str(session, "%s", xpath);
|
||||
fmt = srx_get_str(session, "%s", XPATH_BASE_"/hostname");
|
||||
if (!fmt)
|
||||
fmt = strdup(nm);
|
||||
|
||||
@@ -1648,24 +1652,38 @@ err:
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
int ietf_system_init(struct confd *confd)
|
||||
|
||||
int ietf_system_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
int rc = SR_ERR_OK;
|
||||
if ((rc = change_auth(session, config, diff, event, confd)))
|
||||
return rc;
|
||||
if ((rc = change_ntp(session, config, diff, event, confd)))
|
||||
return rc;
|
||||
if ((rc = change_dns(session, config, diff, event, confd)))
|
||||
return rc;
|
||||
if ((rc = change_editor(session,config, diff, event, confd)))
|
||||
return rc;
|
||||
if ((rc = change_clock(session, config, diff, event, confd)))
|
||||
return rc;
|
||||
if ((rc = change_hostname(session, config, diff, event, confd)))
|
||||
return rc;
|
||||
if ((rc = change_motd(session, config, diff, event, confd)))
|
||||
return rc;
|
||||
if ((rc = change_motd_banner(session, config, diff, event, confd)))
|
||||
return rc;
|
||||
if ((rc = change_nacm(session, config, diff, event, confd))) /* Must be called after ietf_system_change_auth, which create the users */
|
||||
return rc;
|
||||
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
int ietf_system_rpc_init(struct confd *confd)
|
||||
{
|
||||
int rc;
|
||||
|
||||
os_init();
|
||||
|
||||
REGISTER_CHANGE(confd->session, "ietf-system", XPATH_AUTH_, 0, change_auth, confd, &confd->sub);
|
||||
REGISTER_MONITOR(confd->session, "ietf-netconf-acm", "/ietf-netconf-acm:nacm//.",
|
||||
0, change_nacm, confd, &confd->sub);
|
||||
|
||||
REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/hostname", 0, change_hostname, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/infix-system:motd", 0, change_motd, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/infix-system:motd-banner", 0, change_motd_banner, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/infix-system:text-editor", 0, change_editor, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/clock", 0, change_clock, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/ntp", 0, change_ntp, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->session, "ietf-system", XPATH_BASE_"/dns-resolver", 0, change_dns, confd, &confd->sub);
|
||||
|
||||
REGISTER_RPC(confd->session, "/ietf-system:system-restart", rpc_exec, "reboot", &confd->sub);
|
||||
REGISTER_RPC(confd->session, "/ietf-system:system-shutdown", rpc_exec, "poweroff", &confd->sub);
|
||||
REGISTER_RPC(confd->session, "/ietf-system:set-current-datetime", rpc_set_datetime, NULL, &confd->sub);
|
||||
|
||||
@@ -349,23 +349,20 @@ static int del(const char *name)
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
|
||||
int infix_containers_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
struct lyd_node *diff, *cifs, *difs, *cif, *dif;
|
||||
struct lyd_node *cifs, *difs, *cif, *dif;
|
||||
sr_error_t err = 0;
|
||||
sr_data_t *cfg;
|
||||
|
||||
if (diff && !lydx_get_xpathf(diff, CFG_XPATH))
|
||||
return SR_ERR_OK;
|
||||
|
||||
switch (event) {
|
||||
case SR_EV_DONE:
|
||||
break;
|
||||
|
||||
case SR_EV_CHANGE:
|
||||
err = sr_get_data(session, CFG_XPATH "//.", 0, 0, 0, &cfg);
|
||||
if (err || !cfg)
|
||||
return SR_ERR_INTERNAL;
|
||||
|
||||
cifs = lydx_get_descendant(cfg->tree, "containers", "container", NULL);
|
||||
cifs = lydx_get_descendant(config, "containers", "container", NULL);
|
||||
LYX_LIST_FOR_EACH(cifs, cif, "container") {
|
||||
struct lyd_node *mount;
|
||||
LYX_LIST_FOR_EACH(lyd_child(cif), mount, "mount") {
|
||||
@@ -379,13 +376,10 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
|
||||
"Container '%s': mount '%s' source file '%s' is invalid: %s",
|
||||
lydx_get_cattr(cif, "name"), id, src, reason);
|
||||
sr_session_set_error_message(session, errmsg);
|
||||
sr_release_data(cfg);
|
||||
return SR_ERR_VALIDATION_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sr_release_data(cfg);
|
||||
return SR_ERR_OK;
|
||||
|
||||
case SR_EV_ABORT:
|
||||
@@ -393,15 +387,7 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
err = sr_get_data(session, CFG_XPATH "//.", 0, 0, 0, &cfg);
|
||||
if (err || !cfg)
|
||||
goto err_abandon;
|
||||
|
||||
err = srx_get_diff(session, &diff);
|
||||
if (err)
|
||||
goto err_release_data;
|
||||
|
||||
cifs = lydx_get_descendant(cfg->tree, "containers", "container", NULL);
|
||||
cifs = lydx_get_descendant(config, "containers", "container", NULL);
|
||||
difs = lydx_get_descendant(diff, "containers", "container", NULL);
|
||||
|
||||
/* find the modified one, delete or recreate only that */
|
||||
@@ -422,11 +408,6 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
|
||||
}
|
||||
}
|
||||
|
||||
lyd_free_tree(diff);
|
||||
err_release_data:
|
||||
sr_release_data(cfg);
|
||||
err_abandon:
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -484,11 +465,10 @@ static int oci_load(sr_session_ctx_t *session, uint32_t sub_id, const char *xpat
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
int infix_containers_init(struct confd *confd)
|
||||
int infix_containers_rpc_init(struct confd *confd)
|
||||
{
|
||||
int rc;
|
||||
|
||||
REGISTER_CHANGE(confd->session, MODULE, CFG_XPATH, 0, change, confd, &confd->sub);
|
||||
REGISTER_RPC(confd->session, CFG_XPATH "/container/start", action, NULL, &confd->sub);
|
||||
REGISTER_RPC(confd->session, CFG_XPATH "/container/stop", action, NULL, &confd->sub);
|
||||
REGISTER_RPC(confd->session, CFG_XPATH "/container/restart", action, NULL, &confd->sub);
|
||||
|
||||
@@ -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,72 +278,61 @@ static void del(const char *ifname)
|
||||
systemf("initctl -bfq delete dhcp-client-%s", ifname);
|
||||
}
|
||||
|
||||
static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
const char *xpath, sr_event_t event, unsigned request_id, void *_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, *diff, *cifs, *difs, *cif, *dif;
|
||||
struct lyd_node *ifaces, *difaces, *iface, *diface, *ipv4, *dhcp, *ddhcp;
|
||||
sr_error_t err = 0;
|
||||
sr_data_t *cfg;
|
||||
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;
|
||||
}
|
||||
|
||||
err = sr_get_data(session, "//.", 0, 0, 0, &cfg);
|
||||
if (err || !cfg)
|
||||
goto err_abandon;
|
||||
ifaces = lydx_get_descendant(config, "interfaces", "interface", NULL);
|
||||
difaces = lydx_get_descendant(diff, "interfaces", "interface", NULL);
|
||||
|
||||
err = srx_get_diff(session, &diff);
|
||||
if (err)
|
||||
goto err_release_data;
|
||||
/* 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;
|
||||
|
||||
global = lydx_get_descendant(cfg->tree, "dhcp-client", NULL);
|
||||
ena = lydx_is_enabled(global, "enabled");
|
||||
lyd_print_mem(&out, diface, LYD_JSON,
|
||||
LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL);
|
||||
|
||||
cifs = lydx_get_descendant(cfg->tree, "dhcp-client", "client-if", NULL);
|
||||
difs = lydx_get_descendant(diff, "dhcp-client", "client-if", NULL);
|
||||
dipv4 = lydx_get_descendant(lyd_child(diface), "ipv4", NULL);
|
||||
if (!dipv4)
|
||||
continue;
|
||||
|
||||
/* 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");
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
lyd_free_tree(diff);
|
||||
err_release_data:
|
||||
sr_release_data(cfg);
|
||||
err_abandon:
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -383,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;
|
||||
|
||||
@@ -421,11 +410,10 @@ static int cand(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
int infix_dhcp_client_init(struct confd *confd)
|
||||
int infix_dhcp_client_candidate_init(struct confd *confd)
|
||||
{
|
||||
int rc;
|
||||
|
||||
REGISTER_CHANGE(confd->session, MODULE, XPATH, 0, change, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->cand, MODULE, XPATH"//.", SR_SUBSCR_UPDATE, cand, confd, &confd->sub);
|
||||
|
||||
return SR_ERR_OK;
|
||||
|
||||
@@ -294,13 +294,11 @@ static void del(const char *subnet, struct lyd_node *cfg)
|
||||
ERRNO("Failed switching to new %s", DNSMASQ_LEASES);
|
||||
}
|
||||
|
||||
static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
|
||||
int infix_dhcp_server_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, *diff, *cifs, *difs, *cif, *dif;
|
||||
struct lyd_node *global, *cifs, *difs, *cif, *dif;
|
||||
int enabled = 0, added = 0, deleted = 0;
|
||||
sr_error_t err = 0;
|
||||
sr_data_t *cfg;
|
||||
|
||||
switch (event) {
|
||||
case SR_EV_DONE:
|
||||
@@ -311,18 +309,13 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
err = sr_get_data(session, "//.", 0, 0, 0, &cfg);
|
||||
if (err || !cfg)
|
||||
goto err_abandon;
|
||||
if (!lydx_get_xpathf(diff, CFG_XPATH))
|
||||
return SR_ERR_OK;
|
||||
|
||||
err = srx_get_diff(session, &diff);
|
||||
if (err)
|
||||
goto err_release_data;
|
||||
|
||||
global = lydx_get_descendant(cfg->tree, "dhcp-server", NULL);
|
||||
global = lydx_get_descendant(config, "dhcp-server", NULL);
|
||||
enabled = lydx_is_enabled(global, "enabled");
|
||||
|
||||
cifs = lydx_get_descendant(cfg->tree, "dhcp-server", "subnet", NULL);
|
||||
cifs = lydx_get_descendant(config, "dhcp-server", "subnet", NULL);
|
||||
difs = lydx_get_descendant(diff, "dhcp-server", "subnet", NULL);
|
||||
|
||||
/* find the modified one, delete or recreate only that */
|
||||
@@ -356,7 +349,7 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
|
||||
if (!fp)
|
||||
goto err_done;
|
||||
|
||||
node = lydx_get_xpathf(cfg->tree, "/ietf-system:system/hostname");
|
||||
node = lydx_get_xpathf(config, "/ietf-system:system/hostname");
|
||||
if (node) {
|
||||
const char *hostname = lyd_get_value(node);
|
||||
const char *ptr = hostname ? strchr(hostname, '.') : NULL;
|
||||
@@ -385,11 +378,6 @@ err_done:
|
||||
if (added || deleted)
|
||||
system("initctl -nbq touch dnsmasq");
|
||||
|
||||
lyd_free_tree(diff);
|
||||
err_release_data:
|
||||
sr_release_data(cfg);
|
||||
err_abandon:
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -461,12 +449,22 @@ static int clear_stats(sr_session_ctx_t *session, uint32_t sub_id, const char *x
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
int infix_dhcp_server_init(struct confd *confd)
|
||||
int infix_dhcp_server_candidate_init(struct confd *confd)
|
||||
{
|
||||
int rc;
|
||||
|
||||
REGISTER_CHANGE(confd->session, MODULE, CFG_XPATH, 0, change, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->cand, MODULE, CFG_XPATH "//.", SR_SUBSCR_UPDATE, cand, confd, &confd->sub);
|
||||
|
||||
return SR_ERR_OK;
|
||||
fail:
|
||||
ERROR("init failed: %s", sr_strerror(rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
int infix_dhcp_server_rpc_init(struct confd *confd)
|
||||
{
|
||||
int rc;
|
||||
|
||||
REGISTER_RPC(confd->session, CFG_XPATH "/statistics/clear", clear_stats, NULL, &confd->sub);
|
||||
|
||||
return SR_ERR_OK;
|
||||
|
||||
@@ -33,7 +33,7 @@ static int rpc(sr_session_ctx_t *session, uint32_t sub_id, const char *xpath,
|
||||
return rc;
|
||||
}
|
||||
|
||||
int infix_factory_init(struct confd *confd)
|
||||
int infix_factory_rpc_init(struct confd *confd)
|
||||
{
|
||||
int rc;
|
||||
REGISTER_RPC(confd->session, "/infix-factory-default:factory-default", rpc, NULL, &confd->fsub);
|
||||
|
||||
@@ -68,6 +68,9 @@ static void mark_interfaces_used(struct lyd_node *cfg, char **ifaces)
|
||||
{
|
||||
struct lyd_node *node;
|
||||
|
||||
if (!ifaces)
|
||||
return;
|
||||
|
||||
LYX_LIST_FOR_EACH(lyd_child(cfg), node, "interface") {
|
||||
const char *ifname = lyd_get_value(node);
|
||||
|
||||
@@ -477,16 +480,16 @@ static int infer_policy(sr_session_ctx_t *session, const char *name, const char
|
||||
}
|
||||
#endif
|
||||
|
||||
static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
|
||||
int infix_firewall_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
struct lyd_node *tree, *global;
|
||||
struct lyd_node *clist, *cnode;
|
||||
struct lyd_node *diff = NULL;
|
||||
sr_error_t err = SR_ERR_OK;
|
||||
sr_data_t *cfg = NULL;
|
||||
char **ifaces = NULL;
|
||||
|
||||
if (diff && !lydx_get_xpathf(diff, XPATH))
|
||||
return SR_ERR_OK;
|
||||
|
||||
switch (event) {
|
||||
case SR_EV_CHANGE:
|
||||
/* Generate configuration to /etc/firewalld+ */
|
||||
@@ -518,11 +521,7 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
err = sr_get_data(session, "//.", 0, 0, 0, &cfg);
|
||||
if (err || !cfg)
|
||||
return SR_ERR_INTERNAL;
|
||||
|
||||
tree = cfg->tree;
|
||||
tree = config;
|
||||
global = lydx_get_descendant(tree, "firewall", NULL);
|
||||
|
||||
/* Clean up any stale /etc/firewalld+ first */
|
||||
@@ -540,13 +539,6 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
|
||||
ifaces = NULL;
|
||||
}
|
||||
|
||||
err = srx_get_diff(session, &diff);
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
if (!diff)
|
||||
goto done;
|
||||
|
||||
/* Create /etc/firewalld+ directory structure */
|
||||
if (fmkpath(0755, FIREWALLD_DIR_NEXT) ||
|
||||
fmkpath(0755, FIREWALLD_ZONES_DIR) ||
|
||||
@@ -642,12 +634,6 @@ done:
|
||||
free(ifaces);
|
||||
}
|
||||
|
||||
if (diff)
|
||||
lyd_free_tree(diff);
|
||||
|
||||
if (cfg)
|
||||
sr_release_data(cfg);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -699,7 +685,7 @@ static int cand(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
|
||||
#if INFER_POLICY
|
||||
/* Infer allow-host-ipv6 policy */
|
||||
rc = infer_policy(session, "allow-host-ipv6",
|
||||
rc = infer_policy(session, "allow-host-ipv6",
|
||||
"Allows basic IPv6 functionality for the host.",
|
||||
"continue", any, host, icmp_types);
|
||||
if (rc)
|
||||
@@ -725,12 +711,10 @@ static int lockdown(sr_session_ctx_t *session, uint32_t sub_id, const char *xpat
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
int infix_firewall_init(struct confd *confd)
|
||||
int infix_firewall_rpc_init(struct confd *confd)
|
||||
{
|
||||
int rc;
|
||||
|
||||
REGISTER_CHANGE(confd->session, MODULE, XPATH "//.", 0, change, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->cand, MODULE, XPATH "//.", SR_SUBSCR_UPDATE, cand, confd, &confd->sub);
|
||||
REGISTER_RPC(confd->session, XPATH "/lockdown-mode", lockdown, NULL, &confd->sub);
|
||||
|
||||
return SR_ERR_OK;
|
||||
@@ -738,3 +722,16 @@ fail:
|
||||
ERROR("init failed: %s", sr_strerror(rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int infix_firewall_candidate_init(struct confd *confd)
|
||||
{
|
||||
int rc;
|
||||
|
||||
REGISTER_CHANGE(confd->cand, MODULE, XPATH "//.", SR_SUBSCR_UPDATE, cand, confd, &confd->sub);
|
||||
|
||||
return SR_ERR_OK;
|
||||
fail:
|
||||
ERROR("init failed: %s", sr_strerror(rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -18,23 +18,10 @@ static int set_version(sr_session_ctx_t *session)
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
static int change_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
const char *xpath, sr_event_t event, unsigned request_id, void *priv)
|
||||
int infix_meta_change_cb(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
if (event == SR_EV_UPDATE)
|
||||
return set_version(session);
|
||||
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
int infix_meta_init(struct confd *confd)
|
||||
{
|
||||
int rc;
|
||||
|
||||
REGISTER_CHANGE(confd->session, "infix-meta", META_XPATH, SR_SUBSCR_UPDATE,
|
||||
change_cb, confd, &confd->sub);
|
||||
return SR_ERR_OK;
|
||||
fail:
|
||||
ERROR("%s(): failed. %s", __func__, sr_strerror(rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
+71
-142
@@ -19,9 +19,6 @@
|
||||
#define GENERATE_ENUM(ENUM) ENUM,
|
||||
#define GENERATE_STRING(STRING) #STRING,
|
||||
|
||||
#define SSH_HOSTKEYS "/etc/ssh/hostkeys"
|
||||
#define SSH_HOSTKEYS_NEXT SSH_HOSTKEYS"+"
|
||||
|
||||
#define LLDP_CONFIG "/etc/lldpd.d/confd.conf"
|
||||
#define LLDP_CONFIG_NEXT LLDP_CONFIG"+"
|
||||
|
||||
@@ -39,7 +36,13 @@
|
||||
#define SSHD_CONFIG_BASE SSH_BASE "/sshd_config.d"
|
||||
#define SSHD_CONFIG_LISTEN SSHD_CONFIG_BASE "/listen.conf"
|
||||
#define SSHD_CONFIG_HOSTKEY SSHD_CONFIG_BASE "/host-keys.conf"
|
||||
|
||||
#define LLDP_XPATH "/ieee802-dot1ab-lldp:lldp"
|
||||
#define SSH_XPATH "/infix-services:ssh"
|
||||
#define MDNS_XPATH "/infix-services:mdns"
|
||||
#define WEB_XPATH "/infix-services:web"
|
||||
#define WEB_RESTCONF_XPATH WEB_XPATH"/restconf"
|
||||
#define WEB_NETBROWSE_XPATH WEB_XPATH"/netbrowse"
|
||||
#define WEB_CONSOLE_XPATH WEB_XPATH"/console"
|
||||
typedef enum {
|
||||
FOREACH_SVC(GENERATE_ENUM)
|
||||
} svc;
|
||||
@@ -185,12 +188,6 @@ static void svc_enadis(int ena, svc type, const char *svc)
|
||||
systemf("initctl -nbq touch nginx");
|
||||
}
|
||||
|
||||
static int hostname_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
|
||||
{
|
||||
return mdns_records("update", all);
|
||||
}
|
||||
|
||||
static void fput_list(FILE *fp, struct lyd_node *cfg, const char *list, const char *heading)
|
||||
{
|
||||
const char *prefix = heading;
|
||||
@@ -279,14 +276,16 @@ static void mdns_cname(sr_session_ctx_t *session)
|
||||
svc_enadis(ena, none, "mdns-alias");
|
||||
}
|
||||
|
||||
static int mdns_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
|
||||
static int mdns_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
struct lyd_node *srv = NULL;
|
||||
sr_data_t *cfg;
|
||||
int ena;
|
||||
|
||||
cfg = get(session, event, xpath, &srv, "mdns", NULL);
|
||||
if (event != SR_EV_DONE || !lydx_get_xpathf(diff, MDNS_XPATH))
|
||||
return SR_ERR_OK;
|
||||
|
||||
cfg = get(session, event, MDNS_XPATH, &srv, "mdns", NULL);
|
||||
if (!cfg)
|
||||
return SR_ERR_OK;
|
||||
|
||||
@@ -305,20 +304,18 @@ static int mdns_change(sr_session_ctx_t *session, uint32_t sub_id, const char *m
|
||||
return put(cfg);
|
||||
}
|
||||
|
||||
static int lldp_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
|
||||
static int lldp_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
struct lyd_node *node = NULL;
|
||||
sr_data_t *cfg;
|
||||
struct lyd_node *subnode;
|
||||
|
||||
if (diff && !lydx_get_xpathf(diff, LLDP_XPATH))
|
||||
return SR_ERR_OK;
|
||||
|
||||
switch (event) {
|
||||
case SR_EV_ENABLED:
|
||||
case SR_EV_CHANGE:
|
||||
if (sr_get_data(session, xpath, 0, 0, 0, &cfg) || !cfg)
|
||||
break;
|
||||
|
||||
node = cfg->tree;
|
||||
node = lydx_get_xpathf(config, LLDP_XPATH);
|
||||
if (lydx_is_enabled(node, "enabled")){
|
||||
const char *tx_interval = lydx_get_cattr(node, "message-tx-interval");
|
||||
FILE *fp = fopen(LLDP_CONFIG_NEXT, "w");
|
||||
@@ -342,7 +339,7 @@ static int lldp_change(sr_session_ctx_t *session, uint32_t sub_id, const char *m
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return put(cfg);
|
||||
return SR_ERR_OK;
|
||||
|
||||
case SR_EV_DONE:
|
||||
if (fexist(LLDP_CONFIG_NEXT)){
|
||||
@@ -356,7 +353,7 @@ static int lldp_change(sr_session_ctx_t *session, uint32_t sub_id, const char *m
|
||||
if (erase(LLDP_CONFIG))
|
||||
ERRNO("Failed to remove old %s", LLDP_CONFIG);
|
||||
|
||||
svc_change(session, event, xpath, "lldp", "lldpd");
|
||||
svc_change(session, event, LLDP_XPATH, "lldp", "lldpd");
|
||||
break;
|
||||
|
||||
case SR_EV_ABORT:
|
||||
@@ -370,13 +367,15 @@ static int lldp_change(sr_session_ctx_t *session, uint32_t sub_id, const char *m
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
static int ttyd_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
|
||||
static int ttyd_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
struct lyd_node *srv = NULL;
|
||||
sr_data_t *cfg;
|
||||
|
||||
cfg = get(session, event, xpath, &srv, "web", "console", NULL);
|
||||
if (event != SR_EV_DONE || !lydx_get_xpathf(diff, WEB_CONSOLE_XPATH))
|
||||
return SR_ERR_OK;
|
||||
|
||||
cfg = get(session, event, WEB_XPATH, &srv, "web", "console", NULL);
|
||||
if (!cfg)
|
||||
return SR_ERR_OK;
|
||||
|
||||
@@ -385,13 +384,15 @@ static int ttyd_change(sr_session_ctx_t *session, uint32_t sub_id, const char *m
|
||||
return put(cfg);
|
||||
}
|
||||
|
||||
static int netbrowse_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
|
||||
static int netbrowse_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
struct lyd_node *srv = NULL;
|
||||
sr_data_t *cfg;
|
||||
|
||||
cfg = get(session, event, xpath, &srv, "web", "netbrowse", NULL);
|
||||
if (event != SR_EV_DONE || !lydx_get_xpathf(diff, WEB_NETBROWSE_XPATH))
|
||||
return SR_ERR_OK;
|
||||
|
||||
cfg = get(session, event, WEB_XPATH, &srv, "web", "netbrowse", NULL);
|
||||
if (!cfg)
|
||||
return SR_ERR_OK;
|
||||
|
||||
@@ -401,13 +402,15 @@ static int netbrowse_change(sr_session_ctx_t *session, uint32_t sub_id, const ch
|
||||
return put(cfg);
|
||||
}
|
||||
|
||||
static int restconf_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
|
||||
static int restconf_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
struct lyd_node *srv = NULL;
|
||||
sr_data_t *cfg;
|
||||
|
||||
cfg = get(session, event, xpath, &srv, "web", "restconf", NULL);
|
||||
if (event != SR_EV_DONE || !lydx_get_xpathf(diff, WEB_RESTCONF_XPATH))
|
||||
return SR_ERR_OK;
|
||||
|
||||
cfg = get(session, event, WEB_XPATH, &srv, "web", "restconf", NULL);
|
||||
if (!cfg)
|
||||
return SR_ERR_OK;
|
||||
|
||||
@@ -416,17 +419,18 @@ static int restconf_change(sr_session_ctx_t *session, uint32_t sub_id, const cha
|
||||
return put(cfg);
|
||||
}
|
||||
|
||||
static int ssh_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
|
||||
static int ssh_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
struct lyd_node *ssh = NULL, *listen, *host_key;
|
||||
sr_error_t rc = SR_ERR_OK;
|
||||
sr_data_t *cfg;
|
||||
FILE *fp;
|
||||
|
||||
if (diff && !lydx_get_xpathf(diff, SSH_XPATH))
|
||||
return SR_ERR_OK;
|
||||
|
||||
switch (event) {
|
||||
case SR_EV_DONE:
|
||||
return svc_change(session, event, xpath, "ssh", "sshd");
|
||||
return svc_change(session, event, SSH_XPATH, "ssh", "sshd");
|
||||
case SR_EV_ENABLED:
|
||||
case SR_EV_CHANGE:
|
||||
break;
|
||||
@@ -436,10 +440,7 @@ static int ssh_change(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
if (sr_get_data(session, xpath, 0, 0, 0, &cfg) || !cfg) {
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
ssh = cfg->tree;
|
||||
ssh = lydx_get_xpathf(config, SSH_XPATH);
|
||||
|
||||
if (!lydx_is_enabled(ssh, "enabled")) {
|
||||
goto out;
|
||||
@@ -479,27 +480,29 @@ static int ssh_change(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
|
||||
fclose(fp);
|
||||
|
||||
out:
|
||||
sr_release_data(cfg);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int web_change(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
|
||||
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
|
||||
|
||||
static int web_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
struct lyd_node *srv = NULL;
|
||||
sr_data_t *cfg;
|
||||
int ena;
|
||||
|
||||
cfg = get(session, event, xpath, &srv, "web", NULL);
|
||||
if (event != SR_EV_DONE || !lydx_get_xpathf(diff, WEB_XPATH))
|
||||
return SR_ERR_OK;
|
||||
|
||||
cfg = get(session, event, WEB_XPATH, &srv, "web", NULL);
|
||||
if (!cfg)
|
||||
return SR_ERR_OK;
|
||||
|
||||
ena = lydx_is_enabled(srv, "enabled");
|
||||
if (ena) {
|
||||
svc_enadis(srx_enabled(session, "%s/console/enabled", xpath), ttyd, "ttyd");
|
||||
svc_enadis(srx_enabled(session, "%s/netbrowse/enabled", xpath), netbrowse, "netbrowse");
|
||||
svc_enadis(srx_enabled(session, "%s/restconf/enabled", xpath), restconf, "restconf");
|
||||
svc_enadis(srx_enabled(session, "%s/enabled", WEB_CONSOLE_XPATH), ttyd, "ttyd");
|
||||
svc_enadis(srx_enabled(session, "%s/enabled", WEB_NETBROWSE_XPATH), netbrowse, "netbrowse");
|
||||
svc_enadis(srx_enabled(session, "%s/enabled", WEB_RESTCONF_XPATH), restconf, "restconf");
|
||||
} else {
|
||||
svc_enadis(0, ttyd, NULL);
|
||||
svc_enadis(0, netbrowse, NULL);
|
||||
@@ -512,104 +515,30 @@ static int web_change(sr_session_ctx_t *session, uint32_t sub_id, const char *mo
|
||||
return put(cfg);
|
||||
}
|
||||
|
||||
/* Store SSH public/private keys */
|
||||
static int change_keystore_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *module_name,
|
||||
const char *xpath, sr_event_t event, uint32_t request_id, void *_)
|
||||
{
|
||||
int rc = SR_ERR_OK;
|
||||
sr_data_t *cfg;
|
||||
struct lyd_node *changes, *change;
|
||||
|
||||
switch (event) {
|
||||
case SR_EV_CHANGE:
|
||||
case SR_EV_ENABLED:
|
||||
break;
|
||||
case SR_EV_ABORT:
|
||||
rmrf(SSH_HOSTKEYS_NEXT);
|
||||
return SR_ERR_OK;
|
||||
case SR_EV_DONE:
|
||||
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);
|
||||
|
||||
svc_change(session, event, "/infix-services:ssh", "ssh", "sshd");
|
||||
}
|
||||
return SR_ERR_OK;
|
||||
|
||||
default:
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
if (sr_get_data(session, "/ietf-keystore:keystore/asymmetric-keys//.", 0, 0, 0, &cfg) || !cfg) {
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
changes = lydx_get_descendant(cfg->tree, "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;
|
||||
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(public_key_type, "infix-crypto-types:ssh-public-key-format")) {
|
||||
INFO("Public key %s is not of SSH type", name);
|
||||
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;
|
||||
}
|
||||
|
||||
sr_release_data(cfg);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int infix_services_init(struct confd *confd)
|
||||
int infix_services_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd)
|
||||
{
|
||||
int rc;
|
||||
|
||||
REGISTER_CHANGE(confd->session, "infix-services", "/infix-services:mdns",
|
||||
0, mdns_change, confd, &confd->sub);
|
||||
REGISTER_MONITOR(confd->session, "ietf-system", "/ietf-system:system/hostname",
|
||||
0, hostname_change, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->session, "infix-services", "/infix-services:ssh",
|
||||
0, ssh_change, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->session, "infix-services", "/infix-services:web",
|
||||
0, web_change, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->session, "infix-services", "/infix-services:web/infix-services:console",
|
||||
0, ttyd_change, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->session, "infix-services", "/infix-services:web/infix-services:netbrowse",
|
||||
0, netbrowse_change, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->session, "infix-services", "/infix-services:web/infix-services:restconf",
|
||||
0, restconf_change, confd, &confd->sub);
|
||||
REGISTER_CHANGE(confd->session, "ieee802-dot1ab-lldp", "/ieee802-dot1ab-lldp:lldp",
|
||||
0, lldp_change, confd, &confd->sub);
|
||||
|
||||
/* Store SSH keys */
|
||||
REGISTER_CHANGE(confd->session, "ietf-keystore", "/ietf-keystore:keystore//.",
|
||||
0, change_keystore_cb, confd, &confd->sub);
|
||||
|
||||
rc = lldp_change(session, config, diff, event, confd);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = mdns_change(session, config, diff, event, confd); /* TODO: Depends on hostname changes */
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = ssh_change(session, config, diff, event, confd); /* TODO: Depends on keystore changes*/
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = web_change(session, config, diff, event, confd);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = ttyd_change(session, config, diff, event, confd);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = restconf_change(session, config, diff, event, confd);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = netbrowse_change(session, config, diff, event, confd);
|
||||
if (rc)
|
||||
return rc;
|
||||
return SR_ERR_OK;
|
||||
fail:
|
||||
ERROR("init failed: %s", sr_strerror(rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ static int infix_system_sw_set_boot_order(sr_session_ctx_t *session, uint32_t su
|
||||
return SR_ERR_OK;
|
||||
}
|
||||
|
||||
int infix_system_sw_init(struct confd *confd)
|
||||
int infix_system_sw_rpc_init(struct confd *confd)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
+4
-3
@@ -17,14 +17,15 @@
|
||||
- name: Misc tests
|
||||
suite: misc/all.yaml
|
||||
|
||||
|
||||
- name: "IETF System"
|
||||
suite: ietf_system/all.yaml
|
||||
|
||||
# Upgrade may leave wrong boot order
|
||||
- case: meta/bootorder.py
|
||||
infamy:
|
||||
specification: False
|
||||
|
||||
- name: "IETF System"
|
||||
suite: ietf_system/all.yaml
|
||||
|
||||
- name: "IETF Syslog"
|
||||
suite: ietf_syslog/all.yaml
|
||||
|
||||
|
||||
@@ -57,9 +57,7 @@ with infamy.Test() as test:
|
||||
"name": tport,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"autoconf": {
|
||||
"enabled": True
|
||||
}
|
||||
"infix-ip:autoconf": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -79,8 +77,7 @@ with infamy.Test() as test:
|
||||
"name": tport,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"autoconf": {
|
||||
"enabled": True,
|
||||
"infix-ip:autoconf": {
|
||||
"request-address": "169.254.42.42"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ image::topology.svg[Remote syslog topology, align=center, scaledwidth=75%]
|
||||
|
||||
. Set up topology and attach to client and server DUTs
|
||||
. Configure client DUT as syslog client with server DUT as remote, and configure server DUT as syslog server
|
||||
. Send security:notice log message from client
|
||||
. Verify reception of client log message, incl. sorting to /log/security on server
|
||||
. Send security:notice log message from client and verify reception of client log message, incl. sorting to /log/security on server
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,11 @@ Verify logging to remote, acting as a remote, and RFC5424 log format.
|
||||
"""
|
||||
import infamy
|
||||
|
||||
def syslog_check(clientssh, serverssh):
|
||||
clientssh.runsh("logger -t test -m client -p security.notice TestMessage")
|
||||
return serverssh.runsh("tail -n10 /log/security |grep 'test - client - TestMessage'").returncode == 0
|
||||
|
||||
|
||||
with infamy.Test() as test:
|
||||
with test.step("Set up topology and attach to client and server DUTs"):
|
||||
env = infamy.Env()
|
||||
@@ -142,11 +147,8 @@ with infamy.Test() as test:
|
||||
}
|
||||
})
|
||||
|
||||
with test.step("Send security:notice log message from client"):
|
||||
clientssh.runsh("logger -t test -m client -p security.notice TestMessage")
|
||||
with test.step("Send security:notice log message from client and verify reception of client log message, incl. sorting to /log/security on server"):
|
||||
infamy.until(lambda: syslog_check(clientssh, serverssh) == True)
|
||||
|
||||
with test.step("Verify reception of client log message, incl. sorting to /log/security on server"):
|
||||
infamy.until(lambda: serverssh.runsh(
|
||||
"grep 'test - client - TestMessage' /log/security").returncode == 0)
|
||||
|
||||
test.succeed()
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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"}
|
||||
]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
})
|
||||
|
||||
@@ -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"}
|
||||
]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -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}
|
||||
]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -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}
|
||||
]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -212,7 +212,6 @@ table ip nat {
|
||||
"enabled": True,
|
||||
"forwarding": True,
|
||||
"infix-ip:autoconf": {
|
||||
"enabled": True,
|
||||
"request-address": "169.254.1.1"
|
||||
}
|
||||
},
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ def _get_ntp(target):
|
||||
if data is None:
|
||||
return None
|
||||
|
||||
return data["system-state"].get("infix-system:ntp", None) or data["system-state"].get("ntp", None)
|
||||
return data.get("system-state", {}).get("infix-system:ntp", None) or data.get("system-state", {}).get("ntp", None)
|
||||
|
||||
|
||||
def _get_ntp_sources(target):
|
||||
|
||||
+37
-12
@@ -6,7 +6,7 @@
|
||||
# Usage: ./utils/kernel-upgrade.sh <path-to-linux-dir>
|
||||
#
|
||||
|
||||
set -e
|
||||
set -e -o pipefail
|
||||
|
||||
# Parse arguments
|
||||
if [ $# -ne 1 ]; then
|
||||
@@ -139,15 +139,6 @@ rebase_kernel() {
|
||||
log_info "Run 'git rebase --abort' to cancel or resolve conflicts manually"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Push rebased branch to kkit remote
|
||||
log_info "Pushing rebased branch to $KKIT_REMOTE..."
|
||||
if git -C "$LINUX_DIR" push "$KKIT_REMOTE" "$LINUX_BRANCH" --force-with-lease; then
|
||||
log_info "Successfully pushed to $KKIT_REMOTE"
|
||||
else
|
||||
log_error "Push failed"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Update infix and run kernel refresh
|
||||
@@ -195,8 +186,8 @@ update_infix() {
|
||||
|
||||
# Check if versions are the same
|
||||
if [ "$OLD_VERSION" = "$NEW_VERSION" ]; then
|
||||
log_info "Kernel version unchanged ($OLD_VERSION), skipping refresh"
|
||||
return 0
|
||||
log_info "Kernel version unchanged ($OLD_VERSION), nothing to do"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Run kernel refresh script
|
||||
@@ -231,6 +222,16 @@ update_infix() {
|
||||
else
|
||||
log_warn "doc/ChangeLog.md not found, skipping changelog update"
|
||||
fi
|
||||
|
||||
# Commit all changes
|
||||
log_info "Committing changes to infix..."
|
||||
git -C "$INFIX_DIR" add -A
|
||||
if git -C "$INFIX_DIR" diff-index --quiet HEAD --; then
|
||||
log_info "No changes to commit"
|
||||
else
|
||||
git -C "$INFIX_DIR" commit -m "Upgrade Linux kernel to $NEW_VERSION"
|
||||
log_info "Changes committed"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check for uncommitted changes
|
||||
@@ -254,6 +255,29 @@ check_clean_working_tree() {
|
||||
log_info "Working tree is clean"
|
||||
}
|
||||
|
||||
# Push changes to remotes
|
||||
push_changes() {
|
||||
log_info "Pushing changes to remotes..."
|
||||
|
||||
# Push rebased linux branch to kkit remote
|
||||
log_info "Pushing rebased linux branch to $KKIT_REMOTE..."
|
||||
if git -C "$LINUX_DIR" push "$KKIT_REMOTE" "$LINUX_BRANCH" --force-with-lease; then
|
||||
log_info "Successfully pushed linux branch to $KKIT_REMOTE"
|
||||
else
|
||||
log_error "Push to linux remote failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Push infix branch to origin
|
||||
log_info "Pushing infix branch to origin..."
|
||||
if git -C "$INFIX_DIR" push origin "$INFIX_BRANCH"; then
|
||||
log_info "Successfully pushed infix branch to origin"
|
||||
else
|
||||
log_error "Push to infix remote failed"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
log_info "Starting automated kernel upgrade test..."
|
||||
@@ -265,6 +289,7 @@ main() {
|
||||
update_linux_kernel
|
||||
rebase_kernel
|
||||
update_infix
|
||||
push_changes
|
||||
|
||||
log_info "Kernel upgrade completed successfully!"
|
||||
}
|
||||
|
||||
+185
-23
@@ -18,10 +18,12 @@ Usage:
|
||||
$0 [OPTIONS] <board-name>
|
||||
|
||||
Options:
|
||||
-b boot-dir Path to bootloader build directory (default: O= or output/)
|
||||
-d Download bootloader files from latest-boot release
|
||||
-f Force re-download of bootloader even if cached
|
||||
-h This help text
|
||||
-l List available boards
|
||||
-o Override auto-detection of genimage.sh, use host installed version
|
||||
-b boot-dir Path to bootloader build directory (default: O= or output/)
|
||||
-r root-dir Path to rootfs build directory or rootfs.squashfs file (default: O= or output/)
|
||||
|
||||
Arguments:
|
||||
@@ -44,8 +46,11 @@ Examples:
|
||||
# Standalone with separate boot/rootfs builds:
|
||||
$0 -b x-boot -r output raspberrypi-rpi64
|
||||
|
||||
# With downloaded rootfs:
|
||||
$0 -b x-boot -r ~/Downloads/rootfs.squashfs friendlyarm-nanopi-r2s
|
||||
# With downloaded rootfs and bootloader:
|
||||
$0 -d -r ~/Downloads/rootfs.squashfs friendlyarm-nanopi-r2s
|
||||
|
||||
# Download bootloader and compose with Linux image in output directory:
|
||||
$0 -od bananapi-bpi-r3
|
||||
|
||||
EOF
|
||||
}
|
||||
@@ -153,6 +158,83 @@ find_build_dir()
|
||||
return 1
|
||||
}
|
||||
|
||||
# Map board name to bootloader identifier
|
||||
# Returns bootloader name used in artifact naming
|
||||
get_bootloader_name()
|
||||
{
|
||||
board="$1"
|
||||
case "$board" in
|
||||
raspberrypi-rpi64)
|
||||
echo "rpi64_boot"
|
||||
;;
|
||||
bananapi-bpi-r3)
|
||||
echo "bpi_r3_boot"
|
||||
;;
|
||||
friendlyarm-nanopi-r2s)
|
||||
echo "nanopi_r2s_boot"
|
||||
;;
|
||||
*)
|
||||
err "Unknown bootloader for board: $board"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Download and extract bootloader from latest-boot release
|
||||
# Downloads to dl/bootloader/ cache and extracts to temporary build directory
|
||||
# Returns the temporary directory path in SDCARD_TEMP_DIR variable
|
||||
download_bootloader()
|
||||
{
|
||||
board="$1"
|
||||
build_dir="$2"
|
||||
|
||||
bootloader=$(get_bootloader_name "$board") || return 1
|
||||
|
||||
if ! command -v gh >/dev/null 2>&1; then
|
||||
die "gh CLI not found. Install it or build bootloader locally."
|
||||
fi
|
||||
|
||||
# Set up download cache directory
|
||||
dl_dir="${BR2_EXTERNAL_INFIX_PATH}/dl/bootloader"
|
||||
mkdir -p "$dl_dir"
|
||||
|
||||
# Convert underscores to dashes for filename pattern matching
|
||||
bootloader_pattern=$(echo "$bootloader" | tr '_' '-')
|
||||
|
||||
# Find or download bootloader tarball
|
||||
tarball=$(ls "$dl_dir"/${bootloader_pattern}*.tar.gz 2>/dev/null | head -n1)
|
||||
|
||||
if [ -z "$tarball" ] || [ -n "$FORCE_DOWNLOAD" ]; then
|
||||
if [ -n "$FORCE_DOWNLOAD" ] && [ -n "$tarball" ]; then
|
||||
log "Force re-downloading bootloader..."
|
||||
rm -f "$tarball" "$tarball.sha256"
|
||||
else
|
||||
log "Downloading bootloader $bootloader from latest-boot release..."
|
||||
fi
|
||||
|
||||
if ! gh release download latest-boot \
|
||||
--repo kernelkit/infix \
|
||||
--pattern "*${bootloader_pattern}*.tar.gz" \
|
||||
--dir "$dl_dir"; then
|
||||
die "Failed downloading bootloader from latest-boot release. Check gh authentication and network connectivity."
|
||||
fi
|
||||
|
||||
tarball=$(ls "$dl_dir"/${bootloader_pattern}*.tar.gz 2>/dev/null | head -n1)
|
||||
[ -n "$tarball" ] || die "Downloaded tarball not found in $dl_dir"
|
||||
else
|
||||
log "Using cached bootloader: $(basename "$tarball")"
|
||||
fi
|
||||
|
||||
# Create temporary directory for SD card composition
|
||||
SDCARD_TEMP_DIR="${build_dir}/sdcard-${board}-$$"
|
||||
mkdir -p "$SDCARD_TEMP_DIR"
|
||||
|
||||
log "Extracting bootloader to $SDCARD_TEMP_DIR..."
|
||||
tar -xzf "$tarball" --strip-components=1 -C "$SDCARD_TEMP_DIR/"
|
||||
|
||||
log "Bootloader ready in temporary directory"
|
||||
}
|
||||
|
||||
# Discover boot files for Raspberry Pi boot partition
|
||||
# Scans rpi-firmware directory and builds file list for genimage
|
||||
discover_rpi_boot_files()
|
||||
@@ -189,8 +271,19 @@ discover_rpi_boot_files()
|
||||
echo "$files"
|
||||
}
|
||||
|
||||
while getopts "hlob:r:" opt; do
|
||||
while getopts "hldfob:r:" opt; do
|
||||
case $opt in
|
||||
b)
|
||||
BOOT_DIR="$OPTARG"
|
||||
STANDALONE=1
|
||||
;;
|
||||
d)
|
||||
DOWNLOAD_BOOT=1
|
||||
STANDALONE=1
|
||||
;;
|
||||
f)
|
||||
FORCE_DOWNLOAD=1
|
||||
;;
|
||||
h)
|
||||
usage
|
||||
exit 0
|
||||
@@ -199,10 +292,6 @@ while getopts "hlob:r:" opt; do
|
||||
list_boards
|
||||
exit 0
|
||||
;;
|
||||
b)
|
||||
BOOT_DIR="$OPTARG"
|
||||
STANDALONE=1
|
||||
;;
|
||||
o)
|
||||
OVERRIDE=1
|
||||
;;
|
||||
@@ -225,12 +314,19 @@ fi
|
||||
|
||||
# Standalone mode: set up environment from build directories
|
||||
if [ -n "$STANDALONE" ]; then
|
||||
if [ -z "$BOOT_DIR" ]; then
|
||||
BOOT_DIR=$(find_build_dir) || die "Could not find boot directory. Use -b option"
|
||||
fi
|
||||
# In download mode without explicit dirs, default to same location for both
|
||||
if [ -n "$DOWNLOAD_BOOT" ]; then
|
||||
default_dir=$(find_build_dir) || die "Could not find build directory. Set O= or use -b/-r option"
|
||||
: "${BOOT_DIR:=$default_dir}"
|
||||
: "${ROOT_DIR:=$default_dir}"
|
||||
else
|
||||
if [ -z "$BOOT_DIR" ]; then
|
||||
BOOT_DIR=$(find_build_dir) || die "Could not find boot directory. Use -b option"
|
||||
fi
|
||||
|
||||
if [ -z "$ROOT_DIR" ]; then
|
||||
ROOT_DIR=$(find_build_dir) || die "Could not find rootfs directory. Set O= or use -r option"
|
||||
if [ -z "$ROOT_DIR" ]; then
|
||||
ROOT_DIR=$(find_build_dir) || die "Could not find rootfs directory. Set O= or use -r option"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Set up environment variables, some required by genimage.sh
|
||||
@@ -248,22 +344,33 @@ if [ -n "$STANDALONE" ]; then
|
||||
fi
|
||||
done
|
||||
|
||||
# Copy rootfs and partition images to BINARIES_DIR
|
||||
# Copy rootfs and partition images to BINARIES_DIR (skip if same directory)
|
||||
mkdir -p "$BINARIES_DIR"
|
||||
|
||||
# Normalize paths for comparison
|
||||
boot_images=$(cd "$BOOT_DIR" && pwd)/images
|
||||
root_images=""
|
||||
|
||||
if [ -f "$ROOT_DIR" ]; then
|
||||
# Direct path to rootfs.squashfs file
|
||||
log "Copying rootfs from $ROOT_DIR to $BINARIES_DIR/rootfs.squashfs"
|
||||
cp "$ROOT_DIR" "$BINARIES_DIR/rootfs.squashfs"
|
||||
elif [ -f "$ROOT_DIR/images/rootfs.squashfs" ]; then
|
||||
# Build directory with images/ - copy rootfs and partition images
|
||||
log "Copying artifacts from $ROOT_DIR/images/ to $BINARIES_DIR/"
|
||||
cp "$ROOT_DIR/images/rootfs.squashfs" "$BINARIES_DIR/"
|
||||
# Copy partition images if they exist
|
||||
for img in aux.ext4 cfg.ext4 var.ext4; do
|
||||
if [ -f "$ROOT_DIR/images/$img" ]; then
|
||||
cp "$ROOT_DIR/images/$img" "$BINARIES_DIR/"
|
||||
fi
|
||||
done
|
||||
root_images=$(cd "$ROOT_DIR" && pwd)/images
|
||||
# Only copy if different directories
|
||||
if [ "$boot_images" != "$root_images" ]; then
|
||||
# Build directory with images/ - copy rootfs and partition images
|
||||
log "Copying artifacts from $ROOT_DIR/images/ to $BINARIES_DIR/"
|
||||
cp "$ROOT_DIR/images/rootfs.squashfs" "$BINARIES_DIR/"
|
||||
# Copy partition images if they exist
|
||||
for img in aux.ext4 cfg.ext4 var.ext4; do
|
||||
if [ -f "$ROOT_DIR/images/$img" ]; then
|
||||
cp "$ROOT_DIR/images/$img" "$BINARIES_DIR/"
|
||||
fi
|
||||
done
|
||||
else
|
||||
log "Rootfs already in place at $BINARIES_DIR/"
|
||||
fi
|
||||
elif [ -f "$ROOT_DIR/rootfs.squashfs" ]; then
|
||||
# Directory directly containing rootfs.squashfs
|
||||
log "Copying rootfs from $ROOT_DIR/rootfs.squashfs"
|
||||
@@ -292,6 +399,42 @@ fi
|
||||
: "${RELEASE:=""}"
|
||||
: "${INFIX_ID:="infix"}"
|
||||
|
||||
# Download bootloader if requested
|
||||
if [ -n "$DOWNLOAD_BOOT" ]; then
|
||||
# Save original output location
|
||||
ORIGINAL_BINARIES_DIR="$BINARIES_DIR"
|
||||
|
||||
download_bootloader "$BOARD" "$BUILD_DIR"
|
||||
|
||||
# Now use the temporary directory for composition
|
||||
BINARIES_DIR="$SDCARD_TEMP_DIR"
|
||||
|
||||
log "Linking rootfs files to $BINARIES_DIR..."
|
||||
# Link rootfs and partition images to temp directory
|
||||
if [ -f "$ROOT_DIR" ]; then
|
||||
# Direct path to rootfs.squashfs file
|
||||
ln -sf "$(realpath "$ROOT_DIR")" "$BINARIES_DIR/rootfs.squashfs"
|
||||
elif [ -f "$ROOT_DIR/images/rootfs.squashfs" ]; then
|
||||
ln -sf "$(realpath "$ROOT_DIR/images/rootfs.squashfs")" "$BINARIES_DIR/rootfs.squashfs"
|
||||
# Link partition images if they exist
|
||||
for img in aux.ext4 cfg.ext4 var.ext4; do
|
||||
if [ -f "$ROOT_DIR/images/$img" ]; then
|
||||
ln -sf "$(realpath "$ROOT_DIR/images/$img")" "$BINARIES_DIR/$img"
|
||||
fi
|
||||
done
|
||||
elif [ -f "$ROOT_DIR/rootfs.squashfs" ]; then
|
||||
ln -sf "$(realpath "$ROOT_DIR/rootfs.squashfs")" "$BINARIES_DIR/rootfs.squashfs"
|
||||
# Link partition images if they exist
|
||||
for img in aux.ext4 cfg.ext4 var.ext4; do
|
||||
if [ -f "$ROOT_DIR/$img" ]; then
|
||||
ln -sf "$(realpath "$ROOT_DIR/$img")" "$BINARIES_DIR/$img"
|
||||
fi
|
||||
done
|
||||
else
|
||||
die "Could not find rootfs.squashfs in $ROOT_DIR"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Template expansion
|
||||
log "Generating genimage configuration for $BOARD..."
|
||||
|
||||
@@ -343,6 +486,25 @@ else
|
||||
run_genimage "$GENIMAGE_CFG"
|
||||
fi
|
||||
|
||||
# Post-processing: move images and cleanup if using download mode
|
||||
if [ -n "$DOWNLOAD_BOOT" ]; then
|
||||
log "Moving SD card images to $ORIGINAL_BINARIES_DIR..."
|
||||
mkdir -p "$ORIGINAL_BINARIES_DIR"
|
||||
|
||||
for img in "${BINARIES_DIR}"/*-sdcard.img*; do
|
||||
if [ -f "$img" ]; then
|
||||
mv "$img" "$ORIGINAL_BINARIES_DIR/"
|
||||
log " $(basename "$img")"
|
||||
fi
|
||||
done
|
||||
|
||||
log "Cleaning up temporary directory..."
|
||||
rm -rf "$SDCARD_TEMP_DIR"
|
||||
|
||||
# Update BINARIES_DIR for final output message
|
||||
BINARIES_DIR="$ORIGINAL_BINARIES_DIR"
|
||||
fi
|
||||
|
||||
log "SD card image created successfully:"
|
||||
for img in "${BINARIES_DIR}"/*-sdcard.img*; do
|
||||
if [ -f "$img" ]; then
|
||||
|
||||
Reference in New Issue
Block a user