Compare commits

..
Author SHA1 Message Date
Richard Alpe 0ae395cff8 hack: refactor software from cli-pretty to show
Signed-off-by: Richard Alpe <richard@bit42.se>
2025-05-06 16:33:48 +02:00
Richard Alpe ab8b174eff confd: augment new services container to ietf-system
This patch adds operational data support for system services. The
data is in a generic format but is intended to be able to represent
finit information (initctl) nicely.

The reason for augmenting this to ietf-system and not to
infix-services is that we consider this generic system information
which is totally disconnected from what ever services infix might
provide.

In this first state we only support pid, name, description and state.
Making the data look something like:

  "infix-system:services": {
    "service": [
      {
        "pid": 1185,
        "name": "udevd",
        "status": "running",
        "description": "Device event daemon (udev)"
      }]

Signed-off-by: Richard Alpe <richard@bit42.se>
2025-05-06 16:29:03 +02:00
137 changed files with 1272 additions and 3462 deletions
+2 -21
View File
@@ -13,11 +13,7 @@ on:
required: false
default: true
type: boolean
parallell:
description: 'Massive parallel build of each image'
required: false
default: true
type: boolean
jobs:
build:
name: Build Infix ${{ matrix.target }}
@@ -75,7 +71,6 @@ jobs:
echo "tgz=infix-$target.tar.gz" >> $GITHUB_OUTPUT
echo "flv=$flavor" >> $GITHUB_OUTPUT
echo "Building target ${target}${flavor}_defconfig"
- name: Restore Cache of dl/
uses: actions/cache@v4
with:
@@ -101,24 +96,10 @@ jobs:
run: |
make test-unit
- name: Prepare parallel build
id: parallel
run: |
if [ "${{ ((github.event.inputs.parallel == 'true' && github.event_name == 'workflow_dispatch') || (github.ref_name != 'main' && github.event_name != 'workflow_dispatch')) }}" == "true" ]; then
echo "BR2_PER_PACKAGE_DIRECTORIES=y" >> output/.config
MAKE="make -j$((`getconf _NPROCESSORS_ONLN` / 2 + 2))"
echo "Building in parallel with -j$((`getconf _NPROCESSORS_ONLN` / 2 + 2))"
else
echo "Disabling parallel build"
MAKE="make"
fi
echo "MAKE=$MAKE" >> $GITHUB_OUTPUT
- name: Build ${{ matrix.target }}${{ steps.vars.outputs.flv }}
run: |
echo "Building ${{ matrix.target }}${{ steps.vars.outputs.flv }}_defconfig ..."
eval "${{ steps.parallel.outputs.MAKE }}"
make
- name: Check SBOM from Build
run: |
+4 -6
View File
@@ -93,14 +93,12 @@ The [following boards](board/aarch64/README.md) are fully supported:
- Marvell CN9130 CRB
- Marvell EspressoBIN
- Microchip SparX-5i PCB135 (eMMC)
- Raspberry Pi 4B
- StarFive VisionFive2
- NanoPi R2S
Additionally, StarFive VisionFive2, a RISC-V based two-port router, and
an x86_64 build is also available. The latter is primarily intended for
development and testing, but can also be used for evaluation and demo
purposes. For more information, see: [Infix in Virtual
Environments](doc/virtual.md).
An x86_64 build is also available, primarily intended for development
and testing, but can also be used for evaluation and demo purposes. For
more information, see: [Infix in Virtual Environments](doc/virtual.md).
> See the [GitHub Releases](https://github.com/kernelkit/infix/releases)
> page for our pre-built images. The *[Latest Build][]* has bleeding
@@ -1,14 +0,0 @@
--- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts 2025-04-28 00:13:06.880003668 +0200
+++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts 2025-04-28 00:14:17.708941263 +0200
@@ -14,6 +14,11 @@
chosen {
/* 8250 auxiliary UART instead of pl011 */
stdout-path = "serial1:115200n8";
+
+ infix {
+ /* Default admin user password: 'admin' */
+ factory-password-hash = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A";
+ };
};
cam1_reg: regulator-cam1 {
File diff suppressed because it is too large Load Diff
-1
View File
@@ -1 +0,0 @@
root=/dev/mmcblk0p2 rootwait console=tty1 console=ttyAMA0,115200
-41
View File
@@ -1,41 +0,0 @@
# Please note that this is only a sample, we recommend you to change it to fit
# your needs.
# You should override this file using BR2_PACKAGE_RPI_FIRMWARE_CONFIG_FILE.
# See http://buildroot.org/manual.html#rootfs-custom
# and http://elinux.org/RPiconfig for a description of config.txt syntax
start_file=start4.elf
fixup_file=fixup4.dat
kernel=u-boot.bin
device_tree=bcm2711-rpi-4-b.dtb
dtoverlay=rpi-env
dtoverlay=infix-key
# To use an external initramfs file
#initramfs rootfs.cpio.gz
# Disable overscan assuming the display supports displaying the full resolution
# If the text shown on the screen disappears off the edge, comment this out
disable_overscan=1
# How much memory in MB to assign to the GPU on Pi models having
# 256, 512 or 1024 MB total memory
gpu_mem_256=100
gpu_mem_512=100
gpu_mem_1024=100
# Enable UART0 for serial console on ttyAMA0
enable_uart=1
force_turbo=1
#dtoverlay=miniuart-bt
# Run as fast as firmware / board allows
arm_boost=1
# enable 64bits support
arm_64bit=1
# Enable early debugging info
uart_2ndstage=1
-71
View File
@@ -1,71 +0,0 @@
image boot.vfat {
vfat {
files = {
#BOOT_FILES#
}
}
size = 32M
}
image cfg.ext4 {
empty = true
temporary = true
size = 16M
ext4 {
label = "cfg"
}
}
image var.ext4 {
empty = true
temporary = true
size = 512M
ext4 {
label = "var"
use-mke2fs = true
}
}
image sdcard.img {
hdimage {
partition-table-type = "gpt"
}
partition boot {
partition-type-uuid = EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
bootable = "true"
image = "boot.vfat"
}
partition aux {
partition-uuid = D4EF35A0-0652-45A1-B3DE-D63339C82035
image = "aux.ext4"
}
partition primary {
partition-type-uuid = 0FC63DAF-8483-4772-8E79-3D69D8477DE4
bootable = true
size = 200M
image = "rootfs.squashfs"
}
partition secondary {
partition-type-uuid = 0FC63DAF-8483-4772-8E79-3D69D8477DE4
bootable = true
size = 200M
image = "rootfs.squashfs"
}
partition cfg {
partition-uuid = 7aa497f0-73b5-47e5-b2ab-8752d8a48105
image = "cfg.ext4"
}
partition var {
partition-uuid = 8046A06A-E45A-4A14-A6AD-6684704A393F
image = "var.ext4"
}
}
-7
View File
@@ -1,7 +0,0 @@
#!/bin/sh
# Armbian firmware installs to /lib/firmware but driver wants the
# file(s) in /lib/firmware/brcm/
if [ -f "${TARGET_DIR}/lib/firmware/BCM4345C0.hcd" ]; then
mv "${TARGET_DIR}/lib/firmware/BCM4345C0.hcd" "${TARGET_DIR}/lib/firmware/brcm/"
fi
-43
View File
@@ -1,43 +0,0 @@
#!/bin/sh
set -e
BOARD_DIR=$(dirname "$0")
GENIMAGE_CFG="${BUILD_DIR}/genimage.cfg"
GENIMAGE_TMP="${BUILD_DIR}/genimage.tmp"
# Device trees are installed for distro boot (syslinux.conf), but on RPi
# we need them for the SPL, which feeds the TPL (U-Boot) for use instead
# of the (built-in) control DT other platforms use.
find "${TARGET_DIR}/boot" -type f -name '*.dtb' -exec cp '{}' "${BINARIES_DIR}/" \;
# We've asked U-Boot previously to build overlays for us: Infix signing
# key and our ixboot scripts. Make sure here they are installed in the
# proper directory so genimage can create the DOS partition the SPL
# reads config.txt from.
find "${BINARIES_DIR}" -type f -name '*.dtbo' -exec mv '{}' "${BINARIES_DIR}/rpi-firmware/overlays/" \;
# Create FILES array for the genimage.cfg generation
FILES=""
for f in "${BINARIES_DIR}"/*.dtb "${BINARIES_DIR}"/rpi-firmware/*; do
case "$f" in
*~|*.bak) continue ;;
esac
FILES="${FILES}\t\t\t\"${f#"${BINARIES_DIR}/"}\",\n"
done
KERNEL=$(sed -n 's/^kernel=//p' "${BINARIES_DIR}/rpi-firmware/config.txt")
FILES="${FILES}\t\t\t\"${KERNEL}\""
sed "s|#BOOT_FILES#|${FILES}|" "${BOARD_DIR}/genimage.cfg.in" > "${GENIMAGE_CFG}"
ROOTPATH_TMP=$(mktemp -d)
trap 'rm -rf \"$ROOTPATH_TMP\"' EXIT
rm -rf "${GENIMAGE_TMP}"
genimage \
--rootpath "${ROOTPATH_TMP}" \
--tmppath "${GENIMAGE_TMP}" \
--inputpath "${BINARIES_DIR}" \
--outputpath "${BINARIES_DIR}" \
--config "${GENIMAGE_CFG}"
@@ -1,16 +0,0 @@
default rpi4b
menu title Boot Menu
prompt 1
timeout 30
label rpi4b
menu label Infix on Raspberry Pi 4B
kernel /boot/Image
devicetree /boot/broadcom/bcm2711-rpi-4-b.dtb
append ${bootargs_root} 8250.nr_uarts=1 console=ttyS0,115200 ${bootargs_log} -- ${bootargs_user}
label rpi400
menu label Infix on Raspberry Pi 400
kernel /boot/Image
devicetree /boot/broadcom/bcm2711-rpi-400.dtb
append ${bootargs_root} 8250.nr_uarts=1 console=ttyS0,115200 ${bootargs_log} -- ${bootargs_user}
@@ -1,193 +0,0 @@
{
"ieee802-dot1ab-lldp:lldp": {
"infix-lldp:enabled": true
},
"ietf-interfaces:interfaces": {
"interface": [
{
"name": "lo",
"type": "infix-if-type:loopback",
"ietf-ip:ipv4": {
"address": [
{
"ip": "127.0.0.1",
"prefix-length": 8
}
]
},
"ietf-ip:ipv6": {
"address": [
{
"ip": "::1",
"prefix-length": 128
}
]
}
},
{
"name": "eth0",
"type": "infix-if-type:ethernet"
}
]
},
"ietf-keystore:keystore": {
"asymmetric-keys": {
"asymmetric-key": [
{
"name": "genkey",
"public-key-format": "ietf-crypto-types:ssh-public-key-format",
"public-key": "",
"private-key-format": "ietf-crypto-types:rsa-private-key-format",
"cleartext-private-key": "",
"certificates": {}
}
]
}
},
"ietf-netconf-acm:nacm": {
"enable-nacm": true,
"groups": {
"group": [
{
"name": "admin",
"user-name": [
"admin"
]
}
]
},
"rule-list": [
{
"name": "admin-acl",
"group": [
"admin"
],
"rule": [
{
"name": "permit-all",
"module-name": "*",
"access-operations": "*",
"action": "permit",
"comment": "Allow 'admin' group complete access to all operations and data."
}
]
},
{
"name": "default-deny-all",
"group": [
"*"
],
"rule": [
{
"name": "deny-password-read",
"module-name": "ietf-system",
"path": "/ietf-system:system/authentication/user/password",
"access-operations": "*",
"action": "deny"
}
]
}
]
},
"ietf-netconf-server:netconf-server": {
"listen": {
"endpoints": {
"endpoint": [
{
"name": "default-ssh",
"ssh": {
"tcp-server-parameters": {
"local-address": "::"
},
"ssh-server-parameters": {
"server-identity": {
"host-key": [
{
"name": "default-key",
"public-key": {
"central-keystore-reference": "genkey"
}
}
]
}
}
}
}
]
}
}
},
"ietf-system:system": {
"hostname": "rpi4",
"ntp": {
"enabled": true,
"server": [
{
"name": "ntp.org",
"udp": {
"address": "pool.ntp.org"
},
"iburst": true
}
]
},
"authentication": {
"user": [
{
"name": "admin",
"password": "$factory$",
"infix-system:shell": "bash"
}
]
},
"infix-system:motd-banner": "Li0tLS0tLS0uCnwgIC4gLiAgfCBJbmZpeCAtLSBhIE5ldHdvcmsgT3BlcmF0aW5nIFN5c3RlbQp8LS4gdiAuLXwgaHR0cHM6Ly9rZXJuZWxraXQuZ2l0aHViLmlvCictJy0tLSctJwo="
},
"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": {
"infix-meta:version": "1.2"
},
"infix-services:mdns": {
"enabled": true
},
"infix-services:web": {
"enabled": true,
"console": {
"enabled": true
},
"netbrowse": {
"enabled": true
},
"restconf": {
"enabled": true
}
}
}
@@ -1,5 +0,0 @@
{
"eth0": {
"phy-detached-when-down": true
}
}
@@ -1,6 +0,0 @@
# Broadcom BCM2835 Watchdog timer
device /dev/watchdog0 {
timeout = 60
interval = 5
safe-exit = true
}
-3
View File
@@ -1,3 +0,0 @@
# CONFIG_MMC_PCI is not set
CONFIG_OF_OVERLAY_LIST="rpi-env infix-key"
# CONFIG_ENV_IS_IN_FAT is not set
-27
View File
@@ -1,27 +0,0 @@
/dts-v1/;
/plugin/;
&{/} {
config {
environment {
vendor = "infix";
preboot = "run ixpreboot";
ixbootdelay = "0.5";
bootdelay = "-2";
bootmenu_delay = "10";
boot_targets = "mmc1";
ethprime = "eth0";
bootcmd = "run ixboot";
ixpreboot = /incbin/("scripts/ixpreboot.sh");
ixbtn-devmode = "setenv dev_mode yes; echo Enabled";
ixbtn-factory = "echo \"No button available, use bootmenu\"";
ixfactory = /incbin/("scripts/ixfactory.sh");
ixboot = /incbin/("scripts/ixboot.sh");
ixbootslot = /incbin/("scripts/ixbootslot.sh");
ixprepblk = /incbin/("scripts/ixprepblk.sh");
ixprepdhcp = /incbin/("scripts/ixprepdhcp.sh");
};
};
};
+2 -2
View File
@@ -550,7 +550,7 @@ while [ "$1" != "" ]; do
;;
-m | --mount)
shift
mount="$mount --mount=$1"
mount="--mount=$1"
;;
--manual)
manual=true
@@ -696,7 +696,7 @@ case $cmd in
oci)
find $BUILTIN $DOWNLOADS -type f 2>/dev/null
;;
*)
*)
podman ps $all --format "{{.Names}}"
;;
esac
+2 -11
View File
@@ -17,23 +17,14 @@ endef
# U-Boot build tree. This will then be built in to the final U-Boot
# image's control DT via the CONFIG_DEVICE_TREE_INCLUDES option (see
# extras.config).
#
# Some platforms, most notably Raspberry Pi, load the device tree
# from the SPL, effectively overriding the built-in control DT.
# For that we bundle an overlay that can be included instead.
define UBOOT_PRE_BUILD_INSTALL_KEY
$(HOST_DIR)/bin/dtc -a 1024 <(echo '/dts-v1/; / { signature {}; };') \
>$(@D)/infix-key.dtb
$(HOST_DIR)/bin/dtc <(echo '/dts-v1/; / { signature {}; };') >$(@D)/infix-key.dtb
$(foreach key, \
$(call qstrip,$(TRUSTED_KEYS_DEVELOPMENT_PATH)) $(call qstrip,$(TRUSTED_KEYS_EXTRA_PATH)),\
$(call uboot-add-pubkey,$(key),$(@D)/infix-key.dtb))
$(HOST_DIR)/bin/dtc -I dtb -O dts \
<$(@D)/infix-key.dtb \
| sed -e 's:/dts-v[0-9]\+/;::' \
| tee $(@D)/arch/$(UBOOT_ARCH)/dts/infix-key.dtsi \
| sed -e '1i\/dts-v1/;\n/plugin/;\n' -e '/^$$/d' -e 's:/ {:\&{/} {:' \
>$(@D)/arch/$(UBOOT_ARCH)/dts/infix-key.dtso
| sed -e 's:/dts-v[0-9]\+/;::' >$(@D)/arch/$(UBOOT_ARCH)/dts/infix-key.dtsi
rm $(@D)/infix-key.dtb
endef
UBOOT_PRE_BUILD_HOOKS += UBOOT_PRE_BUILD_INSTALL_KEY
+1 -1
View File
@@ -27,7 +27,7 @@ BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.12.32"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.12.26"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/linux_defconfig"
BR2_LINUX_KERNEL_INSTALL_TARGET=y
+1 -1
View File
@@ -27,7 +27,7 @@ BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.12.32"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.12.26"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/linux_defconfig"
BR2_LINUX_KERNEL_INSTALL_TARGET=y
+1 -1
View File
@@ -29,7 +29,7 @@ BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image
BR2_ROOTFS_POST_SCRIPT_ARGS="-c $(BR2_EXTERNAL_INFIX_PATH)/board/aarch64/r2s/genimage.cfg"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.12.32"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.12.26"
BR2_LINUX_KERNEL_PATCH="$(BR2_EXTERNAL_INFIX_PATH)/board/aarch64/r2s/rk3328-nanopi-r2s-dts.patch"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/r2s/linux_defconfig"
-201
View File
@@ -1,201 +0,0 @@
BR2_aarch64=y
BR2_cortex_a72=y
BR2_ARM_FPU_VFPV4=y
BR2_TOOLCHAIN_EXTERNAL=y
BR2_TOOLCHAIN_EXTERNAL_BOOTLIN=y
BR2_TOOLCHAIN_EXTERNAL_GDB_SERVER_COPY=y
BR2_DL_DIR="${BR2_EXTERNAL_INFIX_PATH}/dl"
BR2_CCACHE=y
BR2_CCACHE_DIR="${BR2_EXTERNAL_INFIX_PATH}/.ccache"
BR2_GLOBAL_PATCH_DIR="board/raspberrypi/patches ${BR2_EXTERNAL_INFIX_PATH}/patches"
BR2_DOWNLOAD_FORCE_CHECK_HASHES=y
BR2_TARGET_GENERIC_HOSTNAME="infix"
BR2_TARGET_GENERIC_ISSUE="Infix by KernelKit"
BR2_INIT_FINIT=y
BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y
BR2_ROOTFS_DEVICE_TABLE="system/device_table.txt ${BR2_EXTERNAL_INFIX_PATH}/board/common/xattrs"
BR2_ROOTFS_MERGED_USR=y
# BR2_TARGET_ENABLE_ROOT_LOGIN is not set
BR2_SYSTEM_BIN_SH_BASH=y
BR2_TARGET_GENERIC_GETTY_PORT="@console"
BR2_TARGET_GENERIC_GETTY_TERM="xterm"
BR2_SYSTEM_DHCP="eth0"
BR2_SYSTEM_DEFAULT_PATH="/bin:/sbin:/usr/bin:/usr/sbin"
BR2_ENABLE_LOCALE_WHITELIST="C en_US en_CA C.UTF-8"
BR2_GENERATE_LOCALE="en_US en_CA C.UTF-8"
BR2_TARGET_TZ_INFO=y
BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/rootfs ${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/rpi/rootfs"
BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/rpi/post-build.sh"
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh ${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/rpi/post-image.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.12.32"
BR2_LINUX_KERNEL_PATCH="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/rpi/bcm2711-rpi-4-b-dts.patch"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/rpi/bcm2711_defconfig"
BR2_LINUX_KERNEL_DTS_SUPPORT=y
BR2_LINUX_KERNEL_INTREE_DTS_NAME="broadcom/bcm2711-rpi-4-b broadcom/bcm2711-rpi-400"
BR2_LINUX_KERNEL_DTB_KEEP_DIRNAME=y
BR2_LINUX_KERNEL_INSTALL_TARGET=y
BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y
BR2_PACKAGE_BUSYBOX_CONFIG="$(BR2_EXTERNAL_INFIX_PATH)/board/common/busybox_defconfig"
BR2_PACKAGE_XZ=y
BR2_PACKAGE_STRACE=y
BR2_PACKAGE_STRESS_NG=y
BR2_PACKAGE_JQ=y
BR2_PACKAGE_E2FSPROGS=y
BR2_PACKAGE_ARMBIAN_FIRMWARE=y
BR2_PACKAGE_ARMBIAN_FIRMWARE_AP6255=y
BR2_PACKAGE_BRCMFMAC_SDIO_FIRMWARE_RPI=y
BR2_PACKAGE_LINUX_FIRMWARE=y
BR2_PACKAGE_LINUX_FIRMWARE_BRCM_BCM43XX=y
BR2_PACKAGE_LINUX_FIRMWARE_BRCM_BCM43XXX=y
BR2_PACKAGE_LINUX_FIRMWARE_BRCM_BCM4366B1=y
BR2_PACKAGE_LINUX_FIRMWARE_BRCM_BCM4366C0=y
BR2_PACKAGE_RPI_FIRMWARE=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}/board/aarch64/rpi/config.txt"
BR2_PACKAGE_RPI_FIRMWARE_CMDLINE_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/rpi/cmdline.txt"
BR2_PACKAGE_DBUS_CXX=y
BR2_PACKAGE_DBUS_GLIB=y
BR2_PACKAGE_DBUS_TRIGGERD=y
BR2_PACKAGE_EUDEV_RULES_GEN=y
# BR2_PACKAGE_EUDEV_ENABLE_HWDB is not set
BR2_PACKAGE_EVEMU=y
BR2_PACKAGE_EVTEST=y
BR2_PACKAGE_GPTFDISK=y
BR2_PACKAGE_GPTFDISK_SGDISK=y
BR2_PACKAGE_INPUT_EVENT_DAEMON=y
BR2_PACKAGE_MDIO_TOOLS=y
BR2_PACKAGE_RNG_TOOLS=y
BR2_PACKAGE_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_UBOOT_TOOLS_FIT_CHECK_SIGN=y
BR2_PACKAGE_UBOOT_TOOLS_MKENVIMAGE=y
BR2_PACKAGE_PYTHON3=y
BR2_PACKAGE_PYTHON_GUNICORN=y
BR2_PACKAGE_LIBSSH_OPENSSL=y
BR2_PACKAGE_LIBSSH2=y
BR2_PACKAGE_LIBSSH2_OPENSSL=y
BR2_PACKAGE_LIBOPENSSL_BIN=y
BR2_PACKAGE_LIBINPUT=y
BR2_PACKAGE_LIBCURL_CURL=y
BR2_PACKAGE_NETOPEER2_CLI=y
BR2_PACKAGE_NSS_MDNS=y
BR2_PACKAGE_LINUX_PAM=y
BR2_PACKAGE_LIBPAM_RADIUS_AUTH=y
BR2_PACKAGE_ONIGURUMA=y
BR2_PACKAGE_AVAHI_DAEMON=y
BR2_PACKAGE_AVAHI_DEFAULT_SERVICES=y
BR2_PACKAGE_CHRONY=y
BR2_PACKAGE_CONNTRACK_TOOLS=y
BR2_PACKAGE_DNSMASQ=y
BR2_PACKAGE_ETHTOOL=y
BR2_PACKAGE_FPING=y
BR2_PACKAGE_FRR=y
BR2_PACKAGE_HOSTAPD=y
# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set
BR2_PACKAGE_IPROUTE2=y
BR2_PACKAGE_IPTABLES_NFTABLES=y
BR2_PACKAGE_IPUTILS=y
BR2_PACKAGE_IW=y
BR2_PACKAGE_LLDPD=y
BR2_PACKAGE_MSTPD=y
BR2_PACKAGE_NETCALC=y
BR2_PACKAGE_NETCAT_OPENBSD=y
BR2_PACKAGE_NETSNMP=y
BR2_PACKAGE_NFTABLES=y
BR2_PACKAGE_NGINX=y
BR2_PACKAGE_NGINX_HTTP_SSL_MODULE=y
BR2_PACKAGE_NGINX_HTTP_V2_MODULE=y
BR2_PACKAGE_NMAP=y
BR2_PACKAGE_NMAP_NCAT=y
BR2_PACKAGE_NMAP_NMAP=y
BR2_PACKAGE_NMAP_NPING=y
BR2_PACKAGE_OPENRESOLV=y
BR2_PACKAGE_OPENSSH=y
BR2_PACKAGE_SOCAT=y
BR2_PACKAGE_TCPDUMP=y
BR2_PACKAGE_TRACEROUTE=y
BR2_PACKAGE_ULOGD=y
BR2_PACKAGE_WHOIS=y
BR2_PACKAGE_WIRELESS_REGDB=y
BR2_PACKAGE_WIRELESS_TOOLS=y
BR2_PACKAGE_WPA_SUPPLICANT=y
BR2_PACKAGE_BASH_COMPLETION=y
BR2_PACKAGE_SUDO=y
BR2_PACKAGE_TTYD=y
BR2_PACKAGE_GETENT=y
BR2_PACKAGE_HTOP=y
BR2_PACKAGE_IRQBALANCE=y
BR2_PACKAGE_KMOD_TOOLS=y
BR2_PACKAGE_PWGEN=y
BR2_PACKAGE_RAUC=y
BR2_PACKAGE_RAUC_DBUS=y
BR2_PACKAGE_RAUC_GPT=y
BR2_PACKAGE_RAUC_NETWORK=y
BR2_PACKAGE_RAUC_JSON=y
BR2_PACKAGE_SYSKLOGD=y
BR2_PACKAGE_SYSKLOGD_LOGGER=y
BR2_PACKAGE_WATCHDOGD=y
BR2_PACKAGE_LESS=y
BR2_PACKAGE_MG=y
BR2_PACKAGE_NANO=y
BR2_TARGET_ROOTFS_SQUASHFS=y
# BR2_TARGET_ROOTFS_TAR is not set
BR2_TARGET_UBOOT=y
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)/board/aarch64/rpi/uboot/extras.config"
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)/board/aarch64/rpi/uboot/rpi-env.dtso"
BR2_PACKAGE_HOST_DOSFSTOOLS=y
BR2_PACKAGE_HOST_E2FSPROGS=y
BR2_PACKAGE_HOST_ENVIRONMENT_SETUP=y
BR2_PACKAGE_HOST_GENEXT2FS=y
BR2_PACKAGE_HOST_GENIMAGE=y
BR2_PACKAGE_HOST_KMOD_XZ=y
BR2_PACKAGE_HOST_MTOOLS=y
BR2_PACKAGE_HOST_RAUC=y
BR2_PACKAGE_HOST_UBOOT_TOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
INFIX_VENDOR_HOME="https://github.com/kernelkit"
INFIX_IMAGE_ID="${INFIX_ID}-rpi4"
INFIX_DESC="Infix is a Network Operating System based on Linux. It can be set up both as a switch, with offloading using switchdev, and a router with firewalling."
INFIX_HOME="https://github.com/kernelkit/infix/"
INFIX_DOC="https://github.com/kernelkit/infix/tree/main/doc"
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
BR2_PACKAGE_CONFD=y
BR2_PACKAGE_GENCERT=y
BR2_PACKAGE_STATD=y
BR2_PACKAGE_FACTORY=y
BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y
BR2_PACKAGE_FINIT_PLUGIN_HOOK_SCRIPTS=y
BR2_PACKAGE_FINIT_PLUGIN_MODULES_LOAD=y
BR2_PACKAGE_FINIT_PLUGIN_RTC=y
BR2_PACKAGE_FINIT_RTC_DATE="2024-11-04 10:54:00"
BR2_PACKAGE_FINIT_RTC_FILE="/var/lib/misc/rtc"
BR2_PACKAGE_FINIT_PLUGIN_TTY=y
BR2_PACKAGE_FINIT_PLUGIN_URANDOM=y
BR2_PACKAGE_IITO=y
BR2_PACKAGE_KEYACK=y
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
BR2_PACKAGE_LANDING=y
BR2_PACKAGE_LOWDOWN=y
BR2_PACKAGE_MCD=y
BR2_PACKAGE_MDNS_ALIAS=y
BR2_PACKAGE_NETBROWSE=y
BR2_PACKAGE_PODMAN=y
BR2_PACKAGE_PODMAN_DRIVER_BTRFS=y
BR2_PACKAGE_PODMAN_DRIVER_DEVICEMAPPER=y
BR2_PACKAGE_PODMAN_DRIVER_VFS=y
BR2_PACKAGE_SHOW=y
BR2_PACKAGE_TETRIS=y
BR2_PACKAGE_ROUSETTE=y
BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y
BR2_PACKAGE_HOST_PYTHON_YANGDOC=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
SDCARD_AUX=y
+1 -1
View File
@@ -26,7 +26,7 @@ BR2_ROOTFS_POST_BUILD_SCRIPT="board/qemu/x86_64/post-build.sh ${BR2_EXTERNAL_INF
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.12.32"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.12.26"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/x86_64/linux_defconfig"
BR2_LINUX_KERNEL_INSTALL_TARGET=y
+1 -1
View File
@@ -27,7 +27,7 @@ BR2_ROOTFS_POST_BUILD_SCRIPT="board/qemu/x86_64/post-build.sh ${BR2_EXTERNAL_INF
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.12.32"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.12.26"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/x86_64/linux_defconfig"
BR2_LINUX_KERNEL_INSTALL_TARGET=y
+3 -25
View File
@@ -3,36 +3,16 @@ Change Log
All notable changes to the project are documented in this file.
[v25.05.1][] - 2025-06-12
[v25.05.0][UNRELEASED]
-------------------------
### Changes
- Upgrade Linux kernel to 6.12.32 (LTS)
### Fixes
- Fix #1060: Restore of missing CLI commands, regression in Infix v25.05.0
[v25.05.0][] - 2025-05-27
-------------------------
### Changes
- Upgrade Buildroot to 2025.02.3 (LTS)
- Upgrade Linux kernel to 6.12.30 (LTS)
- Upgrade Linux kernel to 6.12.26 (LTS)
- Upgrade libyang to 3.12.2
- Upgrade sysrepo to 3.6.11
- Upgrade netopeer2 (NETCONF) to 2.4.1
- New hardware support: Raspberry Pi 4B (aarch64)
- Add documentation on Infix upgrading and downgrading, issue #1009
- Add HDMI and USB support for iMX8MP-evk
- Enforced strict format for LLDP destination MAC address:
- Only accepts colon-separated format: `01:80:C2:00:00:0E`
- Add `show lldp` command to show discovered neighbors per interface.
- Add configuration support for per-interface LLDP administrative status
### Fixes
- Fix containers with multiple mounts
- Correct description for LAG LACP modes
- Fix #1040: Add `mount` constraint for container config
[v25.04.0][] - 2025-04-30
@@ -145,7 +125,6 @@ All notable changes to the project are documented in this file.
- Add support for GRE/GRETAP tunnels
- Add support for STP/RSTP on bridges
- Add support for VXLAN tunnels
- Add support for configuring global LLDP `message-tx-interval`
### Fixes
@@ -1578,8 +1557,7 @@ 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.05.1...HEAD
[v25.05.1]: https://github.com/kernelkit/infix/compare/v25.05.0...v25.05.1
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v25.04.0...HEAD
[v25.05.0]: https://github.com/kernelkit/infix/compare/v25.04.0...v25.05.0
[v25.04.0]: https://github.com/kernelkit/infix/compare/v25.03.0...v25.04.0
[v25.03.0]: https://github.com/kernelkit/infix/compare/v25.02.0...v25.03.0
+1 -3
View File
@@ -63,7 +63,7 @@ bootloader's validation procedure, user configuration is kept to a
minimum. Two settings are available:
- **Boot order**: Since Infix maintains two copies of its software image,
and as some bootloaders support [netbooting][2], the order in which boot
and as some bootloaders support netbooting, the order in which boot
sources are considered can be configured. To select the active
source, use [RAUC][]:
@@ -352,5 +352,3 @@ If `var` is not available, Infix will still persist `/var/lib` using
[^1]: See [Upgrading procedures and boot
order](system.md#upgrade-procedures-and-boot-order) for
information on upgrading via CLI.
[2]: netboot.md
+1 -58
View File
@@ -46,7 +46,7 @@ admin@infix-c0-ff-ee:~$
## LLDP
Infix supports LLDP (IEEE 802.1AB). For a device with factory default
Infix supports LLDP (IEEE 802.1AB). For a device with factory default
settings, the link-local IPv6 address can be read from the Management
Address TLV using *tcpdump* or other sniffing tools[^1]:
@@ -131,10 +131,6 @@ tcpdump: listening on tap0, link-type EN10MB (Ethernet), snapshot length 262144
linux-pc:#
```
The following capabilities are available via NETCONF/RESTCONF or the Infix CLI.
### LLDP Enable/Disable
The LLDP service can be disabled using the following commands.
```
@@ -144,59 +140,6 @@ admin@infix-c0-ff-ee:/config/> leave
admin@infix-c0-ff-ee:/>
```
To reenable it from the CLI config mode:
```
admin@test-00-01-00:/config/> set lldp enabled
admin@test-00-01-00:/config/> leave
```
### LLDP Message Transmission Interval
By default, LLDP uses a `message-tx-interval` of 30 seconds, as defined
by the IEEE standard. Infix allows this value to be customized.
To change it using the CLI:
```
admin@test-00-01-00:/config/> set lldp message-tx-interval 1
admin@test-00-01-00:/config/> leave
```
### LLDP Administrative Status per Interface
Infix supports configuring the LLDP administrative status on a per-port
basis. The default mode is `tx-and-rx`, but the following options are
also supported:
- `rx-only` Receive LLDP packets only
- `tx-only` Transmit LLDP packets only
- `disabled` Disable LLDP on the interface
Example configuration:
```
admin@test-00-01-00:/config/> set lldp port e8 dest-mac-address 01:80:C2:00:00:0E admin-status disabled
admin@test-00-01-00:/config/> set lldp port e5 dest-mac-address 01:80:C2:00:00:0E admin-status rx-only
admin@test-00-01-00:/config/> set lldp port e6 dest-mac-address 01:80:C2:00:00:0E admin-status tx-only
admin@test-00-01-00:/config/> leave
```
> [!NOTE]
> The destination MAC address must be the standard LLDP multicast
> address: `01:80:C2:00:00:0E`.
### Displaying LLDP Neighbor Information
In CLI mode, Infix also provides a convenient `show lldp` command to
list LLDP neighbors detected on each interface:
```
admin@test-00-01-00:/> show lldp
INTERFACE REM-IDX TIME CHASSIS-ID PORT-ID
e5 1 902 00:a0:85:00:04:01 00:a0:85:00:04:07
e6 3 897 00:a0:85:00:03:01 00:a0:85:00:03:07
e8 2 901 00:a0:85:00:02:01 00:a0:85:00:02:05
```
## mDNS-SD
+17 -88
View File
@@ -357,45 +357,25 @@ booted from one partition, an `upgrade` will apply to the other
1. Download and unpack the release to install. Make the image *pkg*
bundle available at some URL[^10]
2. (Optional) Backup the startup configuration
3. Assume the unit has booted the `primary` image. Then running the
2. Assume the unit has booted the `primary` image. Then running the
`upgrade` command installs a new image on the `secondary`
partition
4. As part of a successful upgrade, the boot-order is implictly
3. As part of a successful upgrade, the boot-order is implictly
changed to boot the newly installed image
5. Reboot the unit
6. The unit now runs the new image. To upgrade the remaining partition
4. Reboot the unit
5. The unit now runs the new image. To upgrade the remaining partition
(`primary`), run the same upgrade command again, and (optionally)
reboot to verify the upgrade
> [!CAUTION]
> During boot (step 5), the unit may
> [migrate](#configuration-migration) the startup configuration for
> any syntax changes. It is therefore important that you make sure to
> upgrade the other partition as well after reboot, of course after
> having verified your setup.
> During boot, the unit may [migrate](#configuration-migration) the
> startup configuration for any syntax changes. It is therefore
> important that you make sure to upgrade the other partition as well
> after reboot, of course after having verified your setup.
The CLI example below shows steps 2-5.
The CLI example below shows steps 2-4.
*Backup startup configuration:* It is recommended to backup the
startup configuration before performing an upgrade. The backup is
useful if the upgrade fails, and makes a later
[downgrade](#downgrading-infix) smoother to conduct.
```
admin@example:/> dir /cfg
/cfg directory
backup/ ssl/ startup-config.cfg
admin@example:/> copy /cfg/startup-config.cfg /cfg/v25.01.0-startup-config.cfg
admin@example:/> dir /cfg
/cfg directory
backup/ ssl/ startup-config.cfg v25.01.0-startup-config.cfg
admin@example:/>
```
*Upgrade:* Here the image *pkg bundle* was made available via TFTP.
Upgrade: here the image *pkg bundle* was made available via TFTP.
```
admin@example:/> upgrade tftp://198.18.117.1/infix-aarch64-25.03.1.pkg
@@ -413,7 +393,7 @@ Installing `tftp://198.18.117.1/infix-aarch64-25.03.1.pkg` succeeded
admin@example:/>
```
*Reboot:* The unit will boot on the other partition, with the newly
Reboot: The unit will boot on the other partition, with the newly
installed image. The `Loading startup-config` step conducts migration
of startup configuration if applicable.
@@ -455,7 +435,7 @@ As shown, the *boot order* has been updated, so that *secondary* is
now the preferred boot source.
To upgrade the remaining partition (`primary`), run the `upgrade URL`
command again, and (optionally) reboot.
command again, and reboot.
### Configuration Migration
@@ -539,25 +519,8 @@ with the unit in *failure config*.
*Find the backup configuration file:*
Assume you have a backup startup config for the Infix version to
downgrade to (here Infix v25.01.0, config `version 1.4`).
The preferred approach is to use a startup configuration backed up
when running Infix v25.01.0 on the unit. See the section on [upgrading
Infix](#upgrading-infix) above for more information. In the example
below, there is a backup file available named
*v25.01.0-startup-config.cfg*
```
admin@example:/> dir /cfg
/cfg directory
backup/ ssl/ startup-config.cfg v25.01.0-startup-config.cfg
admin@example:/>
```
The alternative is to use a startup config implicitly backed up by the
system as part of [configuration migration](#configuration-migration).
Assume you have a backup startup config for the version to downgrade
to (here Infix v25.01.0, config `version 1.4`).
```
admin@example:/> dir /cfg/backup/
@@ -567,23 +530,6 @@ startup-config-1.4.cfg
admin@example:/>
```
> [!CAUTION] Using a backup configuration file stored when the unit
> was running the old version (e.g., v25.01.0-startup-config.cfg) is
> preferred. Although backup files stored due to configuration
> migration (e.g., startup-config-1.4.cfg) usually works too if the
> configuration file version (`1.4`) matches, there are
> situations when the system may fail to apply it as described below.
The *configuration file version* (`1.4`) is only incremented when
changes in YANG configuration syntax mandates it to handle
*upgrading*. Say the next Infix version includes a new feature
setting, it can still have version `1.4`, as upgrading to it would not
need migration. If a user then enables the new feature setting, the
new configuration will no longer be compatible with the previous *Infix
version*. A downgrade after enabling new features risks ending up with
the unit in *failure config*.
*Use `upgrade` command to downgrade:*
```
@@ -602,19 +548,6 @@ admin@example:/>
*Apply the backup configuration file:*
It is recommended to use a backup configuration file for the Infix version to
downgrade to, if there is one available.
```
admin@example:/> copy /cfg/v25.01.0-startup-config.cfg /cfg/startup-config.cfg
Overwrite existing file /cfg/startup-config.cfg (y/N)? y
admin@example:/>
```
An alternative is to use a backup file stored when the system
conducted a [configuration migration](#configuration-migration). See
the *caution* note above.
```
admin@example:/> copy /cfg/backup/startup-config-1.4.cfg /cfg/startup-config.cfg
Overwrite existing file /cfg/startup-config.cfg (y/N)? y
@@ -623,7 +556,8 @@ admin@example:/>
*Reboot:*
The unit will come up with the applied backup configuration.
The unit will come up with the applied backup configuration instead of
failure config.
```
admin@example:/> reboot
@@ -641,9 +575,6 @@ admin@example:/> reboot
Infix -- a Network Operating System v25.01.0 (ttyS0)
example login:
```
> [!NOTE]
> If the unit despite these measures ends up in *failure config*, see
> the next section for more information on how to recover.
#### Downgrading without applying a backup startup configuration
@@ -749,7 +680,7 @@ Continued configuration is done as with any unit after factory reset.
[3]: https://www.rfc-editor.org/rfc/rfc8341
[4]: https://chrony-project.org/doc/4.6.1/chronyc.html
[5]: https://github.com/kernelkit/infix/blob/main/src/confd/yang/confd/infix-system-software.yang
[6]: netboot.md
[6]: boot.md#system-configuration
[7]: introduction.md#system-boot
[8]: management.md#console-port
[^9]: In failure config, Infix puts all Ethernet ports as individual
@@ -757,5 +688,3 @@ Continued configuration is done as with any unit after factory reset.
using link local IPv6 addresses. This as an alternative to
connecting via a console port.
[^10]: Set up an FTP/TFTP/SFTP or HTTP/HTTPS server on the same LAN.
[11]: scripting.md#-backup-configuration-using-sysrepocfg-and-scp
+52 -1
View File
@@ -1,2 +1,53 @@
include $(BR2_EXTERNAL_INFIX_PATH)/package/board/ix-board.mk
define inner-ix-board
$(2)_VERSION = ix-board
$(2)_LICENSE = BSD-3-Clause
$(2)_LICENSE_FILES = LICENSE
$(2)_SITE_METHOD = local
$(2)_SITE = $$(BR2_EXTERNAL_INFIX_PATH)/src/board/$(1)
$(2)_REDISTRIBUTE = NO
# The kernel must be built first.
$(2)_DEPENDENCIES += \
linux \
$$(BR2_MAKE_HOST_DEPENDENCY)
# This is only defined in some infrastructures (e.g. autotools, cmake),
# but not in others (e.g. generic). So define it here as well.
$(2)_MAKE ?= $$(BR2_MAKE)
define $(2)_DTBS_BUILD
@$$(call MESSAGE,"Building device tree blob(s)")
$$(LINUX_MAKE_ENV) $$($$(PKG)_MAKE) \
-C $$(LINUX_DIR) \
$$(LINUX_MAKE_FLAGS) \
$$($(2)_DTB_MAKE_OPTS) \
PWD=$$(@D)/dts \
M=$$(@D)/dts \
modules
endef
$(2)_POST_BUILD_HOOKS += $(2)_DTBS_BUILD
define $(2)_DTBS_INSTALL_TARGET
@$$(call MESSAGE,"Installing device tree blob(s)")
$$(TARGET_MAKE_ENV) $$(TARGET_CONFIGURE_OPTS) $$($$(PKG)_MAKE) \
-f $$(BR2_EXTERNAL_INFIX_PATH)/package/board/dtb-inst.makefile \
-C $$(@D)/dts \
DESTDIR="$$(TARGET_DIR)" \
install
endef
$(2)_POST_INSTALL_TARGET_HOOKS += $(2)_DTBS_INSTALL_TARGET
define $(2)_OVERLAY_INSTALL_TARGET
@test -d $$(@D)/rootfs && \
$$(call MESSAGE,"Copying overlay") && \
$$(call SYSTEM_RSYNC,$$(@D)/rootfs,$(TARGET_DIR)) || \
true
endef
$(2)_POST_INSTALL_TARGET_HOOKS += $(2)_OVERLAY_INSTALL_TARGET
endef
ix-board = $(call inner-ix-board,$(pkgname),$(call UPPERCASE,$(pkgname)))
include $(sort $(wildcard $(BR2_EXTERNAL_INFIX_PATH)/package/board/*/*.mk))
@@ -20,26 +20,6 @@ define FREESCALE_IMX8MP_EVK_LINUX_CONFIG_FIXUPS
$(call KCONFIG_ENABLE_OPT,CONFIG_INTERCONNECT_IMX)
$(call KCONFIG_ENABLE_OPT,CONFIG_INTERCONNECT_IMX8MP)
$(call KCONFIG_ENABLE_OPT,CONFIG_REALTEK_PHY)
# For X
$(call KCONFIG_ENABLE_OPT,CONFIG_DRM)
$(call KCONFIG_ENABLE_OPT,CONFIG_DRM_ETNAVIV)
$(call KCONFIG_ENABLE_OPT,CONFIG_DRM_IMX8MP_DW_HDMI_BRIDGE)
$(call KCONFIG_ENABLE_OPT,CONFIG_PHY_FSL_SAMSUNG_HDMI_PHY)
$(call KCONFIG_ENABLE_OPT,CONFIG_DRM_IMX8MP_HDMI_PVI)
$(call KCONFIG_ENABLE_OPT,CONFIG_DRM_IMX_LCDIF)
$(call KCONFIG_ENABLE_OPT,CONFIG_INPUT_MOUSE)
$(call KCONFIG_ENABLE_OPT,CONFIG_INPUT_MOUSEDEV)
$(call KCONFIG_ENABLE_OPT,CONFIG_HID_GENERIC)
# For USB
$(call KCONFIG_DISABLE_OPT,CONFIG_USB)
$(call KCONFIG_ENABLE_OPT,CONFIG_USB)
$(call KCONFIG_ENABLE_OPT,CONFIG_USB_DWC3)
$(call KCONFIG_DISABLE_OPT,CONFIG_USB_DWC3_GADGET)
$(call KCONFIG_ENABLE_OPT,CONFIG_USB_DWC3_HOST)
$(call KCONFIG_ENABLE_OPT,CONFIG_ARM_IMX_BUS_DEVFREQ)
$(call KCONFIG_ENABLE_OPT,CONFIG_TYPEC_TCPCI)
$(call KCONFIG_ENABLE_OPT,CONFIG_TYPEC_SWITCH_GPIO)
endef
$(eval $(ix-board))
-51
View File
@@ -1,51 +0,0 @@
define inner-ix-board
$(2)_VERSION = ix-board
$(2)_LICENSE = BSD-3-Clause
$(2)_LICENSE_FILES = LICENSE
$(2)_SITE_METHOD = local
$(2)_SITE = $$(BR2_EXTERNAL_INFIX_PATH)/src/board/$(1)
$(2)_REDISTRIBUTE = NO
# The kernel must be built first.
$(2)_DEPENDENCIES += \
linux \
$$(BR2_MAKE_HOST_DEPENDENCY)
# This is only defined in some infrastructures (e.g. autotools, cmake),
# but not in others (e.g. generic). So define it here as well.
$(2)_MAKE ?= $$(BR2_MAKE)
define $(2)_DTBS_BUILD
@$$(call MESSAGE,"Building device tree blob(s)")
$$(LINUX_MAKE_ENV) $$($$(PKG)_MAKE) \
-C $$(LINUX_DIR) \
$$(LINUX_MAKE_FLAGS) \
$$($(2)_DTB_MAKE_OPTS) \
PWD=$$(@D)/dts \
M=$$(@D)/dts \
modules
endef
$(2)_POST_BUILD_HOOKS += $(2)_DTBS_BUILD
define $(2)_DTBS_INSTALL_TARGET
@$$(call MESSAGE,"Installing device tree blob(s)")
$$(TARGET_MAKE_ENV) $$(TARGET_CONFIGURE_OPTS) $$($$(PKG)_MAKE) \
-f $$(BR2_EXTERNAL_INFIX_PATH)/package/board/dtb-inst.makefile \
-C $$(@D)/dts \
DESTDIR="$$(TARGET_DIR)" \
install
endef
$(2)_POST_INSTALL_TARGET_HOOKS += $(2)_DTBS_INSTALL_TARGET
define $(2)_OVERLAY_INSTALL_TARGET
@test -d $$(@D)/rootfs && \
$$(call MESSAGE,"Copying overlay") && \
$$(call SYSTEM_RSYNC,$$(@D)/rootfs,$(TARGET_DIR)) || \
true
endef
$(2)_POST_INSTALL_TARGET_HOOKS += $(2)_OVERLAY_INSTALL_TARGET
endef
ix-board = $(call inner-ix-board,$(pkgname),$(call UPPERCASE,$(pkgname)))
+7 -19
View File
@@ -70,34 +70,22 @@ define CONFD_INSTALL_YANG_MODULES_CONTAINERS
endef
endif
# PER_PACKAGE_DIR
# Since the last package in the dependency chain that runs sysrepoctl is confd, we need to
# manually copy the *real* content here from host-sysrepo.
ifeq ($(BR2_PER_PACKAGE_DIRECTORIES),y)
define CONFD_INSTALL_IN_ROMFS
cp -a $(PER_PACKAGE_DIR)/host-sysrepo/target/etc/sysrepo/* $(PER_PACKAGE_DIR)/confd/target/etc/sysrepo/
define CONFD_PERMISSIONS
/etc/sysrepo/data/ r 660 root sys-cli - - - - -
/etc/sysrepo/data d 770 root sys-cli - - - - -
endef
endif
# PER_PACKAGE_DIR
# Need to do some special stuff if using per-packet (parallel) since sysrepo install the submodules in
# $(PER_PACKAGE_DIR)/host-sysrepo/target/etc/sysrepo/ but $(PER_PACKAGE_DIR)/confd/target/etc/sysrepo/ contains remains
# of other packets that have installed its models (netopeer2), we want the result in $(PER_PACKAGE_DIR)/host-sysrepo/target/etc/sysrepo/
define CONFD_EMPTY_SYSREPO
rm -rf $(TARGET_DIR)/etc/sysrepo/*
if [ "$(BR2_PER_PACKAGE_DIRECTORIES)" = "y" ]; then \
rm -rf $(PER_PACKAGE_DIR)/host-sysrepo/target/etc/sysrepo/* $(PER_PACKAGE_DIR)/confd/target/etc/sysrepo/*; \
fi
rm -rf $(TARGET_DIR)/etc/sysrepo/data/
endef
define CONFD_CLEANUP
rm -f /dev/shm/$(CONFD_SYSREPO_SHM_PREFIX)*
endef
CONFD_PRE_BUILD_HOOKS += CONFD_EMPTY_SYSREPO
CONFD_PRE_BUILD_HOOKS += CONFD_CLEANUP
CONFD_PRE_INSTALL_TARGET_HOOKS += CONFD_EMPTY_SYSREPO
CONFD_PRE_INSTALL_TARGET_HOOKS += CONFD_CLEANUP
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_EXTRA
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_YANG_MODULES
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_YANG_MODULES_CONTAINERS
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_IN_ROMFS
CONFD_TARGET_FINALIZE_HOOKS += CONFD_CLEANUP
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_CLEANUP
$(eval $(autotools-package))
-1
View File
@@ -11,7 +11,6 @@ LANDING_LICENSE = ISC
LANDING_LICENSE_FILES = LICENSE
define LANDING_INSTALL_TARGET_CMDS
mkdir -p $(TARGET_DIR)/usr/html/
cp $(@D)/*.html $(TARGET_DIR)/usr/html/
cp $(@D)/*.png $(TARGET_DIR)/usr/html/
endef
-27
View File
@@ -1,27 +0,0 @@
diff -urN lowdown-VERSION_1_0_2.orig/configure lowdown-VERSION_1_0_2/configure
--- lowdown-VERSION_1_0_2.orig/configure 2025-03-21 12:58:06.151106271 +0000
+++ lowdown-VERSION_1_0_2/configure 2025-03-21 13:20:20.649825864 +0000
@@ -61,12 +61,7 @@
MAKE_FLAGS=""
-if [ -n "${MAKELEVEL}" ]; then
- if [ "${MAKELEVEL}" -gt 0 ] ; then
- MAKE_FLAGS="--no-print-directory"
- echo "all:" | make ${MAKE_FLAGS} -sf - 2>/dev/null || MAKE_FLAGS=""
- fi
-fi
+MAKE_FLAGS="--no-print-directory"
if [ -n "$MAKE_FLAGS" ]; then
echo "GNU submake detected: using --no-print-directory" 1>&2
@@ -79,9 +74,6 @@
# in.
#----------------------------------------------------------------------
-AR=`printf "all:\\n\\t@echo \\\$(AR)\\n" | make ${MAKE_FLAGS} -sf -`
-CC=`printf "all:\\n\\t@echo \\\$(CC)\\n" | make ${MAKE_FLAGS} -sf -`
-CFLAGS=`printf "all:\\n\\t@echo \\\$(CFLAGS)\\n" | make ${MAKE_FLAGS} -sf -`
CFLAGS="${CFLAGS} -g -W -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes"
CFLAGS="${CFLAGS} -Wwrite-strings -Wno-unused-parameter"
LDLIBS=
+1 -1
View File
@@ -9,7 +9,7 @@ NGHTTP2_ASIO_SITE = https://github.com/kernelkit/nghttp2-asio.git
NGHTTP2_ASIO_SITE_METHOD = git
NGHTTP2_ASIO_LICENSE = MIT
NGHTTP2_ASIO_LICENSE_FILES = COPYING
NGHTTP2_ASIO_DEPENDENCIES = boost nghttp2 openssl
NGHTTP2_ASIO_DEPENDENCIES = boost nghttp2
NGHTTP2_ASIO_INSTALL_STAGING = YES
NGHTTP2_ASIO_AUTOGEN = YES
NGHTTP2_ASIO_AUTORECONF = YES
+2 -2
View File
@@ -10,8 +10,8 @@ PYTHON_LIBYANG_SITE = https://files.pythonhosted.org/packages/91/2e/ff13ee16c874
PYTHON_LIBYANG_SETUP_TYPE = setuptools
PYTHON_LIBYANG_LICENSE = MIT
PYTHON_LIBYANG_LICENSE_FILES = LICENSE
PYTHON_LIBYANG_DEPENDENCIES = python-cython python-cffi libyang
HOST_PYTHON_LIBYANG_DEPENDENCIES = host-python-cython host-python-cffi host-libyang
PYTHON_LIBYANG_DEPENDENCIES = python-cython python-cffi
HOST_PYTHON_LIBYANG_DEPENDENCIES = host-python-cython host-python-cffi
$(eval $(python-package))
$(eval $(host-python-package))
@@ -1,4 +1,4 @@
From 392735fcb41b303b6dbe3517fab9ba734ff2e288 Mon Sep 17 00:00:00 2001
From dfd52e38ab402822aa4011039efa00e9d183d6a6 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Tue, 5 Mar 2024 09:41:46 +0100
Subject: [PATCH 1/2] iplink_bridge: add mcast_flood_always bridge option
@@ -17,7 +17,7 @@ Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
3 files changed, 32 insertions(+)
diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
index c206cf6..84ef423 100644
index c206cf6d..84ef4233 100644
--- a/include/uapi/linux/if_bridge.h
+++ b/include/uapi/linux/if_bridge.h
@@ -830,6 +830,7 @@ enum br_boolopt_id {
@@ -29,7 +29,7 @@ index c206cf6..84ef423 100644
};
diff --git a/ip/iplink_bridge.c b/ip/iplink_bridge.c
index 1fe8955..d4f2c80 100644
index f01ffe15..2a489b7b 100644
--- a/ip/iplink_bridge.c
+++ b/ip/iplink_bridge.c
@@ -41,6 +41,7 @@ static void print_explain(FILE *f)
@@ -80,10 +80,10 @@ index 1fe8955..d4f2c80 100644
if (tb[IFLA_BR_MCAST_ROUTER])
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
index efb6248..2308835 100644
index eabca490..ba0a5304 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -1712,6 +1712,8 @@ the following additional arguments are supported:
@@ -1703,6 +1703,8 @@ the following additional arguments are supported:
] [
.BI vlan_stats_per_port " VLAN_STATS_PER_PORT "
] [
@@ -92,7 +92,7 @@ index efb6248..2308835 100644
.BI mcast_snooping " MULTICAST_SNOOPING "
] [
.BI mcast_vlan_snooping " MULTICAST_VLAN_SNOOPING "
@@ -1860,6 +1862,16 @@ or disable
@@ -1851,6 +1853,16 @@ or disable
.RI ( VLAN_STATS_PER_PORT " == 0) "
per-VLAN per-port stats accounting. Can be changed only when there are no port VLANs configured.
@@ -1,8 +1,9 @@
From fcbddd99782709b8bb8b028b580eaaf750431502 Mon Sep 17 00:00:00 2001
From 0c35a5314291a78047df920779fc55412e96c135 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 12 Mar 2024 10:27:24 +0100
Subject: [PATCH 01/27] [FIX] net: dsa: mv88e6xxx: Fix timeout on waiting for
PPU on 6393X
Organization: Wires
In a multi-chip setup, delays of up to 750ms are observed before the
device (6393X) signals completion of PPU initialization (Global 1,
@@ -1,8 +1,9 @@
From b5056d553c2f1493b66a1c7c456b74fb87eb6f9d Mon Sep 17 00:00:00 2001
From a4d558c209f19f4d1e18f7e0ed8996102b7f875d Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 27 Mar 2024 15:52:43 +0100
Subject: [PATCH 02/27] net: dsa: mv88e6xxx: Improve indirect register access
perf on 6393
Organization: Wires
When operating in multi-chip mode, the 6393 family maps a subset of
commonly used global registers to the outermost address space (in
@@ -1,8 +1,9 @@
From 11d35cf88242ab4c896baadced08c92385264cf5 Mon Sep 17 00:00:00 2001
From 57b19d8263f232d6b3d418fd7a4a71d1f00567bd Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Mon, 22 Apr 2024 23:18:01 +0200
Subject: [PATCH 03/27] net: dsa: mv88e6xxx: Honor ports being managed via
in-band-status
Organization: Wires
Keep all link parameters in their unforced states when the port is
declared as being managed via in-band-status, and let the MAC
@@ -1,8 +1,9 @@
From a975aade77741273d2531e52de5163ed83dda411 Mon Sep 17 00:00:00 2001
From 8c83473996a0830e9d3f74792694de575d1ad6f4 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 24 Apr 2024 22:41:04 +0200
Subject: [PATCH 04/27] net: dsa: mv88e6xxx: Limit rsvd2cpu policy to user
ports on 6393X
Organization: Wires
For packets with a DA in the IEEE reserved L2 group range, originating
from a CPU, forward it as normal, rather than classifying it as
@@ -1,7 +1,8 @@
From 3ec7b214fc24eb0590517eb2e32fcc55e1ddcd43 Mon Sep 17 00:00:00 2001
From ec095ae1520437c6ba73c354c63f11114b69ee5e Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 16 Nov 2023 19:44:32 +0100
Subject: [PATCH 05/27] net: dsa: mv88e6xxx: Add LED infrastructure
Organization: Wires
Parse DT for LEDs and register them for devices that support it,
though no actual implementations exist yet.
@@ -1,7 +1,8 @@
From 245031376473a5da1aa58d2d94cec8b860fa4094 Mon Sep 17 00:00:00 2001
From 4c49605ae3cced0e0358a1b485ceb49c40e43de8 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 16 Nov 2023 21:59:35 +0100
Subject: [PATCH 06/27] net: dsa: mv88e6xxx: Add LED support for 6393X
Organization: Wires
Trigger support:
- "none"
@@ -1,8 +1,9 @@
From 43f2078a012891e34673b6cd5f59d8a6d761a49a Mon Sep 17 00:00:00 2001
From c4eb35a6767bd6652c8c947da1f069cba2c6ed16 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 28 May 2024 10:38:42 +0200
Subject: [PATCH 07/27] net: dsa: tag_dsa: Use tag priority as initial
skb->priority
Organization: Wires
Use the 3-bit priority field from the DSA tag as the initial packet
priority on ingress to the CPU.
@@ -1,8 +1,9 @@
From b461a4b81f08577cb932405712e9b828be69ae2c Mon Sep 17 00:00:00 2001
From 7be2376fd4e698d5b123c36d67c45119b6c4860f Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 16 Jan 2024 16:00:55 +0100
Subject: [PATCH 08/27] net: dsa: Support MDB memberships whose L2 addresses
overlap
Organization: Wires
Multiple IP multicast groups (32 for v4, 2^80 for v6) map to the same
L2 address. This means that switchdev drivers may receive multiple MDB
@@ -1,7 +1,8 @@
From b7685c7c95324e6cbd5b74343b065b2fd6dd7033 Mon Sep 17 00:00:00 2001
From 69b036e535b1ee6f62ee965d6ffbd559be954a3e Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 21 Mar 2024 19:12:15 +0100
Subject: [PATCH 09/27] net: dsa: Support EtherType based priority overrides
Organization: Wires
---
include/net/dsa.h | 4 ++++
@@ -1,8 +1,9 @@
From 88b342d0c8d46b8b51fdebde1f89c74cbae93801 Mon Sep 17 00:00:00 2001
From 6935453500d2083106b9809487d5a6e97fdd39e7 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Fri, 22 Mar 2024 16:15:43 +0100
Subject: [PATCH 10/27] net: dsa: mv88e6xxx: Support EtherType based priority
overrides
Organization: Wires
---
drivers/net/dsa/mv88e6xxx/chip.c | 64 +++++++++++++++++++++++++++++
@@ -1,7 +1,8 @@
From cc93e5f94d1c0f5c459f4ce479bb3e51a636ea3e Mon Sep 17 00:00:00 2001
From e1068697ab45bbf67412c0a1aa07769c2a077efc Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 28 May 2024 11:04:22 +0200
Subject: [PATCH 11/27] net: dsa: mv88e6xxx: Add mqprio qdisc support
Organization: Wires
Add support for attaching mqprio qdisc's to mv88e6xxx ports and use
the packet's traffic class as the outgoing priority when no PCP bits
@@ -1,8 +1,9 @@
From eaf7cdbe2d1f8f4c1a7e3a9da9af8005224564d6 Mon Sep 17 00:00:00 2001
From 47de3a790395796d7717bfc81b3c6bc6ffb683b5 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 29 May 2024 13:20:41 +0200
Subject: [PATCH 12/27] net: dsa: mv88e6xxx: Use VLAN prio over IP when both
are available
Organization: Wires
Switch the priority sourcing precdence to prefer VLAN PCP over IP
DSCP, when both are available.
@@ -1,8 +1,9 @@
From 072e5f29fda05c64ef460c6f22d341c1a15bf0b8 Mon Sep 17 00:00:00 2001
From 75fa8486867714f1c12fd3d9bf40b8201adecdae Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 26 Nov 2024 19:45:59 +0100
Subject: [PATCH 13/27] [FIX] net: dsa: mv88e6xxx: Trap locally terminated
VLANs
Organization: Wires
Before this change, in a setup like the following, packets assigned to
VLAN 10 were forwarded between the switch ports, even though the
@@ -1,8 +1,9 @@
From d60964c1fcffda523339c6dc920a0d9bb47c2dc5 Mon Sep 17 00:00:00 2001
From a0639986c74ca3cd4e57f2f5d50639c83c595115 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 19 Sep 2023 18:38:10 +0200
Subject: [PATCH 14/27] net: phy: marvell10g: Support firmware loading on
88X3310
Organization: Wires
When probing, if a device is waiting for firmware to be loaded into
its RAM, ask userspace for the binary and load it over XMDIO.
@@ -1,8 +1,9 @@
From b3f76049e4f7aa89f9bbc345d7d512ad4623a431 Mon Sep 17 00:00:00 2001
From 968b1126891d9e18da8f82fa54d43aaebf519bfb Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 21 Nov 2023 20:15:24 +0100
Subject: [PATCH 15/27] net: phy: marvell10g: Fix power-up when strapped to
start powered down
Organization: Wires
On devices which are hardware strapped to start powered down (PDSTATE
== 1), make sure that we clear the power-down bit on all units
@@ -1,7 +1,8 @@
From b3e8ff6144d695ddd6209bf2c83e709a307e53ad Mon Sep 17 00:00:00 2001
From 44175ca9f0b20e7ad959054c51d6c685cb9f9586 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 15 Nov 2023 20:58:42 +0100
Subject: [PATCH 16/27] net: phy: marvell10g: Add LED support for 88X3310
Organization: Wires
Pickup the LEDs from the state in which the hardware reset or
bootloader left them, but also support further configuration via
@@ -1,8 +1,9 @@
From 92de10bbe084fb2744e3fa487bc0b4a85595ccf8 Mon Sep 17 00:00:00 2001
From aa25b267d951e8052f4bc314e48ea427f2429891 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 12 Dec 2023 09:51:05 +0100
Subject: [PATCH 17/27] net: phy: marvell10g: Support LEDs tied to a single
media side
Organization: Wires
In a combo-port setup, i.e. where both the copper and fiber interface
are available to the user, the LEDs may be physically located either
@@ -1,7 +1,8 @@
From e4d37c329a06d914ad7c49f9230804eb2f02a310 Mon Sep 17 00:00:00 2001
From e551a59c1848d1e1731fc80727a0d145f22787b0 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 27 Mar 2024 10:10:19 +0100
Subject: [PATCH 18/27] net: phy: Do not resume PHY when attaching
Organization: Wires
The PHY should not start negotiating with its link-partner until
explicitly instructed to do so.
@@ -1,8 +1,9 @@
From 6c543747d8b5611b84041376fa2299944fb60ab4 Mon Sep 17 00:00:00 2001
From f7974affbd2493316b47be12e1b375f531ccbeb1 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 4 Mar 2024 16:47:28 +0100
Subject: [PATCH 19/27] net: bridge: avoid classifying unknown multicast as
mrouters_only
Organization: Wires
Unknown multicast, MAC/IPv4/IPv6, should always be flooded according to
the per-port mcast_flood setting, as well as to detected and configured
@@ -188,7 +189,7 @@ index b2ae0d2434d2..3137c1fcfc6a 100644
ipv6_addr_is_all_snoopers(&ipv6_hdr(skb)->daddr))
br_ip6_multicast_mrd_rcv(brmctx, pmctx, skb);
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index df502cc1191c..b456cf9ec1cc 100644
index 041f6e571a20..40651b07df94 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -483,6 +483,7 @@ enum net_bridge_opts {
@@ -199,7 +200,7 @@ index df502cc1191c..b456cf9ec1cc 100644
};
struct net_bridge {
@@ -887,8 +888,8 @@ void br_forward(const struct net_bridge_port *to, struct sk_buff *skb,
@@ -886,8 +887,8 @@ void br_forward(const struct net_bridge_port *to, struct sk_buff *skb,
bool local_rcv, bool local_orig);
int br_forward_finish(struct net *net, struct sock *sk, struct sk_buff *skb);
void br_flood(struct net_bridge *br, struct sk_buff *skb,
@@ -210,7 +211,7 @@ index df502cc1191c..b456cf9ec1cc 100644
/* return true if both source port and dest port are isolated */
static inline bool br_skb_isolated(const struct net_bridge_port *to,
@@ -1409,6 +1410,19 @@ static inline void br_multicast_flood(struct net_bridge_mdb_entry *mdst,
@@ -1408,6 +1409,19 @@ static inline void br_multicast_flood(struct net_bridge_mdb_entry *mdst,
{
}
@@ -1,8 +1,9 @@
From 2a32b5fa3c5a1eccba292572eea1c092b4dd5fc7 Mon Sep 17 00:00:00 2001
From 95d58304a71fd93d6096db629abce24bf84ea510 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Tue, 5 Mar 2024 06:44:41 +0100
Subject: [PATCH 20/27] net: bridge: Ignore router ports when forwarding L2
multicast
Organization: Wires
Multicast router ports are either statically configured or learned from
control protocol traffic (IGMP/MLD/PIM). These protocols regulate IP
@@ -16,10 +17,10 @@ Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index b456cf9ec1cc..aad99a27d968 100644
index 40651b07df94..e90b4f5cab76 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -1087,7 +1087,10 @@ br_multicast_get_first_rport_node(struct net_bridge_mcast *brmctx,
@@ -1086,7 +1086,10 @@ br_multicast_get_first_rport_node(struct net_bridge_mcast *brmctx,
if (skb->protocol == htons(ETH_P_IPV6))
return rcu_dereference(hlist_first_rcu(&brmctx->ip6_mc_router_list));
#endif
@@ -1,8 +1,9 @@
From d8e5e7cef63d5eba6ef2c9e4f1f2cec359b71019 Mon Sep 17 00:00:00 2001
From 044c9d6d96738f24849180f06d0a3d19861fbb73 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Thu, 4 Apr 2024 16:36:30 +0200
Subject: [PATCH 21/27] net: bridge: drop delay for applying strict multicast
filtering
Organization: Wires
This *local* patch drops the initial delay before applying strict multicast
filtering, introduced in [1] and recently updated in [2].
@@ -163,7 +164,7 @@ index 3137c1fcfc6a..34be07a1fd00 100644
#endif
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index aad99a27d968..ee8c2268ab5a 100644
index e90b4f5cab76..73b78c594564 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -78,7 +78,6 @@ struct bridge_mcast_own_query {
@@ -174,7 +175,7 @@ index aad99a27d968..ee8c2268ab5a 100644
};
/* selected querier */
@@ -1165,8 +1164,7 @@ __br_multicast_querier_exists(struct net_bridge_mcast *brmctx,
@@ -1164,8 +1163,7 @@ __br_multicast_querier_exists(struct net_bridge_mcast *brmctx,
own_querier_enabled = false;
}
@@ -1,8 +1,9 @@
From 9a1600de341da6d7e5b4294040f9b9bb1dbaf4c2 Mon Sep 17 00:00:00 2001
From f3f893da3380e7faf14b068c4490236d7102e52f Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 16 May 2024 14:51:54 +0200
Subject: [PATCH 22/27] net: bridge: Differentiate MDB additions from
modifications
Organization: Wires
Before this change, the reception of an IGMPv3 report (and analogously
for MLDv2) that adds a new group, would trigger two MDB RTM_NEWMDB
@@ -40,7 +41,7 @@ index db7254d52d93..63508279df47 100644
RTM_NEWNSID = 88,
#define RTM_NEWNSID RTM_NEWNSID
diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c
index 7e1ad229e133..3b1873e7c499 100644
index 1a52a0bca086..d5757ab72d2f 100644
--- a/net/bridge/br_mdb.c
+++ b/net/bridge/br_mdb.c
@@ -734,7 +734,7 @@ static int br_mdb_replace_group_sg(const struct br_mdb_config *cfg,
@@ -1,8 +1,9 @@
From 0c877e451f0c7b722ad5d230ea1caab0967c1dad Mon Sep 17 00:00:00 2001
From fd9bccb249ef2768b567a5ae658f1d5f2083888e Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Fri, 24 Nov 2023 23:29:55 +0100
Subject: [PATCH 23/27] nvmem: layouts: onie-tlv: Let device probe even when
TLV is invalid
Organization: Wires
Before this change, probing an NVMEM device, expected to contain a
valid TLV, would fail if it had not been provisioned yet. But an
@@ -1,7 +1,8 @@
From 97cf0cdd2066192002da814883dc0bfff423a7ff Mon Sep 17 00:00:00 2001
From b9729c330f866285cb96131d0aa28f3f70f2629b Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 29 Apr 2024 15:14:51 +0200
Subject: [PATCH 24/27] usb: core: adjust log level for unauthorized devices
Organization: Wires
The fact that a USB device currently is not authorized is not an error,
so let's adjust the log level so these messages slip below radar for the
@@ -1,8 +1,9 @@
From 2a0b03f9e4d789a36627a0798542b265be075b97 Mon Sep 17 00:00:00 2001
From 7ba5eea475b969ec5c1827a76b7dc714b551f6ad Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Thu, 16 Jan 2025 12:35:12 +0100
Subject: [PATCH 25/27] net: dsa: mv88e6xxx: collapse disabled state into
blocking
Organization: Wires
This patch changes the behavior of switchcore ports wrt. the port state.
Instead of disabling the port, the driver now treats the disabled state
@@ -1,8 +1,9 @@
From 856ee833fe803bcda382c0ddd5af5dfe1f29add5 Mon Sep 17 00:00:00 2001
From a661d6d7d362ded9ec2730fcb3b8fb508841ea84 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 12 Feb 2025 22:03:14 +0100
Subject: [PATCH 26/27] net: dsa: mv88e6xxx: Only activate LAG offloading when
bridged
Organization: Wires
The current port isolation scheme for mv88e6xxx is detailed here:
https://lore.kernel.org/netdev/20220203101657.990241-1-tobias@waldekranz.com/
@@ -1,8 +1,9 @@
From f5bea4bc63d8c77ba4268f53acadde1b7fbd384f Mon Sep 17 00:00:00 2001
From 47be565408de02e2ab973d0b05bf88826d2e3510 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Sun, 11 Aug 2024 11:27:35 +0200
Subject: [PATCH 27/27] net: usb: r8152: add r8153b support for link/activity
LEDs
Organization: Wires
This patch adds support for the link/activity LEDs on the NanoPi R2S
and OrangePi R1 Plus.
@@ -18,7 +19,7 @@ Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
1 file changed, 8 insertions(+)
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 2cab046749a9..c9947ad320ff 100644
index 96fa3857d8e2..cddb025aa56b 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -41,6 +41,11 @@
+1 -1
View File
@@ -1,2 +1,2 @@
# Calculated with ../utils/kernel-refresh.sh
sha256 a9b020721778384507010177d3929e7d4058f7f6120f05a99d56b5c5c0346a70 linux-6.12.32.tar.xz
sha256 402de222c7425893c38102ddd53d2b602c74c2eabcf6631bb0791089c05e3bca linux-6.12.26.tar.xz
@@ -1,109 +1,6 @@
#include <arm64/freescale/imx8mp-evk.dts>
#include <dt-bindings/usb/pd.h>
&usb3_phy0 {
status = "okay";
};
&iomuxc {
pinctrl_typec_mux: typec1muxgrp {
fsl,pins = <
MX8MP_IOMUXC_SAI1_MCLK__GPIO4_IO20 0x16
>;
};
pinctrl_typec: typec1grp {
fsl,pins = <
MX8MP_IOMUXC_SAI1_TXD7__GPIO4_IO19 0x1c4
>;
};
};
&i2c2 {
ptn5110: tcpc@50 {
compatible = "nxp,ptn5110";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_typec>;
reg = <0x50>;
interrupt-parent = <&gpio4>;
interrupts = <19 8>;
port {
typec_dr_sw: endpoint {
remote-endpoint = <&usb3_drd_sw>;
};
};
usb_con: connector {
compatible = "usb-c-connector";
label = "USB-C";
power-role = "dual";
data-role = "dual";
try-power-role = "sink";
source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)
PDO_VAR(5000, 20000, 3000)>;
op-sink-microwatt = <15000000>;
self-powered;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@1 {
reg = <1>;
typec_con_ss: endpoint {
remote-endpoint = <&usb3_data_ss>;
};
};
};
};
};
};
&usb3_phy0 {
fsl,phy-tx-vref-tune = <0xe>;
fsl,phy-tx-preemp-amp-tune = <3>;
fsl,phy-tx-vboost-level = <5>;
fsl,phy-comp-dis-tune = <7>;
fsl,pcs-tx-deemph-3p5db = <0x21>;
fsl,phy-pcs-tx-swing-full = <0x7f>;
status = "okay";
};
&usb3_0 {
status = "okay";
};
&usb_dwc3_0 {
dr_mode = "otg";
hnp-disable;
srp-disable;
adp-disable;
usb-role-switch;
role-switch-default-mode = "none";
snps,dis-u1-entry-quirk;
snps,dis-u2-entry-quirk;
status = "okay";
port {
usb3_drd_sw: endpoint {
remote-endpoint = <&typec_dr_sw>;
};
};
};
/ {
gpio-sbu-mux {
compatible = "gpio-sbu-mux";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_typec_mux>;
switch-gpios = <&gpio4 20 GPIO_ACTIVE_LOW>;
orientation-switch;
port {
usb3_data_ss: endpoint {
remote-endpoint = <&typec_con_ss>;
};
};
};
chosen {
infix {
/* "admin" */
-28
View File
@@ -250,35 +250,7 @@ static int change(sr_session_ctx_t *session, uint32_t sub_id, const char *module
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);
LYX_LIST_FOR_EACH(cifs, cif, "container") {
struct lyd_node *mount;
LYX_LIST_FOR_EACH(lyd_child(cif), mount, "mount") {
const char *src = lydx_get_cattr(mount, "source");
const char *id = lydx_get_cattr(mount, "name");
if (src && access(src, R_OK) != 0) {
char errmsg[256];
const char *reason = strerror(errno);
snprintf(errmsg, sizeof(errmsg),
"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:
default:
return SR_ERR_OK;
+2 -2
View File
@@ -25,12 +25,12 @@ MODULES=(
"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-lldp@2025-01-08.yang"
"infix-dhcp-common@2025-01-29.yang"
"infix-dhcp-client@2025-01-29.yang"
"infix-dhcp-server@2025-01-29.yang"
"infix-meta@2024-10-18.yang"
"infix-system@2025-01-25.yang"
"infix-system@2025-04-29.yang"
"infix-services@2024-12-03.yang"
"ieee802-ethernet-interface@2019-06-21.yang"
"infix-ethernet-interface@2024-02-27.yang"
@@ -22,13 +22,6 @@ module infix-containers {
prefix infix-sys;
}
revision 2025-05-14 {
description
"Validation improvement:
- Added constraint to require either 'source' or 'content' in a container mount.";
reference "internal";
}
revision 2024-11-15 {
description "Two major changes:
- Add support for ftp/http/https images with checksum
@@ -349,7 +342,6 @@ module infix-containers {
}
choice data {
mandatory true;
case source {
leaf source {
description "Host path to mount in container, may be a glob.
+1 -1
View File
@@ -104,7 +104,7 @@ module infix-dhcp-client {
The default is an empty list, meaning all supported options. To
restrict the client to only get IP address and default route, set
this to: 'netmask router'";
this to: 'subnet router'";
must "not(id = 'fqdn' and 'value/hex')" {
error-message "FQDN option must use string format";
+2 -2
View File
@@ -88,10 +88,10 @@ submodule infix-if-lag {
type enumeration {
enum passive {
description "LACP passive mode";
description "LACP active mode";
}
enum active {
description "LACP active mode.";
description "LACP passive mode.";
}
}
}
-23
View File
@@ -11,13 +11,6 @@ module infix-lldp {
contact "kernelkit@googlegroups.com";
description "Infix augments and deviations to ieee-dot1ab-lldp.";
revision 2025-05-05 {
description
"Restrict 'dest-mac-address' to only allow the LLDP multicast MAC
address (01:80:C2:00:00:0E).";
reference "internal";
}
revision 2025-01-08 {
description "Enable std. /lldp:lldp/message-tx-interval";
}
@@ -39,22 +32,6 @@ module infix-lldp {
}
}
deviation "/lldp:lldp/lldp:port/lldp:dest-mac-address" {
deviate replace {
type string {
pattern "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}";
}
}
}
deviation "/lldp:lldp/lldp:port/lldp:dest-mac-address" {
deviate add {
must "translate(., 'abcdef', 'ABCDEF') = '01:80:C2:00:00:0E'" {
error-message "Only the LLDP Multicast MAC (01:80:C2:00:00:0E) is allowed.";
}
}
}
deviation "/lldp:lldp/lldp:message-fast-tx" {
deviate not-supported;
}
+98
View File
@@ -28,6 +28,11 @@ module infix-system {
contact "kernelkit@googlegroups.com";
description "Infix augments and deviations to ietf-system.";
revision 2025-04-29 {
description "Add services status.";
reference "internal";
}
revision 2025-01-25 {
description "Add DNS resolver status.";
reference "internal";
@@ -412,6 +417,99 @@ module infix-system {
}
}
}
container services {
description "List of monitored system services (processes)";
config false;
list service {
key "pid";
description "Tracked system service processes.";
leaf pid {
type uint32;
description "Process ID (PID) of the service.";
}
leaf name {
type string;
description "Name of the service or process.";
}
leaf description {
type string;
description
"Short description of the service.";
}
leaf status {
type enumeration {
enum halted {
description "Service is halted.";
}
enum missing {
description "Service files or dependencies are missing.";
}
enum crashed {
description "Service has crashed.";
}
enum stopped {
description "Service has been manually stopped.";
}
enum busy {
description "Service is busy.";
}
enum restart {
description "Service is restarting.";
}
enum conflict {
description "Service has a conflict preventing start.";
}
enum unknown {
description "Service is in an unknown state.";
}
enum done {
description "Service task has completed.";
}
enum failed {
description "Service task has failed.";
}
enum active {
description "Run/task type service is active.";
}
enum stopping {
description "Service is in the process of stopping.";
}
enum teardown {
description "Service is performing teardown operations.";
}
enum setup {
description "Service is setting up.";
}
enum cleanup {
description "Service is cleaning up.";
}
enum paused {
description "Service is paused.";
}
enum waiting {
description "Service is waiting for conditions.";
}
enum starting {
description "Service is starting.";
}
enum running {
description "Service is running.";
}
enum dead {
description "Service process is dead.";
}
}
description
"Detailed current status of the process.";
}
}
}
}
deviation "/sys:system/sys:hostname" {
+1 -1
View File
@@ -2,5 +2,5 @@
# REMEMBER TO UPDATE infix-interfaces ALSO IN confd.inc
MODULES=(
"infix-interfaces@2025-01-09.yang -e vlan-filtering -e containers"
"infix-containers@2025-05-14.yang"
"infix-containers@2024-11-15.yang"
)
+4 -1
View File
@@ -3,7 +3,7 @@
MODULES=(
"sysrepo@2024-10-25.yang"
"sysrepo-factory-default@2025-03-18.yang"
"sysrepo-factory-default@2024-05-02.yang"
"sysrepo-monitoring@2023-08-11.yang"
"sysrepo-notifications@2025-01-10.yang"
"sysrepo-plugind@2022-08-26.yang"
@@ -15,8 +15,11 @@ MODULES=(
"ietf-netconf-notifications@2012-02-06.yang"
"ietf-netconf-with-defaults@2011-06-01.yang"
"ietf-origin@2018-02-14.yang"
"ietf-yang-library@2016-06-21.yang"
"ietf-yang-library@2019-01-04.yang"
"iana-if-type@2014-05-08.yang"
"ietf-interfaces@2018-02-20.yang"
"ietf-ip@2018-02-22.yang"
"ietf-network-instance@2019-01-21.yang"
+13 -19
View File
@@ -373,12 +373,6 @@
</ACTION>
</COMMAND>
<COMMAND name="lldp" help="Show LLDP neighbors">
<ACTION sym="script">
show lldp
</ACTION>
</COMMAND>
<COMMAND name="hardware" help="Show hardware information">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
show hardware |pager
@@ -477,23 +471,22 @@
<ACTION sym="script">sysinfo</ACTION>
</COMMAND>
-->
<COMMAND name="version" help="Show software version">
<ACTION sym="script" in="tty" interrupt="true">cat /etc/version</ACTION>
</COMMAND>
<COMMAND name="version" help="Show software version">
<ACTION sym="script" in="tty" interrupt="true">cat /etc/version</ACTION>
</COMMAND>
<COMMAND name="factory-config" help="Show factory-config">
<ACTION sym="script" in="tty" out="tty" interrupt="true">jq -C . /etc/factory-config.cfg |pager</ACTION>
</COMMAND>
<COMMAND name="factory-config" help="Show factory-config">
<ACTION sym="script" in="tty" out="tty" interrupt="true">jq -C . /etc/factory-config.cfg |pager</ACTION>
</COMMAND>
<COMMAND name="running-config" help="Show running-config">
<ACTION sym="script" in="tty" out="tty" interrupt="true">sysrepocfg -X -f json | jq -C . |pager</ACTION>
</COMMAND>
<COMMAND name="running-config" help="Show running-config">
<ACTION sym="script" in="tty" out="tty" interrupt="true">sysrepocfg -X -f json | jq -C . |pager</ACTION>
</COMMAND>
<COMMAND name="startup-config" help="Show startup-config">
<ACTION sym="script" in="tty" out="tty" interrupt="true">jq -C . /cfg/startup-config.cfg |pager</ACTION>
<COMMAND name="startup-config" help="Show startup-config">
<ACTION sym="script" in="tty" out="tty" interrupt="true">jq -C . /cfg/startup-config.cfg |pager</ACTION>
</COMMAND>
</COMMAND>
</COMMAND>
<COMMAND name="factory-reset" help="Restore the system to factory default state">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
/bin/yorn "This will restore the device to factory defaults"
@@ -587,6 +580,7 @@
rauc install $force $KLISH_PARAM_URI
</ACTION>
</COMMAND>
</VIEW>
<VIEW name="config">
+45
View File
@@ -0,0 +1,45 @@
class JsonData:
@staticmethod
def get(default, indata, *args):
data = indata
for arg in args:
if arg in data:
data = data.get(arg)
else:
return default
return data
class Decore():
@staticmethod
def decorate(sgr, txt, restore="0"):
return f"\033[{sgr}m{txt}\033[{restore}m"
@staticmethod
def invert(txt):
return Decore.decorate("7", txt)
@staticmethod
def bold(txt):
return Decore.decorate("1", txt)
@staticmethod
def red(txt):
return Decore.decorate("31", txt, "39")
@staticmethod
def green(txt):
return Decore.decorate("32", txt, "39")
@staticmethod
def yellow(txt):
return Decore.decorate("33", txt, "39")
@staticmethod
def underline(txt):
return Decore.decorate("4", txt, "24")
@staticmethod
def gray_bg(txt):
return Decore.decorate("100", txt)
+111
View File
@@ -0,0 +1,111 @@
import json
from common import Decore
from common import JsonData
from dataclasses import dataclass
class System:
def __init__(self, cfg):
self.services = self.Services(cfg)
self.software = self.Software(cfg)
class Services:
def __init__(self, cfg):
self.cfg = cfg
def get(self):
return self.cfg.run("/ietf-system:system-state/infix-system:services")
def pretty(self):
data = self.get()
return data if data else {}
class Software:
class Slot:
@dataclass
class Pad:
name: int = 10
state: int = 10
version: int = 23
date: int = 25
hash: int = 64
def __init__(self, data, version, date): # TODO: why is slot version and date on top level?
self.pad = self.Pad()
self.name = data.get('bootname', '')
self.size = data.get('size', '')
self.type = data.get('class', '')
self.hash = data.get('sha256', '')
self.state = data.get('state', '')
self.version = version # TODO
self.date = version # TODO
def print_detailed(self):
"""Detailed information about one bundle"""
print(f"Name : {self.name}")
print(f"State : {self.state}")
print(f"Version : {self.version}")
print(f"Size : {self.size}")
print(f"SHA-256 : {self.hash}")
print(f"Installed : {self.date}")
@classmethod
def print_hdr(cls):
pad = cls.Pad()
hdr = (f"{'NAME':<{pad.name}}"
f"{'STATE':<{pad.state}}"
f"{'VERSION':<{pad.version}}"
f"{'DATE':<{pad.date}}")
print(Decore.invert(hdr))
def print_slot_row(self):
if self.type != "rootfs":
return
"""Brief information about one bundle"""
row = f"{self.name:<{self.pad.name}}"
row += f"{self.state:<{self.pad.state}}"
row += f"{self.version:<{self.pad.version}}"
row += f"{self.date:<{self.pad.date}}"
print(row)
def __init__(self, cfg):
self.cfg = cfg
self.data = self.get()
self.slots = self.data.get("slot", [])
self.version = JsonData.get('', self.data, 'bundle', 'version')
self.date = JsonData.get('', self.data, 'installed', 'datetime')
self.boot_order = self.data.get("boot-order", ["Unknown"])
def get(self):
return self.cfg.run("/ietf-system:system-state/infix-system:software")
def pprint(self):
software = self.data
print(Decore.invert("BOOT ORDER"))
order = " ".join(boot.strip() for boot in self.boot_order)
print(f"{order}\n")
self.Slot.print_hdr()
for _slot in reversed(self.slots):
slot = self.Slot(_slot, self.version, self.date)
slot.print_slot_row()
def pprint_slot(self, name):
match = next((slot for slot in self.slots if slot.get("bootname") == name), None)
if match:
slot = self.Slot(match, self.version, self.date)
slot.print_detailed()
def show(self, args):
if self.cfg.raw_output:
print(json.dumps(self.data, indent=2))
return
if args:
self.pprint_slot(args[0])
else:
self.pprint()
+23 -64
View File
@@ -1,35 +1,17 @@
#!/usr/bin/env python3
import re
import subprocess
import json
from typing import List
import os
import shlex
import argparse
import subprocess
from sysrepocfg import Sysrepocfg
from modules.system import System
RAW_OUTPUT = False
def run_sysrepocfg(xpath: str) -> dict:
if not isinstance(xpath, str) or not xpath.startswith("/"):
print("Invalid XPATH. It must be a valid string starting with '/'.")
return {}
safe_xpath = shlex.quote(xpath)
try:
result = subprocess.run([
"sysrepocfg", "-f", "json", "-X", "-d", "operational", "-x", safe_xpath
], capture_output=True, text=True, check=True)
json_data = json.loads(result.stdout)
return json_data
except subprocess.CalledProcessError as e:
print(f"Error running sysrepocfg: {e}")
return {}
except json.JSONDecodeError as e:
print(f"Error parsing JSON output: {e}")
return {}
def cli_pretty(json_data: dict, command: str, *args: str):
if not command or not all(isinstance(arg, str) for arg in args):
print("Invalid command or arguments. All arguments must be strings.")
@@ -47,7 +29,7 @@ def cli_pretty(json_data: dict, command: str, *args: str):
print(f"Error running cli-pretty: {e}")
def dhcp(args: List[str]) -> None:
data = run_sysrepocfg("/infix-dhcp-server:dhcp-server")
data = Sysrepocfg.run("/infix-dhcp-server:dhcp-server")
if not data:
print("No interface data retrieved.")
return
@@ -58,7 +40,7 @@ def dhcp(args: List[str]) -> None:
cli_pretty(data, "show-dhcp-server")
def hardware(args: List[str]) -> None:
data = run_sysrepocfg("/ietf-hardware:hardware")
data = Sysrepocfg.run("/ietf-hardware:hardware")
if not data:
print("No hardware data retrieved.")
return
@@ -69,7 +51,7 @@ def hardware(args: List[str]) -> None:
cli_pretty(data, "show-hardware")
def ntp(args: List[str]) -> None:
data = run_sysrepocfg("/system-state/ntp")
data = Sysrepocfg.run("/system-state/ntp")
if not data:
print("No ntp data retrieved.")
return
@@ -90,7 +72,7 @@ def is_valid_interface_name(interface_name: str) -> bool:
return bool(re.match(pattern, interface_name))
def interface(args: List[str]) -> None:
data = run_sysrepocfg("/ietf-interfaces:interfaces")
data = Sysrepocfg.run("/ietf-interfaces:interfaces")
if not data:
print("No interface data retrieved.")
return
@@ -111,7 +93,7 @@ def interface(args: List[str]) -> None:
print("Too many arguments provided. Only one interface name is expected.")
def stp(args: List[str]) -> None:
data = run_sysrepocfg("/ietf-interfaces:interfaces")
data = Sysrepocfg.run("/ietf-interfaces:interfaces")
if not data:
print("No interface data retrieved.")
return
@@ -121,31 +103,14 @@ def stp(args: List[str]) -> None:
return
cli_pretty(data, "show-bridge-stp")
def software(args: List[str]) -> None:
data = run_sysrepocfg("/ietf-system:system-state/infix-system:software")
if not data:
print("No software data retrieved.")
return
if RAW_OUTPUT:
print(json.dumps(data, indent=2))
return
if len(args) == 0 or not args[0]: # Treat "" as no arg.
cli_pretty(data, "show-software")
elif len(args) == 1:
name = args[0]
if name not in ("primary", "secondary"):
print(f"Invalid software name: {name}")
return
cli_pretty(data, f"show-software", "-n", name)
else:
print("Too many arguments provided. Only one name is expected.")
def software(cfg : Sysrepocfg, args: List[str]) -> None:
system = System(cfg)
system.software.show(args)
def routes(args: List[str]):
ip_version = args[0] if args and args[0] in ["ipv4", "ipv6"] else "ipv4"
data = run_sysrepocfg("/ietf-routing:routing/ribs")
data = Sysrepocfg.run("/ietf-routing:routing/ribs")
if not data:
print("No route data retrieved.")
return
@@ -154,25 +119,15 @@ def routes(args: List[str]):
return
cli_pretty(data, "show-routing-table", "-i", ip_version)
def lldp(args: List[str]):
data = run_sysrepocfg("/ieee802-dot1ab-lldp:lldp")
if not data:
print("No lldp data retrieved.")
return
if RAW_OUTPUT:
print(json.dumps(data, indent=2))
return
cli_pretty(data, "show-lldp")
def execute_command(command: str, args: List[str]):
def execute_legacy_non_class_command(command: str, args: List[str]):
command_mapping = {
'dhcp': dhcp,
'hardware': hardware,
'interface': interface,
'ntp': ntp,
'routes': routes,
'lldp': lldp,
'software' : software,
'stp': stp,
}
@@ -181,7 +136,6 @@ def execute_command(command: str, args: List[str]):
else:
print(f"Unknown command: {command}")
def main():
global RAW_OUTPUT
@@ -189,11 +143,16 @@ def main():
parser.add_argument('command', help="Command to execute")
parser.add_argument('args', nargs=argparse.REMAINDER, help="Additional arguments for the command")
parser.add_argument('-r', '--raw', action='store_true', help="Print raw JSON output from Sysrepo")
parser.add_argument( "-f", "--datafile", default=None, type=str, help="Path to the input JSON data file")
args = parser.parse_args()
RAW_OUTPUT = args.raw
execute_command(args.command, args.args)
RAW_OUTPUT = args.raw
cfg = Sysrepocfg(args.datafile, args.raw)
if args.command == "software":
software(cfg, args.args)
else:
execute_legacy_non_class_command(args.command, args.args)
if __name__ == "__main__":
+59
View File
@@ -0,0 +1,59 @@
import shlex
import sys
import subprocess
import json
class Sysrepocfg:
def __init__(self, data_file=None, raw=False):
self.data_file = data_file
self.raw_output = raw
def _run(self, safe_xpath):
try:
result = subprocess.run([
"sysrepocfg", "-f", "json", "-X", "-d", "operational", "-x", safe_xpath
], capture_output=True, text=True, check=True)
data = json.loads(result.stdout)
if not data:
sys.exit(f"Error, no data from sysrepo")
return data
except subprocess.CalledProcessError as e:
sys.exit(f"Error, running sysrepocfg: {e}")
except json.JSONDecodeError as e:
sys.exit(f"Error, parsing JSON output: {e}")
def _run_emulator(self, xpath):
"""
Emulates `sysrepocfg -X -x <xpath>` by extracting a subtree from the JSON file.
:param json_file: Path to the local JSON file containing sysrepo-style data.
:param xpath: YANG-style XPath (e.g., '/ietf-interfaces:interfaces').
:return: Extracted subtree or None if not found.
"""
with open(self.data_file, 'r') as f:
data = json.load(f)
path_parts = xpath.strip('/').split('/')
node = data
for part in path_parts:
if isinstance(node, dict) and part in node:
node = node[part]
else:
return None # Path doesn't exist
return node
def run(self, xpath: str) -> dict:
if not isinstance(xpath, str) or not xpath.startswith("/"):
print("Invalid XPATH. It must be a valid string starting with '/'.")
return {}
safe_xpath = shlex.quote(xpath)
if self.data_file is not None:
return self._run_emulator(safe_xpath)
return self._run(safe_xpath)
+23 -190
View File
@@ -20,7 +20,6 @@ class PadMdb:
group = 20
ports = 45
class PadStpPort:
port = 12
id = 7
@@ -31,7 +30,6 @@ class PadStpPort:
total = 12 + 7 + 12 + 12 + 6 + 31
class PadRoute:
dest = 30
pref = 8
@@ -51,15 +49,6 @@ class PadRoute:
else:
raise ValueError(f"unknown IP version: {ipv}")
class PadSoftware:
name = 10
date = 25
hash = 64
state = 10
version = 23
class PadDhcpServer:
ip = 17
mac = 19
@@ -67,13 +56,11 @@ class PadDhcpServer:
cid = 19
exp = 10
class PadUsbPort:
title = 30
name = 20
state = 10
class PadNtpSource:
address = 16
mode = 13
@@ -81,7 +68,6 @@ class PadNtpSource:
stratum = 11
poll = 14
class Decore():
@staticmethod
def decorate(sgr, txt, restore="0"):
@@ -115,21 +101,11 @@ class Decore():
def gray_bg(txt):
return Decore.decorate("100", txt)
class PadLldp:
interface = 16
rem_idx = 10
time = 12
chassis_id = 20
port_id = 20
def datetime_now():
if UNIT_TEST:
return datetime(2023, 1, 1, 12, 0, 0, tzinfo=timezone.utc)
return datetime.now(timezone.utc)
def get_json_data(default, indata, *args):
data = indata
for arg in args:
@@ -140,14 +116,12 @@ def get_json_data(default, indata, *args):
return data
def remove_yang_prefix(key):
parts = key.split(":", 1)
if len(parts) > 1:
return parts[1]
return key
class Date(datetime):
def _pretty_delta(delta):
assert(delta.total_seconds() > 0)
@@ -197,6 +171,7 @@ class Date(datetime):
return cls.strptime(f"{date}+{tz}", "%Y-%m-%dT%H:%M:%S%z")
class Route:
def __init__(self, data, ip):
self.data = data
@@ -304,41 +279,6 @@ class Route:
row += f"{hop:<{PadRoute.next_hop}} "
print(row)
class Software:
"""Software bundle class """
def __init__(self, data):
self.data = data
self.name = data.get('bootname', '')
self.size = data.get('size', '')
self.type = data.get('class', '')
self.hash = data.get('sha256', '')
self.state = data.get('state', '')
self.version = get_json_data('', self.data, 'bundle', 'version')
self.date = get_json_data('', self.data, 'installed', 'datetime')
def is_rootfs(self):
"""True if bundle type is 'rootfs'"""
return self.type == "rootfs"
def print(self):
"""Brief information about one bundle"""
row = f"{self.name:<{PadSoftware.name}}"
row += f"{self.state:<{PadSoftware.state}}"
row += f"{self.version:<{PadSoftware.version}}"
row += f"{self.date:<{PadSoftware.date}}"
print(row)
def detail(self):
"""Detailed information about one bundle"""
print(f"Name : {self.name}")
print(f"State : {self.state}")
print(f"Version : {self.version}")
print(f"Size : {self.size}")
print(f"SHA-256 : {self.hash}")
print(f"Installed : {self.date}")
class USBport:
def __init__(self, data):
self.data = data
@@ -351,7 +291,6 @@ class USBport:
row += f"{self.state:<{PadUsbPort.state}}"
print(row)
class STPBridgeID:
def __init__(self, id):
self.id = id
@@ -364,7 +303,6 @@ class STPBridgeID:
)
return f"{prio:1x}.{sysid:03x}.{addr}"
class STPPortID:
def __init__(self, id):
self.id = id
@@ -376,7 +314,6 @@ class STPPortID:
)
return f"{prio:1x}.{pid:03x}"
class DhcpServer:
def __init__(self, data):
self.data = data
@@ -554,7 +491,6 @@ class Iface:
def is_gretap(self):
return self.data['type'] == "infix-if-type:gretap"
def oper(self, detail=False):
"""Remap in brief overview to fit column widths."""
if not detail and self.oper_status == "lower-layer-down":
@@ -741,7 +677,7 @@ class Iface:
lower.pr_name(pipe)
lower.pr_proto_lag()
def pr_veth(self):
def pr_veth(self, _ifaces):
self.pr_name(pipe="")
self.pr_proto_veth()
self.pr_proto_ipv4()
@@ -952,25 +888,6 @@ class Iface:
print(f"{' port':<{20}}: {tc.get('port', 'UNKNOWN')}")
class LldpNeighbor:
def __init__(self, iface, data):
self.interface = iface
self.remote_index = data.get("remote-index", 0)
self.time_mark = data.get("time-mark", 0)
self.chassis_id = data.get("chassis-id", "unknown")
self.port_id = data.get("port-id", "unknown")
def print(self):
row = (
f"{self.interface:<{PadLldp.interface}}"
f"{self.remote_index:<{PadLldp.rem_idx}}"
f"{self.time_mark:<{PadLldp.time}}"
f"{self.chassis_id:<{PadLldp.chassis_id}}"
f"{self.port_id:<{PadLldp.port_id}}"
)
print(row)
def find_iface(_ifaces, name):
for _iface in [Iface(data) for data in _ifaces]:
if _iface.name == name:
@@ -982,11 +899,9 @@ def find_iface(_ifaces, name):
def version_sort(s):
return [int(x) if x.isdigit() else x for x in re.split(r'(\d+)', s)]
def ifname_sort(iface):
return version_sort(iface["name"])
def brport_sort(iface):
brname = iface.get("infix-interfaces:bridge-port", {}).get("bridge", "")
return version_sort(brname) + version_sort(iface["name"])
@@ -1030,7 +945,7 @@ def pr_interface_list(json):
continue
if iface.is_veth():
iface.pr_veth()
iface.pr_veth(ifaces)
continue
if iface.is_gre():
@@ -1100,6 +1015,7 @@ def show_bridge_mdb(json):
iface.pr_vlans_mdb(iface.name)
def show_bridge_stp_port(ifname, brport):
stp = brport["stp"]
@@ -1133,7 +1049,6 @@ def show_bridge_stp_port(ifname, brport):
)
print(row)
def show_bridge_stp(json):
if not json.get("ietf-interfaces:interfaces"):
print("Error, top level \"ietf-interfaces:interface\" missing")
@@ -1202,46 +1117,6 @@ def show_routing_table(json, ip):
route = Route(r, ip)
route.print()
def find_slot(_slots, name):
for _slot in [Software(data) for data in _slots]:
if _slot.name == name:
return _slot
return False
def show_software(json, name):
if not json.get("ietf-system:system-state", "infix-system:software"):
print("Error, cannot find infix-system:software")
sys.exit(1)
software = get_json_data({}, json, 'ietf-system:system-state', 'infix-system:software')
slots = software.get("slot")
boot_order = software.get("boot-order", ["Unknown"])
if name:
slot = find_slot(slots, name)
if slot:
slot.detail()
else:
print(Decore.invert("BOOT ORDER"))
order=""
for boot in boot_order:
order+=f"{boot.strip()} "
print(order)
print("")
hdr = (f"{'NAME':<{PadSoftware.name}}"
f"{'STATE':<{PadSoftware.state}}"
f"{'VERSION':<{PadSoftware.version}}"
f"{'DATE':<{PadSoftware.date}}")
print(Decore.invert(hdr))
for _s in reversed(slots):
slot = Software(_s)
if slot.is_rootfs():
slot.print()
def show_hardware(json):
if not json.get("ietf-hardware:hardware"):
print(f"Error, top level \"ietf-hardware:component\" missing")
@@ -1260,7 +1135,6 @@ def show_hardware(json):
port = USBport(component)
port.print()
def show_ntp(json):
if not json.get("ietf-system:system-state"):
print("NTP client not enabled.")
@@ -1281,7 +1155,6 @@ def show_ntp(json):
row += f"{source['poll']:>{PadNtpSource.poll}}"
print(row)
def show_dhcp_server(json, stats):
data = json.get("infix-dhcp-server:dhcp-server")
if not data:
@@ -1301,37 +1174,6 @@ def show_dhcp_server(json, stats):
print(Decore.invert(hdr))
server.print()
def show_lldp(json):
if not json.get("ieee802-dot1ab-lldp:lldp"):
print("Error: No LLDP data available.")
sys.exit(1)
lldp_ports = json["ieee802-dot1ab-lldp:lldp"].get("port", [])
if not lldp_ports:
print("No LLDP neighbors found.")
return
header = (
f"{'INTERFACE':<{PadLldp.interface}}"
f"{'REM-IDX':<{PadLldp.rem_idx}}"
f"{'TIME':<{PadLldp.time}}"
f"{'CHASSIS-ID':<{PadLldp.chassis_id}}"
f"{'PORT-ID':<{PadLldp.port_id}}"
)
print(Decore.invert(header))
for port_data in lldp_ports:
port_name = port_data["name"]
neighbors = port_data.get("remote-systems-data", [])
for neighbor in neighbors:
entry = LldpNeighbor(port_name, neighbor)
entry.print()
def main():
global UNIT_TEST
@@ -1349,51 +1191,42 @@ def main():
parser.add_argument('-t', '--test', action='store_true', help='Enable unit test mode')
subparsers.add_parser('show-boot-order', help='Show NTP sources')
parser_show_routing_table = subparsers.add_parser('show-routing-table', help='Show the routing table')
parser_show_routing_table.add_argument('-i', '--ip', required=True, help='IPv4 or IPv6 address')
subparsers.add_parser('show-bridge-mdb', help='Show bridge MDB')
parser_show_interfaces = subparsers.add_parser('show-interfaces', help='Show interfaces')
parser_show_interfaces.add_argument('-n', '--name', help='Interface name')
subparsers.add_parser('show-bridge-stp', help='Show spanning tree state')
parser_show_bridge_mdb = subparsers.add_parser('show-bridge-mdb', help='Show bridge MDB')
parser_show_bridge_stp = subparsers.add_parser('show-bridge-stp',
help='Show spanning tree state')
subparsers.add_parser('show-dhcp-server', help='Show DHCP server') \
.add_argument("-s", "--stats", action="store_true", help="Show server statistics")
parser_show_hardware = subparsers.add_parser('show-hardware', help='Show USB ports')
subparsers.add_parser('show-hardware', help='Show USB ports')
parser_show_ntp_sources = subparsers.add_parser('show-ntp', help='Show NTP sources')
subparsers.add_parser('show-interfaces', help='Show interfaces') \
.add_argument('-n', '--name', help='Interface name')
parser_show_boot_order = subparsers.add_parser('show-boot-order', help='Show NTP sources')
subparsers.add_parser('show-lldp', help='Show LLDP neighbors')
subparsers.add_parser('show-ntp', help='Show NTP sources')
subparsers.add_parser('show-routing-table', help='Show the routing table') \
.add_argument('-i', '--ip', required=True, help='IPv4 or IPv6 address')
subparsers.add_parser('show-software', help='Show software versions') \
.add_argument('-n', '--name', help='Slotname')
parser_dhcp_srv = subparsers.add_parser('show-dhcp-server', help='Show DHCP server')
parser_dhcp_srv.add_argument("-s", "--stats", action="store_true", help="Show server statistics")
args = parser.parse_args()
UNIT_TEST = args.test
if args.command == "show-bridge-mdb":
if args.command == "show-interfaces":
show_interfaces(json_data, args.name)
elif args.command == "show-routing-table":
show_routing_table(json_data, args.ip)
elif args.command == "show-bridge-mdb":
show_bridge_mdb(json_data)
elif args.command == "show-bridge-stp":
show_bridge_stp(json_data)
elif args.command == "show-dhcp-server":
show_dhcp_server(json_data, args.stats)
elif args.command == "show-hardware":
show_hardware(json_data)
elif args.command == "show-interfaces":
show_interfaces(json_data, args.name)
elif args.command == "show-lldp":
show_lldp(json_data)
elif args.command == "show-ntp":
show_ntp(json_data)
elif args.command == "show-routing-table":
show_routing_table(json_data, args.ip)
elif args.command == "show-software":
show_software(json_data, args.name)
elif args.command == "show-dhcp-server":
show_dhcp_server(json_data, args.stats)
else:
print(f"Error, unknown command '{args.command}'")
sys.exit(1)
+19
View File
@@ -177,6 +177,24 @@ def add_platform(out):
insert(out, "platform", platform)
def add_services(out):
data = HOST.run_json(["initctl", "-j"], [])
services = []
for d in data:
if "pid" not in d or "status" not in d or "identity" not in d or "description" not in d:
continue
entry = {
"pid": d["pid"],
"name": d["identity"],
"status": d["status"],
"description": d["description"]
}
services.append(entry)
insert(out, "infix-system:services", "service", services)
def add_software(out):
software = {}
try:
@@ -291,5 +309,6 @@ def operational():
add_dns(out_state)
add_clock(out_state)
add_platform(out_state)
add_services(out_state)
return out
+17 -23
View File
@@ -4,35 +4,20 @@ from collections import defaultdict
def operational():
"""Retrieve LLDP neighbor information and store in remote-systems-data under the correct port."""
# https://www.ieee802.org/1/files/public/YANGs/ieee802-types.yang
# <chassis-component> and <port-component> subtypes are not supported in
# https://github.com/lldpd/lldpd until v1.0.19
chassis_id_subtype_mapping = {
#"unhandled": "chassis-component",
# Reference: https://www.ieee802.org/1/files/public/YANGs/ieee802-types.yang
subtype_mapping = {
"component": "chassis-component",
"ifalias": "interface-alias",
#"unhandled": "port-component",
"port": "port-component",
"mac": "mac-address",
"ip": "network-address",
"ifname": "interface-name",
"local": "local"
}
# https://www.ieee802.org/1/files/public/YANGs/ieee802-types.yang
# <port-component> and <agent-circuit-id> subtypes are not supported in
# https://github.com/lldpd/lldpd until v1.0.19
port_id_subtype_mapping = {
"ifalias": "interface-alias",
#"unhandled": "port-component",
"mac": "mac-address",
"ip": "network-address",
"ifname": "interface-name",
#"unhandled": "agent-circuit-id"
"local": "local"
}
DEFAULT_MAC = "00-00-00-00-00-00"
LLDP_MULTICAST_MAC = "01:80:C2:00:00:0E"
port_data = defaultdict(lambda: {"remote-systems-data": [], "dest-mac-address": LLDP_MULTICAST_MAC})
port_data = defaultdict(lambda: {"remote-systems-data": [], "dest-mac-address": None})
data = HOST.run_json(["lldpcli", "show", "neighbors", "-f", "json"])
@@ -47,12 +32,18 @@ def operational():
time_mark = parse_time(iface_data.get("age"))
chassis = iface_data.get("chassis", {})
chassis_id_type, chassis_id_value = extract_chassis_id(chassis, chassis_id_subtype_mapping)
chassis_id_type, chassis_id_value = extract_chassis_id(chassis, subtype_mapping)
port_info = iface_data.get("port", {})
port_id_type = port_id_subtype_mapping.get(port_info.get("id", {}).get("type"), "unknown")
port_id_type = subtype_mapping.get(port_info.get("id", {}).get("type"), "unknown")
port_id_value = port_info.get("id", {}).get("value", "")
dest_mac_address = (
chassis_id_value.replace(":", "-") if chassis_id_type == "mac-address" else
port_id_value.replace(":", "-") if port_id_type == "mac-address" else
DEFAULT_MAC
)
remote_entry = {
"time-mark": time_mark,
"remote-index": remote_index,
@@ -64,6 +55,9 @@ def operational():
port_data[iface_name]["remote-systems-data"].append(remote_entry)
if port_data[iface_name]["dest-mac-address"] is None:
port_data[iface_name]["dest-mac-address"] = dest_mac_address
formatted_output = {
"ieee802-dot1ab-lldp:lldp": {
"port": [
@@ -1 +0,0 @@
../../../infamy/topologies/1x3.dot
@@ -0,0 +1,25 @@
graph "1x3" {
layout="neato";
overlap="false";
esep="+80";
node [shape=record, fontname="DejaVu Sans Mono, Book"];
edge [color="cornflowerblue", penwidth="2", fontname="DejaVu Serif, Book"];
host [
label="host | { <mgmt> mgmt | <data1> data1 | <data2> data2 }",
pos="0,12!",
requires="controller",
];
target [
label="{ <mgmt> mgmt | <data1> data1 | <data2> data2 } | target",
pos="10,12!",
requires="infix",
];
host:mgmt -- target:mgmt [requires="mgmt", color=lightgrey]
host:data1 -- target:data1 [color=black]
host:data2 -- target:data2 [color=black]
}
@@ -35,7 +35,7 @@
<!-- host&#45;&#45;target -->
<g id="edge1" class="edge">
<title>host:mgmt&#45;&#45;target:mgmt</title>
<path fill="none" stroke="lightgray" stroke-width="2" d="M108,-58C108,-58 308.03,-58 308.03,-58"/>
<path fill="none" stroke="lightgrey" stroke-width="2" d="M108,-58C108,-58 308.03,-58 308.03,-58"/>
</g>
<!-- host&#45;&#45;target -->
<g id="edge2" class="edge">

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

@@ -8,14 +8,14 @@ attached to a VLAN filtering bridge are always locally terminated.
.---------------------------.
| target |
| |
| data1.10 br0 data2.10 |
| data0.10 br0 data1.10 |
| \ / \ / |
'------data1-----data2------'
'------data0-----data1------'
| |
| |
.------data1-----data2------.
.------data0-----data1------.
| / : \ |
| data1.10 : data2.10 |
| data0.10 : data1.10 |
| : |
| host |
| : |
@@ -23,7 +23,7 @@ attached to a VLAN filtering bridge are always locally terminated.
....
In this setup, even though VLAN 10 is allowed to ingress and egress on
both `data1` and `data2`, _bridging_ of packets from one to the other
both `data0` and `data1`, _bridging_ of packets from one to the other
must _not_ be allowed.
"""
@@ -35,10 +35,10 @@ with infamy.Test() as test:
tgt = env.attach("target", "mgmt")
with test.step("Configure bridge and VLAN interfaces on target"):
_, hdata0 = env.ltop.xlate( "host", "data0")
_, hdata1 = env.ltop.xlate( "host", "data1")
_, hdata2 = env.ltop.xlate( "host", "data2")
_, ddata0 = env.ltop.xlate("target", "data0")
_, ddata1 = env.ltop.xlate("target", "data1")
_, ddata2 = env.ltop.xlate("target", "data2")
tgt.put_config_dicts({
"ietf-interfaces": {
@@ -53,12 +53,35 @@ with infamy.Test() as test:
"vlan": [
{
"vid": 1,
"untagged": [ddata1, ddata2]
"untagged": [ddata0, ddata1]
},
]
}
}
},
{
"name": ddata0,
"infix-interfaces:bridge-port": {
"pvid": 1,
"bridge": "br0"
}
},
{
"name": f"{ddata0}.10",
"type": "infix-if-type:vlan",
"vlan": {
"id": 10,
"lower-layer-if": ddata0,
},
"ipv4": {
"address": [
{
"ip": "10.10.1.2",
"prefix-length": 24,
}
]
}
},
{
"name": ddata1,
"infix-interfaces:bridge-port": {
@@ -73,29 +96,6 @@ with infamy.Test() as test:
"id": 10,
"lower-layer-if": ddata1,
},
"ipv4": {
"address": [
{
"ip": "10.10.1.2",
"prefix-length": 24,
}
]
}
},
{
"name": ddata2,
"infix-interfaces:bridge-port": {
"pvid": 1,
"bridge": "br0"
}
},
{
"name": f"{ddata2}.10",
"type": "infix-if-type:vlan",
"vlan": {
"id": 10,
"lower-layer-if": ddata2,
},
"ipv4": {
"address": [
{
@@ -110,8 +110,8 @@ with infamy.Test() as test:
}
})
with infamy.IsolatedMacVlan(hdata1) as ns0, \
infamy.IsolatedMacVlan(hdata2) as ns1:
with infamy.IsolatedMacVlan(hdata0) as ns0, \
infamy.IsolatedMacVlan(hdata1) as ns1:
with test.step("Configure IP addresses and VLAN interfaces on host"):
ns0.addip("10.0.1.1")
@@ -128,17 +128,17 @@ with infamy.Test() as test:
ip addr add 10.10.2.1/24 dev vlan10
""")
with test.step("Verify that host:data1 reaches host:data2 with untagged packets"):
with test.step("Verify that host:data0 reaches host:data1 with untagged packets"):
ns0.must_reach("10.0.1.2")
with test.step("Verify that traffic on VLAN 10 from host:data1 does not reach host:data2"):
with test.step("Verify that traffic on VLAN 10 from host:data0 does not reach host:data1"):
infamy.parallel(lambda: ns0.runsh("timeout -s INT 5 ping -i 0.2 -b 10.10.1.255 || true"),
lambda: ns1.must_not_receive("ip src 10.10.1.1"))
with test.step("Verify that host:data1 can reach target on VLAN 10"):
with test.step("Verify that host:data0 can reach target on VLAN 10"):
ns0.must_reach("10.10.1.2")
with test.step("Verify that host:data2 can reach target on VLAN 10"):
with test.step("Verify that host:data1 can reach target on VLAN 10"):
ns1.must_reach("10.10.2.2")
test.succeed()
@@ -14,11 +14,11 @@
<polygon fill="none" stroke="black" points="0,-0.5 0,-69.5 108,-69.5 108,-0.5 0,-0.5"/>
<text text-anchor="middle" x="25" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">host</text>
<polyline fill="none" stroke="black" points="50,-0.5 50,-69.5 "/>
<text text-anchor="middle" x="79" y="-54.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
<text text-anchor="middle" x="79" y="-54.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">tgt</text>
<polyline fill="none" stroke="black" points="50,-46.5 108,-46.5 "/>
<text text-anchor="middle" x="79" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data1</text>
<text text-anchor="middle" x="79" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data0</text>
<polyline fill="none" stroke="black" points="50,-23.5 108,-23.5 "/>
<text text-anchor="middle" x="79" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data2</text>
<text text-anchor="middle" x="79" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data1</text>
</g>
<!-- target -->
<g id="node2" class="node">
@@ -26,25 +26,25 @@
<polygon fill="none" stroke="black" points="308.03,-0.5 308.03,-69.5 432.03,-69.5 432.03,-0.5 308.03,-0.5"/>
<text text-anchor="middle" x="337.03" y="-54.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
<polyline fill="none" stroke="black" points="308.03,-46.5 366.03,-46.5 "/>
<text text-anchor="middle" x="337.03" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data1</text>
<text text-anchor="middle" x="337.03" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data0</text>
<polyline fill="none" stroke="black" points="308.03,-23.5 366.03,-23.5 "/>
<text text-anchor="middle" x="337.03" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data2</text>
<text text-anchor="middle" x="337.03" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data1</text>
<polyline fill="none" stroke="black" points="366.03,-0.5 366.03,-69.5 "/>
<text text-anchor="middle" x="399.03" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">target</text>
</g>
<!-- host&#45;&#45;target -->
<g id="edge1" class="edge">
<title>host:mgmt&#45;&#45;target:mgmt</title>
<path fill="none" stroke="lightgray" stroke-width="2" d="M108,-58C108,-58 308.03,-58 308.03,-58"/>
<title>host:tgt&#45;&#45;target:mgmt</title>
<path fill="none" stroke="cornflowerblue" stroke-width="2" d="M108,-58C108,-58 308.03,-58 308.03,-58"/>
</g>
<!-- host&#45;&#45;target -->
<g id="edge2" class="edge">
<title>host:data1&#45;&#45;target:data1</title>
<title>host:data0&#45;&#45;target:data0</title>
<path fill="none" stroke="black" stroke-width="2" d="M108,-35C108,-35 308.03,-35 308.03,-35"/>
</g>
<!-- host&#45;&#45;target -->
<g id="edge3" class="edge">
<title>host:data2&#45;&#45;target:data2</title>
<title>host:data1&#45;&#45;target:data1</title>
<path fill="none" stroke="black" stroke-width="2" d="M108,-12C108,-12 308.03,-12 308.03,-12"/>
</g>
</g>

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

@@ -7,14 +7,14 @@ attached to a VLAN filtering bridge are always locally terminated.
.---------------------------.
| target |
| |
| data1.10 br0 data2.10 |
| data0.10 br0 data1.10 |
| \ / \ / |
'------data1-----data2------'
'------data0-----data1------'
| |
| |
.------data1-----data2------.
.------data0-----data1------.
| / : \ |
| data1.10 : data2.10 |
| data0.10 : data1.10 |
| : |
| host |
| : |
@@ -22,7 +22,7 @@ attached to a VLAN filtering bridge are always locally terminated.
....
In this setup, even though VLAN 10 is allowed to ingress and egress on
both `data1` and `data2`, _bridging_ of packets from one to the other
both `data0` and `data1`, _bridging_ of packets from one to the other
must _not_ be allowed.
==== Topology
@@ -41,10 +41,10 @@ endif::topdoc[]
. Set up topology and attach to target
. Configure bridge and VLAN interfaces on target
. Configure IP addresses and VLAN interfaces on host
. Verify that host:data1 reaches host:data2 with untagged packets
. Verify that traffic on VLAN 10 from host:data1 does not reach host:data2
. Verify that host:data0 reaches host:data1 with untagged packets
. Verify that traffic on VLAN 10 from host:data0 does not reach host:data1
. Verify that host:data0 can reach target on VLAN 10
. Verify that host:data1 can reach target on VLAN 10
. Verify that host:data2 can reach target on VLAN 10
<<<
+6 -8
View File
@@ -3,16 +3,14 @@
<<<
include::mdns/mdns_enable_disable/Readme.adoc[]
include::mdns_enable_disable/Readme.adoc[]
include::mdns/mdns_allow_deny/Readme.adoc[]
include::mdns_allow_deny/Readme.adoc[]
include::lldp/lldp_enable_disable/Readme.adoc[]
include::lldp_enable_disable/Readme.adoc[]
include::lldp/lldp_admin_status/Readme.adoc[]
include::lldp_admin_status/Readme.adoc[]
include::lldp/lldp_ieee_group_forward/Readme.adoc[]
include::ssh_server_config/Readme.adoc[]
include::ssh/ssh_server_config/Readme.adoc[]
include::ssh/ssh_key_authentication/Readme.adoc[]
include::ssh_key_authentication/Readme.adoc[]
+3 -3
View File
@@ -1,9 +1,9 @@
---
- name: lldp
suite: lldp/lldp.yaml
suite: lldp.yaml
- name: mdns
suite: mdns/mdns.yaml
suite: mdns.yaml
- name: ssh
suite: ssh/ssh.yaml
suite: ssh.yaml
@@ -4,6 +4,3 @@
- name: lldp_admin_status
case: lldp_admin_status/test.py
- name: lldp_ieee_group_forward
case: lldp_ieee_group_forward/test.py
@@ -1 +0,0 @@
lldp_ieee_group_forward.adoc
@@ -1,27 +0,0 @@
=== LLDP IEEE Group Forward
==== Description
Verify that LLDP packets can be flooded to all ports on a bridge.
Operation and non-operation are confirmed using tcpdump.
==== Topology
ifdef::topdoc[]
image::{topdoc}../../test/case/infix_services/lldp/lldp_ieee_group_forward/topology.svg[LLDP IEEE Group Forward topology]
endif::topdoc[]
ifndef::topdoc[]
ifdef::testgroup[]
image::lldp/lldp_ieee_group_forward/topology.svg[LLDP IEEE Group Forward topology]
endif::testgroup[]
ifndef::testgroup[]
image::topology.svg[LLDP IEEE Group Forward topology]
endif::testgroup[]
endif::topdoc[]
==== Test sequence
. Set up topology and attach to target DUT
. Configure interfaces and disable LLDP daemon
. Verify LLDP absence on host:data2
. Enable LLDP flooding by setting group forward
. Verify LLDP arrival on host:data2
<<<
@@ -1,145 +0,0 @@
#!/usr/bin/env python3
"""LLDP IEEE Group Forward
Verify that LLDP packets can be flooded to all ports on a bridge.
Operation and non-operation are confirmed using tcpdump.
"""
import time
import threading
import infamy
from scapy.all import Ether, sendp
from scapy.contrib.lldp import (
LLDPDU, LLDPDUChassisID, LLDPDUPortID,
LLDPDUTimeToLive, LLDPDUEndOfLLDPDU
)
SNIFFING_DURATION = 3
LLDP_INTERVAL = 1
LLDP_TTL = 3
LLDP_MULTICAST_MAC = "01:80:C2:00:00:0E"
LLDP_ETHERTYPE = 0x88cc
CHASSIS_ID = "Chassis-Test"
SRC_MAC = "02:01:02:03:04:05"
BRIDGE = "br0"
def send_lldp_packet(iface):
eth = Ether(src=SRC_MAC, dst=LLDP_MULTICAST_MAC, type=LLDP_ETHERTYPE)
lldpdu = eth / LLDPDU()
lldpdu /= LLDPDUChassisID(subtype=7, id=CHASSIS_ID)
lldpdu /= LLDPDUPortID(subtype=5, id=iface)
lldpdu /= LLDPDUTimeToLive(ttl=LLDP_TTL)
lldpdu /= LLDPDUEndOfLLDPDU()
sendp(lldpdu, iface=iface, verbose=False)
def send_lldp_packets_continuously(iface, stop_event):
time.sleep(LLDP_INTERVAL/2)
while not stop_event.is_set():
send_lldp_packet(iface)
time.sleep(LLDP_INTERVAL)
def capture_traffic(iface):
with infamy.IsolatedMacVlan(iface) as netns:
sniffer = infamy.Sniffer(netns, f"ether proto {LLDP_ETHERTYPE}")
with sniffer:
time.sleep(SNIFFING_DURATION)
return sniffer.output()
def start_lldp_sender_thread(iface):
stop = threading.Event()
thread = threading.Thread(
target=send_lldp_packets_continuously,
args=(iface, stop)
)
thread.start()
return stop, thread
with infamy.Test() as test:
with test.step("Set up topology and attach to target DUT"):
env = infamy.Env()
target = env.attach("target", "mgmt")
_, hdata1 = env.ltop.xlate("host", "data1")
_, hdata2 = env.ltop.xlate("host", "data2")
with test.step("Configure interfaces and disable LLDP daemon"):
target.put_config_dicts({
"ietf-interfaces": {
"interfaces": {
"interface": [
{
"name": BRIDGE,
"type": "infix-if-type:bridge",
"enabled": True,
},
{
"name": target["data1"],
"enabled": True,
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": target["data2"],
"enabled": True,
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
}
]
}
},
"ieee802-dot1ab-lldp": {
"lldp": {
"enabled": False
}
}
})
stop_event, sender_thread = start_lldp_sender_thread(hdata1)
try:
with test.step("Verify LLDP absence on host:data2"):
captured_traffic = capture_traffic(hdata2)
if "LLDP" in captured_traffic.stdout:
test.fail()
finally:
stop_event.set()
sender_thread.join()
with test.step("Enable LLDP flooding by setting group forward"):
target.put_config_dicts({
"ietf-interfaces": {
"interfaces": {
"interface": [
{
"name": BRIDGE,
"infix-interfaces:bridge": {
"ieee-group-forward": [
"lldp"
]
}
}
]
}
}
})
stop_event, sender_thread = start_lldp_sender_thread(hdata1)
try:
with test.step("Verify LLDP arrival on host:data2"):
captured_traffic = capture_traffic(hdata2)
if "LLDP" not in captured_traffic.stdout:
test.fail()
finally:
stop_event.set()
sender_thread.join()
test.succeed()
@@ -1,24 +0,0 @@
graph "1x3" {
layout="neato";
overlap="false";
esep="+80";
node [shape=record, fontname="DejaVu Sans Mono, Book"];
edge [color="cornflowerblue", penwidth="2", fontname="DejaVu Serif, Book"];
host [
label="host | { <mgmt> mgmt | <data1> data1 | <data2> data2 }",
pos="0,12!",
requires="controller",
];
target [
label="{ <mgmt> mgmt | <data1> data1 | <data2> data2 } | target",
pos="10,12!",
requires="infix",
];
host:mgmt -- target:mgmt [requires="mgmt", color="lightgray"]
host:data1 -- target:data1 [color="black", requires="ieee-mc"]
host:data2 -- target:data2 [color="black", requires="ieee-mc"]
}

Some files were not shown because too many files have changed in this diff Show More