Compare commits

...
21 Commits
Author SHA1 Message Date
Mattias WalströmandGitHub 1cc84e95e4 Merge pull request #1448 from kernelkit/cand/v26.02.x
Move local GitHub actions to kernelkit/actions repo
2026-03-16 16:09:54 +01:00
Joachim WibergandClaude Sonnet 4.6 62adf55270 .github: move local actions to kernelkit/actions repo
Fixes a regression from 0c11cea where local composite actions
(.github/actions/) were referenced with relative paths. When spins
reuse our reusable workflows, GitHub resolves relative action paths
in the context of the calling repo, not infix — breaking the build.

Replace all uses of ./.github/actions/{cache-restore,podman-cleanup}
with kernelkit/actions/{cache-restore,podman-cleanup}@v1 (new repo).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 16:01:33 +01:00
Mattias WalströmandGitHub 7176666340 Merge pull request #1445 from kernelkit/lts-kernel-backport
LTS kernel backport + net.d tmpfiles fix
2026-03-13 08:27:24 +01:00
Joachim Wiberg 0b475a7ce6 Update ChangeLog for v26.02.1 GA
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-03-13 07:33:15 +01:00
Joachim Wiberg 2e9e5858b9 package/netd: ensure /etc/net.d exists at boot
Before netd starts confd might want to create .conf file for it to run,
so we sort of depend on /etc/net.d existing at boot.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-03-12 23:33:21 +01:00
Mattias WalströmandJoachim Wiberg 4c8b62d1b1 Upgrade Linux kernel to 6.18.17
Signed-off-by: Mattias Walström <lazzer@gmail.com>
2026-03-12 19:47:33 +01:00
Joachim WibergandGitHub e17780f197 Merge pull request #1442 from kernelkit/netd-backport
Backport fix to critical v26.02.0 regression
2026-03-12 16:10:14 +01:00
Joachim Wiberg b4ea26961f Update ChangeLog for v26.02.1 GA
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-03-12 13:53:38 +01:00
Joachim Wiberg be3891c2f0 netd: watch conf.d with inotify, retry on backend failure
Two races could prevent DHCP-learned default routes from being installed
at boot:

1. The signal from the DHCP client script could be lost leaving conf.d
   updated but frr.conf stale.

2. Even when the signal was received, 'vtysh -b' could fail because the
   FRR daemon chain (mgmtd→zebra→staticd) writes PID files before being
   fully operational, causing netd to give up with no retry.

Fix both by refactoring netd to use libev:

- Use an inotify watch of CONF_DIR, so netd reacts directly to file
  changes without depending on signal delivery.

- On backend_apply() failure, schedule a retry in 5s and call pidfile()
  unconditionally so dependent services are not blocked waiting for the
  Finit condition 'pid/netd' to be satisfied.

We also take this opportunity to rename /etc/netd/conf.d/ to /etc/net.d/
The extra /etc/netd/ directory level served no purpose — nothing else
lives there.  Flatten to /etc/net.d/ which reads more naturally as the
drop-in directory for network configuration snippets.

Also, reduce logging a bit since each netd backend already logs success
or fail which is sufficient to know that a configuration change has been
applied or not.

Finally, with the new inotify processing in netd it's redundant to call
'initctl reload netd' from the udhcpc script, in fact it will only cause
unnecessary overhead, so we drop it.

Fixes #1438

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-03-12 13:50:01 +01:00
Joachim WibergandGitHub f6f6381eaf Merge pull request #1433 from kernelkit/cand/v26.02.x
v26.02.1 Release Candidate
2026-03-11 14:07:13 +01:00
Joachim Wiberg e5754b4001 doc: prepare for v26.02.1 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-03-11 12:36:17 +01:00
Joachim Wiberg 6838cc9c25 confd: follow-up to OSPF point-to-multipoint
Add a must expression to ensure users do not set static neighbors when
the interface type is not point-to-multipoint or non-broadcast.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-03-11 12:36:17 +01:00
Mattias WalströmandJoachim Wiberg d869f6c478 Followup OSPF point-to-multipoint
[skip ci]
2026-03-11 12:36:16 +01:00
Mattias WalströmandJoachim Wiberg f37d29aa21 ospf: add point-to-multipoint and hybrid interface type support
Signed-off-by: Mattias Walström <lazzer@gmail.com>
2026-03-11 12:36:16 +01:00
ael-botandJoachim Wiberg 982a754472 Upgrade Linux kernel to 6.18.16 2026-03-10 14:33:33 +01:00
Joachim Wiberg 931ae71019 board: relocate SafeXcel firmware selection to Marvell BSPs
The MVEBU SafeXcel Crypto Engine firmware (linux-firmware minifw) was
originally added in 70c12c3 to the generic aarch64 defconfigs to silence
kernel probe failures on Marvell Armada SoCs (37xx, 7k, 8k, CN913x):

  crypto-safexcel f2800000.crypto: Firmware load failed.
  crypto-safexcel f2800000.crypto: HW init failed (-2)

It was then accidentally dropped in 0e2d12e (kernel upgrade to 6.18),
which rebased on a tree that predated the firmware addition.

Rather than restoring it to the generic defconfigs, move it to the two
Marvell board Config.in files where it actually belongs — consistent
with how RTL8169 firmware was handled for the Raspberry Pi CM4 IoT
Router Board Mini in 68313773.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-03-10 14:27:31 +01:00
Joachim Wiberg c69a617ecb patches: lift iptables name length limit in firewalld
A legacy name length limit in firewalld triggered problems with longer
policy names.  This patch to firewalld lifts that limit by checking the
backend in use, no limit for nftables.

Fixes #1389

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-03-10 14:27:31 +01:00
Joachim Wiberg c79beea4ec statd: silence 'show firewall' when firewall is disabled
Fixes #1416

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-03-10 14:27:30 +01:00
Joachim Wiberg cf1e81c8d1 package/skeleton-init-fint: increase zebra netlink buffer
Increase Zebra NETLINK buffer to fix reported issues with zebra being
out of sync with kernel routes and interface changes.

Also, try '-a' option to allow other processes to delete zebra routes.

Other changes in this commit:
 - Minor fixes to Finit service files for consistency
 - Empty daemon.conf stub files to silence bogus mgmtd errors at startup
 - Relocate all skeleton files from board/common to separate from files
   that are actual Infix additions and what's package system integration

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-03-10 14:27:30 +01:00
Mattias WalströmandJoachim Wiberg e04937a0f7 GPS: Disable GPS in _minimal config 2026-03-10 14:27:30 +01:00
Mattias WalströmandJoachim Wiberg e838f6dfd8 yang: add feature flags for wifi and gps in infix-hardware 2026-03-10 14:27:27 +01:00
105 changed files with 1636 additions and 257 deletions
-41
View File
@@ -1,41 +0,0 @@
name: 'Restore Build Caches'
description: 'Restore dl/ and .ccache/ caches for Buildroot builds'
inputs:
target:
description: 'Build target for cache key differentiation'
required: true
dl-prefix:
description: 'Prefix for dl/ cache key (e.g., "dl", "dl-boot")'
required: false
default: 'dl'
ccache-prefix:
description: 'Prefix for .ccache/ cache key (e.g., "ccache", "ccache-boot")'
required: false
default: 'ccache'
enabled:
description: 'Set to false to skip cache restoration'
required: false
default: 'true'
runs:
using: 'composite'
steps:
- name: Restore Cache of dl/
if: ${{ inputs.enabled == 'true' }}
uses: actions/cache@v4
with:
path: dl/
key: ${{ inputs.dl-prefix }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
restore-keys: |
${{ inputs.dl-prefix }}-
dl-
- name: Restore Cache of .ccache/
if: ${{ inputs.enabled == 'true' }}
uses: actions/cache@v4
with:
path: .ccache/
key: ${{ inputs.ccache-prefix }}-${{ inputs.target }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
restore-keys: |
${{ inputs.ccache-prefix }}-${{ inputs.target }}-
${{ inputs.ccache-prefix }}-
ccache-
-15
View File
@@ -1,15 +0,0 @@
name: 'Podman Cleanup'
description: 'Clean up stale podman state from previous runs'
runs:
using: 'composite'
steps:
- name: Cleanup podman state
shell: bash
run: |
set -x
podman ps -a || true
podman stop -a || true
podman rm -a -f || true
podman volume prune -f || true
podman system prune -a -f || true
podman system migrate || true
+1 -1
View File
@@ -66,7 +66,7 @@ jobs:
echo "Building ${defconfig}_defconfig, version ${version}-${rev}, artifact ${archive} ..."
- uses: ./.github/actions/cache-restore
- uses: kernelkit/actions/cache-restore@v1
with:
target: ${{ matrix.defconfig }}
dl-prefix: dl-boot
+2 -2
View File
@@ -28,7 +28,7 @@ jobs:
clean: true
submodules: recursive
- uses: ./.github/actions/podman-cleanup
- uses: kernelkit/actions/podman-cleanup@v1
- name: Set Release Variables
id: vars
@@ -40,7 +40,7 @@ jobs:
echo "dir=infix-$target" >> $GITHUB_OUTPUT
echo "tgz=infix-$target.tar.gz" >> $GITHUB_OUTPUT
- uses: ./.github/actions/cache-restore
- uses: kernelkit/actions/cache-restore@v1
with:
target: ${{ matrix.target }}
enabled: ${{ inputs.use_cache }}
+2 -2
View File
@@ -89,7 +89,7 @@ jobs:
submodules: recursive
token: ${{ secrets.CHECKOUT_TOKEN || github.token }}
- uses: ./.github/actions/podman-cleanup
- uses: kernelkit/actions/podman-cleanup@v1
- name: Run pre-build script
if: ${{ inputs.pre_build_script != '' }}
@@ -120,7 +120,7 @@ jobs:
echo "tgz=${name}-${target}.tar.gz" >> $GITHUB_OUTPUT
echo "Building target ${target}_defconfig"
- uses: ./.github/actions/cache-restore
- uses: kernelkit/actions/cache-restore@v1
with:
target: ${{ env.TARGET }}
+1 -1
View File
@@ -45,7 +45,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/cache-restore
- uses: kernelkit/actions/cache-restore@v1
with:
target: x86_64
dl-prefix: dl-netconf
+1 -1
View File
@@ -52,7 +52,7 @@ jobs:
with:
submodules: 'true'
- uses: ./.github/actions/podman-cleanup
- uses: kernelkit/actions/podman-cleanup@v1
- name: Set Release Variables
id: rel
+1 -1
View File
@@ -70,7 +70,7 @@ jobs:
submodules: recursive
token: ${{ secrets.CHECKOUT_TOKEN || github.token }}
- uses: ./.github/actions/podman-cleanup
- uses: kernelkit/actions/podman-cleanup@v1
- name: Run pre-test script
if: ${{ inputs.pre_test_script != '' }}
+2 -2
View File
@@ -87,7 +87,7 @@ jobs:
submodules: recursive
token: ${{ secrets.CHECKOUT_TOKEN || github.token }}
- uses: ./.github/actions/podman-cleanup
- uses: kernelkit/actions/podman-cleanup@v1
- name: Run pre-build script
if: ${{ inputs.pre_build_script != '' }}
@@ -98,7 +98,7 @@ jobs:
chmod +x ./pre-build.sh
bash ./pre-build.sh
- uses: ./.github/actions/cache-restore
- uses: kernelkit/actions/cache-restore@v1
with:
target: ${{ env.TARGET }}
+1
View File
@@ -1,5 +1,6 @@
config BR2_PACKAGE_ALDER_ALDER
bool "Alder"
depends on BR2_aarch64
select BR2_PACKAGE_LINUX_FIRMWARE_INSIDE_SECURE_MINIFW
help
Alder
@@ -1,5 +1,6 @@
config BR2_PACKAGE_MARVELL_CN9130_CRB
bool "Marvell CN9130-CRB"
depends on BR2_aarch64
select BR2_PACKAGE_LINUX_FIRMWARE_INSIDE_SECURE_MINIFW
help
Customer Reference Board for CN9130
@@ -1,5 +1,6 @@
config BR2_PACKAGE_MARVELL_ESPRESSOBIN
bool "Marvell ESPRESSObin"
depends on BR2_aarch64
select BR2_PACKAGE_LINUX_FIRMWARE_INSIDE_SECURE_MINIFW
help
Marvell ESPRESSObin
+1
View File
@@ -1,5 +1,6 @@
config BR2_PACKAGE_STYX_DCP_SC_28P
bool "Styx DCP-SC-28P"
depends on BR2_aarch64
select BR2_PACKAGE_LINUX_FIRMWARE_INSIDE_SECURE_MINIFW
help
Styx DCP-SC-28P
@@ -7,7 +7,7 @@ ACTION="$1"
IP_CACHE="/var/lib/misc/${interface}.cache"
RESOLV_CONF="/run/resolvconf/interfaces/${interface}.conf"
NTPFILE="/run/chrony/dhcp-sources.d/${interface}.sources"
NAME="/etc/netd/conf.d/${interface}-dhcp.conf"
NAME="/etc/net.d/${interface}-dhcp.conf"
NEXT="${NAME}+"
[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
@@ -118,8 +118,6 @@ set_dhcp_routes()
# Reduce changes needed by comparing with previous route(s)
cmp -s "$NAME" "$NEXT" && return
mv "$NEXT" "$NAME"
initctl reload netd
}
clr_dhcp_routes()
@@ -127,8 +125,6 @@ clr_dhcp_routes()
log "deleting DHCP routes"
[ -f "$NAME" ] || return
rm "$NAME"
initctl reload netd
}
clr_dhcp_addresses()
+1 -4
View File
@@ -27,7 +27,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.15"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.17"
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
@@ -41,9 +41,6 @@ BR2_PACKAGE_DBUS_CXX=y
BR2_PACKAGE_DBUS_GLIB=y
BR2_PACKAGE_EUDEV_RULES_GEN=y
# BR2_PACKAGE_EUDEV_ENABLE_HWDB is not set
BR2_PACKAGE_GPSD_DEVICES="/dev/gps0"
BR2_PACKAGE_GPSD_MAX_CLIENT_VALUE=2
BR2_PACKAGE_GPSD_MAX_DEV_VALUE=1
BR2_PACKAGE_GPTFDISK=y
BR2_PACKAGE_GPTFDISK_SGDISK=y
BR2_PACKAGE_MDIO_TOOLS=y
+1 -5
View File
@@ -27,7 +27,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.15"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.17"
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
@@ -41,9 +41,6 @@ BR2_PACKAGE_DBUS_CXX=y
BR2_PACKAGE_DBUS_GLIB=y
BR2_PACKAGE_EUDEV_RULES_GEN=y
# BR2_PACKAGE_EUDEV_ENABLE_HWDB is not set
BR2_PACKAGE_GPSD_DEVICES="/dev/gps0"
BR2_PACKAGE_GPSD_MAX_CLIENT_VALUE=2
BR2_PACKAGE_GPSD_MAX_DEV_VALUE=1
BR2_PACKAGE_GPTFDISK=y
BR2_PACKAGE_GPTFDISK_SGDISK=y
BR2_PACKAGE_MDIO_TOOLS=y
@@ -126,7 +123,6 @@ INFIX_DESC="Infix is an immutable, friendly, and secure operating system that tu
INFIX_HOME="https://github.com/kernelkit/infix/"
INFIX_DOC="https://www.kernelkit.org/infix/"
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
BR2_PACKAGE_FEATURE_GPS=y
BR2_PACKAGE_CONFD=y
BR2_PACKAGE_NETD=y
BR2_PACKAGE_CONFD_TEST_MODE=y
+1 -4
View File
@@ -28,7 +28,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.15"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.17"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/arm/linux_defconfig"
BR2_LINUX_KERNEL_INSTALL_TARGET=y
@@ -43,9 +43,6 @@ BR2_PACKAGE_DBUS_CXX=y
BR2_PACKAGE_DBUS_GLIB=y
BR2_PACKAGE_EUDEV_RULES_GEN=y
# BR2_PACKAGE_EUDEV_ENABLE_HWDB is not set
BR2_PACKAGE_GPSD_DEVICES="/dev/gps0"
BR2_PACKAGE_GPSD_MAX_CLIENT_VALUE=2
BR2_PACKAGE_GPSD_MAX_DEV_VALUE=1
BR2_PACKAGE_GPTFDISK=y
BR2_PACKAGE_GPTFDISK_SGDISK=y
BR2_PACKAGE_MDIO_TOOLS=y
+1 -5
View File
@@ -28,7 +28,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.15"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.17"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/arm/linux_defconfig"
BR2_LINUX_KERNEL_INSTALL_TARGET=y
@@ -43,9 +43,6 @@ BR2_PACKAGE_DBUS_CXX=y
BR2_PACKAGE_DBUS_GLIB=y
BR2_PACKAGE_EUDEV_RULES_GEN=y
# BR2_PACKAGE_EUDEV_ENABLE_HWDB is not set
BR2_PACKAGE_GPSD_DEVICES="/dev/gps0"
BR2_PACKAGE_GPSD_MAX_CLIENT_VALUE=2
BR2_PACKAGE_GPSD_MAX_DEV_VALUE=1
BR2_PACKAGE_GPTFDISK=y
BR2_PACKAGE_GPTFDISK_SGDISK=y
BR2_PACKAGE_MDIO_TOOLS=y
@@ -126,7 +123,6 @@ INFIX_DESC="Infix is an immutable, friendly, and secure operating system that tu
INFIX_HOME="https://github.com/kernelkit/infix/"
INFIX_DOC="https://www.kernelkit.org/infix/"
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
BR2_PACKAGE_FEATURE_GPS=y
BR2_PACKAGE_CONFD=y
BR2_PACKAGE_NETD=y
BR2_PACKAGE_CONFD_TEST_MODE=y
-3
View File
@@ -52,9 +52,6 @@ BR2_PACKAGE_DBUS_CXX=y
BR2_PACKAGE_DBUS_GLIB=y
BR2_PACKAGE_EUDEV_RULES_GEN=y
# BR2_PACKAGE_EUDEV_ENABLE_HWDB is not set
BR2_PACKAGE_GPSD_DEVICES="/dev/gps0"
BR2_PACKAGE_GPSD_MAX_CLIENT_VALUE=2
BR2_PACKAGE_GPSD_MAX_DEV_VALUE=1
BR2_PACKAGE_GPTFDISK=y
BR2_PACKAGE_GPTFDISK_SGDISK=y
BR2_PACKAGE_MDIO_TOOLS=y
+1 -4
View File
@@ -26,7 +26,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
BR2_ROOTFS_POST_BUILD_SCRIPT="board/qemu/x86_64/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.15"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.17"
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
@@ -41,9 +41,6 @@ BR2_PACKAGE_DBUS_CXX=y
BR2_PACKAGE_DBUS_GLIB=y
BR2_PACKAGE_EUDEV_RULES_GEN=y
# BR2_PACKAGE_EUDEV_ENABLE_HWDB is not set
BR2_PACKAGE_GPSD_DEVICES="/dev/gps0"
BR2_PACKAGE_GPSD_MAX_CLIENT_VALUE=2
BR2_PACKAGE_GPSD_MAX_DEV_VALUE=1
BR2_PACKAGE_GPTFDISK=y
BR2_PACKAGE_GPTFDISK_SGDISK=y
BR2_PACKAGE_RNG_TOOLS=y
+1 -5
View File
@@ -26,7 +26,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
BR2_ROOTFS_POST_BUILD_SCRIPT="board/qemu/x86_64/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.15"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.17"
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
@@ -41,9 +41,6 @@ BR2_PACKAGE_DBUS_CXX=y
BR2_PACKAGE_DBUS_GLIB=y
BR2_PACKAGE_EUDEV_RULES_GEN=y
# BR2_PACKAGE_EUDEV_ENABLE_HWDB is not set
BR2_PACKAGE_GPSD_DEVICES="/dev/gps0"
BR2_PACKAGE_GPSD_MAX_CLIENT_VALUE=2
BR2_PACKAGE_GPSD_MAX_DEV_VALUE=1
BR2_PACKAGE_GPTFDISK=y
BR2_PACKAGE_GPTFDISK_SGDISK=y
BR2_PACKAGE_RNG_TOOLS=y
@@ -125,7 +122,6 @@ INFIX_DESC="Infix is an immutable, friendly, and secure operating system that tu
INFIX_HOME="https://github.com/kernelkit/infix/"
INFIX_DOC="https://www.kernelkit.org/infix/"
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
BR2_PACKAGE_FEATURE_GPS=y
BR2_PACKAGE_CONFD=y
BR2_PACKAGE_NETD=y
BR2_PACKAGE_CONFD_TEST_MODE=y
+20
View File
@@ -3,6 +3,25 @@ Change Log
All notable changes to the project are documented in this file.
[v26.02.1][] - 2026-03-13
-------------------------
### Changes
- Upgrade Linux kernel to 6.18.17 (LTS)
- Add support for disabling WiFi and GPS features in builds
- Add OSPF point-to-multipoint (P2MP) and hybrid interface type support. This
also includes support for setting static neighbors, issue #1426
### Fixes
- Fix #1389: legacy name limit in firewalld triggered problems with policy names
- Fix #1416: `show firewall` command show an error when the firewall is disabled
- Fix #1438: default route from DHCP client not set at boot, regression in v26.02.0
- Fix instabilities in Zebra route manager after Frr upgrade in v26.02.0
- Fix regression in MVEBU SafeXcel Crypto Engine for Marvell Armada SOCs (37xx,
7k, 8k, and CN913x series). Firmware package lost in v26.01.0
[v26.02.0][] - 2026-03-01
-------------------------
@@ -1932,6 +1951,7 @@ Supported YANG models in addition to those used by sysrepo and netopeer:
[buildroot]: https://buildroot.org/
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v26.02.0...HEAD
[v26.02.1]: https://github.com/kernelkit/infix/compare/v26.02.0...v26.02.1
[v26.02.0]: https://github.com/kernelkit/infix/compare/v26.01.0...v26.02.0
[v26.01.0]: https://github.com/kernelkit/infix/compare/v25.11.0...v26.01.0
[v25.11.0]: https://github.com/kernelkit/infix/compare/v25.10.0...v25.11.0
+60
View File
@@ -131,6 +131,66 @@ an Ethernet interface can be done as follows.
admin@example:/config/routing/…/ospf/area/0.0.0.0/interface/e0/>
</code></pre>
### Point-to-Multipoint
Point-to-Multipoint (P2MP) is used when multiple OSPF routers share a
common network segment but should form individual adjacencies rather
than electing a Designated Router (DR). This is common in NBMA-like
environments, DMVPN, or hub-and-spoke topologies.
Infix supports two P2MP variants via the `interface-type` setting:
| **Interface Type** | **Behavior** |
|:----------------------|:-----------------------------------------------|
| `hybrid` | P2MP with multicast Hellos (broadcast-capable) |
| `point-to-multipoint` | P2MP with unicast Hellos (non-broadcast) |
#### Hybrid (broadcast-capable P2MP)
Use `hybrid` when all neighbors on the segment can receive multicast.
Hello packets are sent to the standard OSPF multicast address (224.0.0.5)
and neighbors are discovered automatically — no manual neighbor
configuration is needed.
<pre class="cli"><code>admin@example:/config/> <b>edit routing control-plane-protocol ospfv2 name default ospf</b>
admin@example:/config/routing/…/ospf/> <b>set area 0.0.0.0 interface e0 interface-type hybrid</b>
admin@example:/config/routing/…/ospf/> <b>leave</b>
admin@example:/>
</code></pre>
#### Non-broadcast P2MP
Use `point-to-multipoint` when the network does not support multicast.
Hello packets are sent as unicast directly to each configured neighbor.
Since neighbors cannot be discovered automatically, they must be
configured explicitly using static neighbors (see below).
<pre class="cli"><code>admin@example:/config/> <b>edit routing control-plane-protocol ospfv2 name default ospf</b>
admin@example:/config/routing/…/ospf/> <b>set area 0.0.0.0 interface e0 interface-type point-to-multipoint</b>
admin@example:/config/routing/…/ospf/> <b>leave</b>
admin@example:/>
</code></pre>
### Static Neighbors
When using non-broadcast interface types (such as `point-to-multipoint`),
OSPF cannot discover neighbors via multicast. Static neighbors must be
configured so the router knows where to send unicast Hello packets.
<pre class="cli"><code>admin@example:/config/> <b>edit routing control-plane-protocol ospfv2 name default ospf</b>
admin@example:/config/routing/…/ospf/> <b>set area 0.0.0.0 interface e0 static-neighbors neighbor 10.0.123.2</b>
admin@example:/config/routing/…/ospf/> <b>set area 0.0.0.0 interface e0 static-neighbors neighbor 10.0.123.3</b>
admin@example:/config/routing/…/ospf/> <b>leave</b>
admin@example:/>
</code></pre>
> [!NOTE]
> Static neighbors are only needed for non-broadcast interface types.
> With `hybrid` (or `broadcast`), neighbors are discovered automatically
> via multicast.
### OSPF global settings
In addition to *area* and *interface* specific settings, OSPF provides
+12
View File
@@ -30,6 +30,11 @@ CONFD_CONF_OPTS += --enable-wifi
else
CONFD_CONF_OPTS += --disable-wifi
endif
ifeq ($(BR2_PACKAGE_FEATURE_GPS),y)
CONFD_CONF_OPTS += --enable-gps
else
CONFD_CONF_OPTS += --disable-gps
endif
define CONFD_INSTALL_EXTRA
for fn in confd.conf resolvconf.conf; do \
cp $(CONFD_PKGDIR)/$$fn $(FINIT_D)/available/; \
@@ -80,6 +85,12 @@ define CONFD_INSTALL_YANG_MODULES_WIFI
$(BR2_EXTERNAL_INFIX_PATH)/utils/srload $(@D)/yang/wifi.inc
endef
endif
ifeq ($(BR2_PACKAGE_FEATURE_GPS),y)
define CONFD_INSTALL_YANG_MODULES_GPS
$(COMMON_SYSREPO_ENV) \
$(BR2_EXTERNAL_INFIX_PATH)/utils/srload $(@D)/yang/gps.inc
endef
endif
# PER_PACKAGE_DIR
# Since the last package in the dependency chain that runs sysrepoctl is confd, we need to
@@ -109,6 +120,7 @@ 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_YANG_MODULES_WIFI
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_YANG_MODULES_GPS
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_IN_ROMFS
CONFD_TARGET_FINALIZE_HOOKS += CONFD_CLEANUP
+2 -1
View File
@@ -2,9 +2,10 @@ config BR2_PACKAGE_NETD
bool "netd"
select BR2_PACKAGE_LIBITE
select BR2_PACKAGE_LIBCONFUSE
select BR2_PACKAGE_LIBEV
help
Network route daemon. Manages static routes and RIP routing.
Reads configuration from /etc/netd/conf.d/*.conf.
Reads configuration from /etc/net.d/*.conf.
With FRR: Full routing via gRPC, vtysh, or frr.conf.
Without FRR: Standalone Linux backend via rtnetlink.
+6 -2
View File
@@ -4,13 +4,13 @@
#
################################################################################
NETD_VERSION = 1.0
NETD_VERSION = 1.1.0
NETD_SITE_METHOD = local
NETD_SITE = $(BR2_EXTERNAL_INFIX_PATH)/src/netd
NETD_LICENSE = BSD-3-Clause
NETD_LICENSE_FILES = LICENSE
NETD_REDISTRIBUTE = NO
NETD_DEPENDENCIES = libite libconfuse jansson
NETD_DEPENDENCIES = libite libconfuse jansson libev
NETD_AUTORECONF = YES
NETD_CONF_ENV = CFLAGS="$(INFIX_CFLAGS)"
@@ -34,6 +34,10 @@ else
NETD_CONF_OPTS += --without-frr
endif
define NETD_INSTALL_EXTRA
cp $(NETD_PKGDIR)/tmpfiles.conf $(TARGET_DIR)/etc/tmpfiles.d/netd.conf
endef
NETD_TARGET_FINALIZE_HOOKS += NETD_INSTALL_EXTRA
$(eval $(autotools-package))
+1
View File
@@ -0,0 +1 @@
d /etc/net.d - - -
@@ -1,2 +1,2 @@
# --log-level debug
ZEBRA_ARGS="-A 127.0.0.1 -u frr -g frr --log syslog --log-level err"
ZEBRA_ARGS="-A 127.0.0.1 -a -s 90000000 -u frr -g frr --log syslog --log-level err"
@@ -1,2 +1,3 @@
service <!> pid:!/run/frr/mgmtd.pid env:-/etc/default/mgmtd \
[2345] mgmtd $MGMTD_ARGS -- FRR MGMT daemon
[2345] mgmtd $MGMTD_ARGS \
-- FRR MGMT daemon
@@ -1,2 +1,3 @@
service <!pid/zebra> env:-/etc/default/ospfd \
[2345] ospfd $OSPFD_ARGS -- OSPF daemon
service <!pid/zebra> pid:!/run/frr/ospfd.pid env:-/etc/default/ospfd \
[2345] ospfd $OSPFD_ARGS \
-- OSPF daemon
@@ -1,3 +1,3 @@
service <pid/zebra> env:-/etc/default/ripd \
[2345] ripd $RIPD_ARGS
service <pid/zebra> pid:!/run/frr/ripd.pid env:-/etc/default/ripd \
[2345] ripd $RIPD_ARGS \
-- RIP daemon
@@ -1,3 +1,3 @@
service <!pid/mgmtd> pid:!/run/frr/zebra.pid env:-/etc/default/zebra \
[2345] zebra $ZEBRA_ARGS
service <!pid/mgmtd> pid:!/run/frr/zebra.pid env:-/etc/default/zebra \
[2345] zebra $ZEBRA_ARGS \
-- Zebra routing daemon
@@ -1,5 +1,4 @@
# Default FRR daemons file for Infix - confd overwrites on routing changes.
# watchfrr, zebra, mgmtd, and staticd are always started by frrinit.sh.
# Default FRR daemons file used with watchfrr, started by frrinit.sh.
ospfd=no
ripd=no
bfdd=no
@@ -25,4 +24,3 @@ staticd_options="-A 127.0.0.1"
bfdd_options=" -A 127.0.0.1"
frr_profile="traditional"
@@ -0,0 +1 @@
! Empty stub — mgmtd reads its own config at startup; file must exist to avoid log noise.
@@ -0,0 +1 @@
! Empty stub — mgmtd reads per-daemon configs at startup; file must exist to avoid log noise.
@@ -0,0 +1 @@
! Empty stub — mgmtd reads per-daemon configs at startup; file must exist to avoid log noise.
@@ -0,0 +1 @@
! Empty stub — mgmtd reads per-daemon configs at startup; file must exist to avoid log noise.
@@ -0,0 +1 @@
! Empty stub — mgmtd reads per-daemon configs at startup; file must exist to avoid log noise.
@@ -1,7 +1,7 @@
From 03f273fc540082d1eaa23bd9b5847e695afd8283 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Thu, 25 Sep 2025 15:00:54 +0200
Subject: [PATCH] Silence warnings about old backends
Subject: [PATCH 1/2] Silence warnings about old backends
Organization: Wires
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
@@ -0,0 +1,95 @@
From 6ab218fe7f2c7027cc5347e3b082285870c502e6 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Fri, 6 Mar 2026 07:44:38 +0100
Subject: [PATCH 2/2] fix(functions): lift iptables name length limit when
using nftables
Organization: Wires
The max_zone_name_len() and max_policy_name_len() functions return 17
and 18 respectively, derived from iptables' 28-char netfilter chain name
limit. These limits are applied unconditionally in Zone.check_name()
and Policy.check_name() regardless of the active backend.
When FirewallBackend=nftables nftables imposes no such restriction, so
user-defined zone and policy names (e.g. "appletv-to-lan-guest", 20
chars) that exceed the iptables-derived limit are incorrectly rejected.
Add _nftables_backend() which reads firewalld.conf directly so the check
can be skipped without threading backend context through to check_name()
call sites, which have no access to all_io_objects. When nftables is
active, both functions return sys.maxsize, effectively disabling the
length check.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/firewall/functions.py | 31 ++++++++++++++++++++++++++++++-
1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/src/firewall/functions.py b/src/firewall/functions.py
index 27c862fd..1b8a32ce 100644
--- a/src/firewall/functions.py
+++ b/src/firewall/functions.py
@@ -10,9 +10,10 @@ import os
import os.path
import shlex
import string
+import sys
import tempfile
from firewall.core.logger import log
-from firewall.config import FIREWALLD_TEMPDIR, FIREWALLD_PIDFILE
+from firewall.config import FIREWALLD_CONF, FIREWALLD_TEMPDIR, FIREWALLD_PIDFILE
NOPRINT_TRANS_TABLE = {
# Limit to C0 and C1 code points. Building entries for all unicode code
@@ -576,12 +577,35 @@ def ppid_of_pid(pid):
return pid
+def _nftables_backend():
+ """Return True if FirewallBackend=nftables is configured in firewalld.conf.
+
+ When using nftables the iptables-derived 28-char chain name limit does not
+ apply. Reading the config file directly avoids threading backend context
+ through check_name() call sites, which have no access to all_io_objects.
+ """
+ try:
+ with open(FIREWALLD_CONF) as f:
+ for line in f:
+ line = line.strip()
+ if line.startswith("FirewallBackend="):
+ return line.split("=", 1)[1].strip() == "nftables"
+ except OSError:
+ pass
+ return False
+
+
def max_policy_name_len():
"""
iptables limits length of chain to (currently) 28 chars.
The longest chain we create is POST_<policy>_allow,
which leaves 28 - 11 = 17 chars for <policy>.
+
+ When using the nftables backend, nftables imposes no practical name length
+ restriction, so we return sys.maxsize to lift the check entirely.
"""
+ if _nftables_backend():
+ return sys.maxsize
from firewall.core.ipXtables import POLICY_CHAIN_PREFIX
from firewall.core.base import SHORTCUTS
@@ -594,7 +618,12 @@ def max_zone_name_len():
Netfilter limits length of chain to (currently) 28 chars.
The longest chain we create is POST_<zone>_allow,
which leaves 28 - 11 = 17 chars for <zone>.
+
+ When using the nftables backend, nftables imposes no practical name length
+ restriction, so we return sys.maxsize to lift the check entirely.
"""
+ if _nftables_backend():
+ return sys.maxsize
from firewall.core.base import SHORTCUTS
longest_shortcut = max(map(len, SHORTCUTS.values()))
--
2.43.0
@@ -1,8 +1,9 @@
From 443245154df3a713a61feffa5043da4c200b30fa Mon Sep 17 00:00:00 2001
From 346def32eb16c04f267c1da13735945c9a54231f Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 19 Sep 2023 18:38:10 +0200
Subject: [PATCH 01/33] 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 a81a31111af41ce03bfd0a6bf493a440195c0aa8 Mon Sep 17 00:00:00 2001
From 77b517d44bdffdf6b34e6349c1dd2fa3b82f8a49 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 21 Nov 2023 20:15:24 +0100
Subject: [PATCH 02/33] 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 05bbe3556f357ba52eb12aef54831c2a7270f4fe Mon Sep 17 00:00:00 2001
From 9e51a2fa9f7aa8bace041a943b517faa47f30624 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 15 Nov 2023 20:58:42 +0100
Subject: [PATCH 03/33] 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 e4d030d502f358a4ed21eb75e2c3cffbe5c2b8da Mon Sep 17 00:00:00 2001
From d6da0f58dc1a27bf6a73ac8842e7830772199550 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 12 Dec 2023 09:51:05 +0100
Subject: [PATCH 04/33] 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 44c1b964008099707a86150597f07fb9afa2d4ab Mon Sep 17 00:00:00 2001
From bbfb5ff1a1deac6617e889e9eae61ad90932372d Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 27 Mar 2024 10:10:19 +0100
Subject: [PATCH 05/33] 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.
@@ -19,7 +20,7 @@ administratively down.
1 file changed, 1 deletion(-)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 7a67c900e79a..5c61faf4b10a 100644
index 2353d6eced68..9b0983453393 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1750,7 +1750,6 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
@@ -27,6 +28,6 @@ index 7a67c900e79a..5c61faf4b10a 100644
goto error;
- phy_resume(phydev);
if (!phydev->is_on_sfp_module)
phy_led_triggers_register(phydev);
/**
* If the external phy used by current mac interface is managed by
@@ -1,8 +1,9 @@
From a0ed79ec338c0a1ec647ecffe5de532bc93ae34e Mon Sep 17 00:00:00 2001
From 86d59814723739aae2e0dccc1d5143e99239e517 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 4 Mar 2024 16:47:28 +0100
Subject: [PATCH 06/33] 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
@@ -61,7 +62,7 @@ index c37e52e2f29a..0759bc37d6f0 100644
/* shouldn't be called with unsupported options */
WARN_ON(1);
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index a818fdc22da9..3cdb97ded410 100644
index 525d4eccd194..6278dfc9612f 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -89,10 +89,10 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -140,7 +141,7 @@ index dea09096ad0f..f0a613238e0d 100644
continue;
break;
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 1405f1061a54..1ae4b4173821 100644
index 2cbae0f9ae1f..0c539bf4bebe 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -186,9 +186,13 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
@@ -1,8 +1,9 @@
From 1d7a80c8f0a1f1fdb9feededbe6a81ef95ea235f Mon Sep 17 00:00:00 2001
From 9fa94b200cb73d0d03f724610e53b8019a6ebad2 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Tue, 5 Mar 2024 06:44:41 +0100
Subject: [PATCH 07/33] 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
@@ -1,8 +1,9 @@
From 7d5b408393f724aa3fb9109d0373270bff5912a4 Mon Sep 17 00:00:00 2001
From 53004f71947c52aab8e6e3fabc3fd5d78a3c643f Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Thu, 4 Apr 2024 16:36:30 +0200
Subject: [PATCH 08/33] 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].
@@ -1,8 +1,9 @@
From fcb5ec6195e9201d547148f23115305d012258e1 Mon Sep 17 00:00:00 2001
From 7229b8a8650191d42ff67d584751ab49dbcd7ed8 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 16 May 2024 14:51:54 +0200
Subject: [PATCH 09/33] 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
@@ -1,8 +1,9 @@
From ea7944d9e73280180e6e80e7de5e1a20e308ecab Mon Sep 17 00:00:00 2001
From 5b8492fa5bc5b79455e79a8e37498ecb93ee5359 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Fri, 24 Nov 2023 23:29:55 +0100
Subject: [PATCH 10/33] 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,8 +1,9 @@
From 6d8bdf087b6b5f4a1a714858fcf9c548afee0041 Mon Sep 17 00:00:00 2001
From 9f4c2b07839ef00084ed542c48149f0f335dd760 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Sun, 11 Aug 2024 11:27:35 +0200
Subject: [PATCH 11/33] 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 6a43054d5171..ef8bcb4a7339 100644
index da8de7b1a489..36d79a77316c 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -41,6 +41,11 @@
@@ -33,7 +34,7 @@ index 6a43054d5171..ef8bcb4a7339 100644
#define R8152_PHY_ID 32
#define PLA_IDR 0xc000
@@ -7277,6 +7282,9 @@ static void r8153b_init(struct r8152 *tp)
@@ -7279,6 +7284,9 @@ static void r8153b_init(struct r8152 *tp)
ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN);
ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data);
@@ -1,8 +1,9 @@
From e6250ce25bc96c91c74ad8bdea6132087bc3c8d3 Mon Sep 17 00:00:00 2001
From 3ad4ee7ae3a89aada6d57176c07cef526d9c96eb Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Sun, 10 Aug 2025 18:52:54 +0200
Subject: [PATCH 12/33] arm64: dts: mediatek: mt7986a: rename BPi R3 ports to
match case
Organization: Wires
For ref. see: https://wiki.banana-pi.org/File:Bpi-r3_Metal_case.jpg
@@ -1,8 +1,9 @@
From dcafe00d03f102ce48cb9068c884009e753b53bf Mon Sep 17 00:00:00 2001
From 3250cc2366b749241d615615ce2ea0d768bb4921 Mon Sep 17 00:00:00 2001
From: Mattias Walström <lazzer@gmail.com>
Date: Wed, 20 Aug 2025 21:38:24 +0200
Subject: [PATCH 13/33] drm/panel-simple: Add a timing for the Raspberry Pi 7"
panel
Organization: Wires
The Raspberry Pi 7" 800x480 panel uses a Toshiba TC358762 DSI
to DPI bridge chip, so there is a requirement for the timings
@@ -1,7 +1,8 @@
From 38d942ffce63ee1fa9beecf6bac3d7b30e87c87a Mon Sep 17 00:00:00 2001
From 642ead96253f70bf7c0fcca3c2fa85e73914bb33 Mon Sep 17 00:00:00 2001
From: Mattias Walström <lazzer@gmail.com>
Date: Thu, 21 Aug 2025 11:20:23 +0200
Subject: [PATCH 14/33] input:touchscreen:edt-ft5x06: Add polled mode
Organization: Wires
Not all hardware has interrupts therefore we need
to poll the touchscreen.
@@ -1,8 +1,9 @@
From 60cd0f84c208ab9bc53ad070e81bb0173e356889 Mon Sep 17 00:00:00 2001
From 43a979e0aa5701c0c1c0c0e9d57800bd0ef01faa Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 12 Mar 2024 10:27:24 +0100
Subject: [PATCH 15/33] [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 de9af4997489a4f2a4110412b418bb7a317664fe Mon Sep 17 00:00:00 2001
From 76efa741dff5a8ad7d31a3d6b676c564397c88e6 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 27 Mar 2024 15:52:43 +0100
Subject: [PATCH 16/33] 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 94db20c708ac578007ef56ebd6a4321f45ca2ba7 Mon Sep 17 00:00:00 2001
From 7901aa874746fcd698d57099e01690ca591d9361 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Mon, 22 Apr 2024 23:18:01 +0200
Subject: [PATCH 17/33] 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 a52c2c0be135f32dac53410a6f67226ecb59da58 Mon Sep 17 00:00:00 2001
From bff65cd654873c1fe2910f1ab8a757539fa920b7 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 24 Apr 2024 22:41:04 +0200
Subject: [PATCH 18/33] 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,8 +1,9 @@
From 668ba9f49cd17cb27145fbe579931b9ddf74ea88 Mon Sep 17 00:00:00 2001
From a93d06218d7b7627c5327aa10c612471840eee05 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 28 May 2024 10:38:42 +0200
Subject: [PATCH 19/33] 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 79450dc7dd78cb3d1e3798180151e4927f3d862f Mon Sep 17 00:00:00 2001
From c467011d7ea11c7c3f728dc73b433cc3c0b67b80 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 16 Jan 2024 16:00:55 +0100
Subject: [PATCH 20/33] 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 7d282dfc8044ad74aa190203efdc350bf9ab8c97 Mon Sep 17 00:00:00 2001
From d84d7cf2a2b00203ac6e2261fd3474e6c0c954ca Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 21 Mar 2024 19:12:15 +0100
Subject: [PATCH 21/33] net: dsa: Support EtherType based priority overrides
Organization: Wires
---
include/net/dsa.h | 4 ++++
@@ -1,8 +1,9 @@
From 2b0679aa4727f71f3858291002c3abb5eade7ca7 Mon Sep 17 00:00:00 2001
From e556a41a4c568492a2723ca5de155edd22ddd913 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Fri, 22 Mar 2024 16:15:43 +0100
Subject: [PATCH 22/33] net: dsa: mv88e6xxx: Support EtherType based priority
overrides
Organization: Wires
---
drivers/net/dsa/mv88e6xxx/chip.c | 64 +++++++++++++++++++++++++++++
@@ -1,7 +1,8 @@
From 7f6fd96a6b80c541b0fba0e5cc9de10aa0801eb0 Mon Sep 17 00:00:00 2001
From d3546da36444aa4679725ec839f08da518d4923b Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 28 May 2024 11:04:22 +0200
Subject: [PATCH 23/33] 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 54a42d398869bf484d31a499af28ba95ce75c412 Mon Sep 17 00:00:00 2001
From b7519c9fa980c3875d27b11ffd6981b0ed48e9b5 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 29 May 2024 13:20:41 +0200
Subject: [PATCH 24/33] 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 dbc7e27badea74027b2742fe768db95e48edc4d7 Mon Sep 17 00:00:00 2001
From 521ca7fd27093c4ddcddd662a6dfd21f000275b8 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 26 Nov 2024 19:45:59 +0100
Subject: [PATCH 25/33] [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 6ffe3f8912a00fd32f5607c9aa25b7ed8b408a47 Mon Sep 17 00:00:00 2001
From 89b2a6e022f85b415a46f49df0c93676834bf57c Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Thu, 16 Jan 2025 12:35:12 +0100
Subject: [PATCH 26/33] 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 6a87d9cd29e08b0b322233d35621d90470a974e6 Mon Sep 17 00:00:00 2001
From 63367ac49816e95fd4da9194d58d1f5074cf8119 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 12 Feb 2025 22:03:14 +0100
Subject: [PATCH 27/33] 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,7 +1,8 @@
From d98d5f87b9f5202c55864da0f8a6e9b63a123d2e Mon Sep 17 00:00:00 2001
From b5ccc175297291d19697cd775c6f2a5691828e68 Mon Sep 17 00:00:00 2001
From: Mattias Walström <lazzer@gmail.com>
Date: Wed, 14 Jan 2026 18:22:41 +0100
Subject: [PATCH 28/33] net: dsa: mv88e6xxx: Add LED support for 6393X
Organization: Wires
Original commit:
commit 462277b926140ee2d231317e92afb6cabf640268
@@ -1,4 +1,4 @@
From f844b2470f23814f3d98c22fc1958958155f2370 Mon Sep 17 00:00:00 2001
From 8c51a0724ae7b1ad5115282c954d4edc81364585 Mon Sep 17 00:00:00 2001
From: Mattias Walström <lazzer@gmail.com>
Date: Thu, 15 Jan 2026 22:47:37 +0100
Subject: [PATCH 29/33] wifi: brcmfmac: support deletion and recreation of
@@ -6,6 +6,7 @@ Subject: [PATCH 29/33] wifi: brcmfmac: support deletion and recreation of
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Wires
The Broadcom FullMAC firmware does not allow the primary interface
(bsscfgidx 0) to be deleted - it always exists in firmware. However,
@@ -1,4 +1,4 @@
From 58dcf72c338bd0248dad8105a4169be926d19be2 Mon Sep 17 00:00:00 2001
From 36e885ca1f4115203e05e2886ae32563247b3b97 Mon Sep 17 00:00:00 2001
From: Mattias Walström <lazzer@gmail.com>
Date: Mon, 19 Jan 2026 13:06:53 +0100
Subject: [PATCH 30/33] wifi: brcmfmac: check connection state before querying
@@ -6,6 +6,7 @@ Subject: [PATCH 30/33] wifi: brcmfmac: check connection state before querying
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Wires
In station mode, brcmf_cfg80211_get_station() queries the firmware for
station info even when not connected to an AP. This results in error
@@ -1,4 +1,4 @@
From b408ba43a37bb71f8ea2b83c7f4a4ba0b806f2c7 Mon Sep 17 00:00:00 2001
From 5463dd561cd1076e7f18a5119acc969c5f0ab989 Mon Sep 17 00:00:00 2001
From: Mattias Walström <lazzer@gmail.com>
Date: Tue, 20 Jan 2026 20:12:10 +0100
Subject: [PATCH 31/33] wifi: brcmfmac: suppress log spam for
@@ -6,6 +6,7 @@ Subject: [PATCH 31/33] wifi: brcmfmac: suppress log spam for
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Wires
When scanning, the driver attempts to set each channel and logs an
error if the firmware rejects it. For regulatory-restricted channels,
@@ -1,4 +1,4 @@
From 2558ffc3abdbbc38a367d6a83c9133e39238339f Mon Sep 17 00:00:00 2001
From 1f631f03e316387caf2af8ebc082796ce843c26c Mon Sep 17 00:00:00 2001
From: Mattias Walström <lazzer@gmail.com>
Date: Tue, 20 Jan 2026 20:18:45 +0100
Subject: [PATCH 32/33] wifi: brcmfmac: reduce log noise during AP to station
@@ -6,6 +6,7 @@ Subject: [PATCH 32/33] wifi: brcmfmac: reduce log noise during AP to station
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Wires
When transitioning from AP mode to station mode (e.g., hostapd stopping
and wpa_supplicant starting), several non-fatal errors can occur:
@@ -1,8 +1,9 @@
From fdfab37c4e5c375c204c797f77f91ee6edcbe983 Mon Sep 17 00:00:00 2001
From d88dde71434c48f78d44803e467adbc6633d4b10 Mon Sep 17 00:00:00 2001
From: Mattias Walström <lazzer@gmail.com>
Date: Tue, 17 Feb 2026 21:59:59 +0100
Subject: [PATCH 33/33] net: phy: air_en8811h: add OF device table for
auto-loading
Organization: Wires
mdio_uevent() only emits an OF-style MODALIAS via
of_device_uevent_modalias(), never the mdio: binary format that
+1 -1
View File
@@ -1,2 +1,2 @@
# Calculated with utils/kernel-refresh.sh
sha256 7c716216c3c4134ed0de69195701e677577bbcdd3979f331c182acd06bf2f170 linux-6.18.15.tar.xz
sha256 2bff97ab0590bc5ccdd5b82286d5ef324828672126ebddc88d062e3ac65af80d linux-6.18.17.tar.xz
+8
View File
@@ -46,6 +46,10 @@ AC_ARG_ENABLE(wifi,
AS_HELP_STRING([--enable-wifi], [Enable support for Wi-Fi]),,[
enable_wifi=no])
AC_ARG_ENABLE(gps,
AS_HELP_STRING([--enable-gps], [Enable support for GPS receivers]),,[
enable_gps=no])
AC_ARG_WITH(login-shell,
AS_HELP_STRING([--with-login-shell=shell], [Login shell for new users, default: /bin/false]),
[login_shell=$withval], [login_shell=yes])
@@ -60,6 +64,9 @@ AS_IF([test "x$enable_containers" = "xyes"], [
AS_IF([test "x$enable_wifi" = "xyes"], [
AC_DEFINE(HAVE_WIFI, 1, [Built with Wi-Fi support])])
AS_IF([test "x$enable_gps" = "xyes"], [
AC_DEFINE(HAVE_GPS, 1, [Built with GPS receiver support])])
AS_IF([test "x$with_login_shell" != "xno"], [
AS_IF([test "x$login_shell" = "xyes"], [login_shell=/bin/false])
AC_DEFINE_UNQUOTED(LOGIN_SHELL, "$login_shell", [Default: /bin/false])],[
@@ -131,6 +138,7 @@ cat <<EOF
Optional features:
Container support ....: $enable_containers
Wi-Fi support ........: $enable_wifi
GPS support ..........: $enable_gps
Login shell ..........: $login_shell
Default crypt algo ...: $crypt
+36 -2
View File
@@ -8,7 +8,7 @@
#define XPATH_BASE_ "/ietf-routing:routing/control-plane-protocols/control-plane-protocol"
#define XPATH_OSPF_ XPATH_BASE_ "/ietf-ospf:ospf"
#define NETD_CONF "/etc/netd/conf.d/confd.conf"
#define NETD_CONF "/etc/net.d/confd.conf"
#define NETD_CONF_NEXT NETD_CONF "+"
#define NETD_CONF_PREV NETD_CONF "-"
#define OSPFD_CONF "/etc/frr/ospfd.conf"
@@ -154,6 +154,17 @@ int parse_rip(sr_session_ctx_t *session, struct lyd_node *rip, FILE *fp)
return num_interfaces;
}
static const char *ospf_network_type(const char *yang_type)
{
if (!strcmp(yang_type, "hybrid"))
return "point-to-multipoint";
if (!strcmp(yang_type, "point-to-multipoint"))
return "point-to-multipoint non-broadcast";
/* broadcast, non-broadcast, point-to-point pass through unchanged */
return yang_type;
}
int parse_ospf_interfaces(sr_session_ctx_t *session, struct lyd_node *areas, FILE *fp)
{
struct lyd_node *interface, *interfaces, *area;
@@ -203,7 +214,7 @@ int parse_ospf_interfaces(sr_session_ctx_t *session, struct lyd_node *areas, FIL
if (passive)
fputs(" ip ospf passive\n", fp);
if (interface_type)
fprintf(fp, " ip ospf network %s\n", interface_type);
fprintf(fp, " ip ospf network %s\n", ospf_network_type(interface_type));
if (cost)
fprintf(fp, " ip ospf cost %s\n", cost);
}
@@ -226,6 +237,28 @@ int parse_ospf_redistribute(sr_session_ctx_t *session, struct lyd_node *redistri
return 0;
}
static void parse_ospf_static_neighbors(struct lyd_node *areas, FILE *fp)
{
struct lyd_node *area, *interface, *interfaces, *neighbors, *neighbor;
LY_LIST_FOR(lyd_child(areas), area) {
interfaces = lydx_get_child(area, "interfaces");
LY_LIST_FOR(lyd_child(interfaces), interface) {
neighbors = lydx_get_child(interface, "static-neighbors");
if (!neighbors)
continue;
LY_LIST_FOR(lyd_child(neighbors), neighbor) {
const char *id = lydx_get_cattr(neighbor, "identifier");
if (id)
fprintf(fp, " neighbor %s\n", id);
}
}
}
}
int parse_ospf_areas(sr_session_ctx_t *session, struct lyd_node *areas, FILE *fp)
{
int areas_configured = 0;
@@ -315,6 +348,7 @@ int parse_ospf(sr_session_ctx_t *session, struct lyd_node *ospf)
fputs("router ospf\n", fp);
num_areas = parse_ospf_areas(session, areas, fp);
parse_ospf_redistribute(session, lydx_get_child(ospf, "redistribute"), fp);
parse_ospf_static_neighbors(areas, fp);
default_route = lydx_get_child(ospf, "default-route-advertise");
if (default_route) {
/* enable is obsolete in favor for enabled. */
+2 -2
View File
@@ -14,7 +14,7 @@ MODULES=(
"ietf-routing@2018-03-13.yang"
"ietf-ipv6-unicast-routing@2018-03-13.yang"
"ietf-ipv4-unicast-routing@2018-03-13.yang"
"ietf-ospf@2022-10-19.yang -e bfd -e explicit-router-id"
"ietf-ospf@2022-10-19.yang -e bfd -e explicit-router-id -e hybrid-interface"
"ietf-rip@2020-02-20.yang"
"iana-bfd-types@2021-10-21.yang"
"ietf-bfd-types@2022-09-22.yang"
@@ -31,7 +31,7 @@ MODULES=(
"ieee802-dot1q-types@2022-10-29.yang"
"infix-ip@2025-11-02.yang"
"infix-if-type@2026-01-07.yang"
"infix-routing@2025-12-02.yang"
"infix-routing@2026-03-11.yang"
"ieee802-dot1ab-lldp@2022-03-15.yang"
"infix-lldp@2025-05-05.yang"
"infix-dhcp-common@2025-12-21.yang"
+11
View File
@@ -45,6 +45,13 @@ module infix-hardware {
description "Initial";
reference "internal";
}
feature wifi {
description "WiFi support is an optional build-time feature in Infix.";
}
feature gps {
description "GPS support is an optional build-time feature in Infix.";
}
typedef country-code {
type string {
@@ -104,11 +111,13 @@ module infix-hardware {
description "This identity is used to a VPD memory on the device.";
}
identity wifi {
if-feature wifi;
base iahw:hardware-class;
description "This identity is used to describe a WiFi radio/PHY";
}
identity gps {
if-feature gps;
base iahw:hardware-class;
description "GPS/GNSS receiver for time synchronization";
}
@@ -211,6 +220,7 @@ module infix-hardware {
*/
container wifi-radio {
if-feature wifi;
when "derived-from-or-self(../iehw:class, 'ih:wifi')";
presence "WiFi radio configuration";
description
@@ -534,6 +544,7 @@ module infix-hardware {
*/
container gps-receiver {
if-feature gps;
when "derived-from-or-self(../iehw:class, 'ih:gps')";
presence "GPS receiver configuration";
description
+12 -20
View File
@@ -26,6 +26,12 @@ module infix-routing {
contact "kernelkit@googlegroups.com";
description "Deviations and augments for ietf-routing, ietf-ospf, and ietf-rip.";
revision 2026-03-11 {
description "Remove interface-type deviation to expose standard ietf-ospf
interface types including point-to-multipoint and hybrid.
Un-deviate static-neighbors for non-broadcast P2MP support.";
}
revision 2025-12-02 {
description "Add configurable OSPF debug logging container.
Add RIP (Routing Information Protocol) support.";
@@ -247,18 +253,6 @@ module infix-routing {
}
/* OSPF */
typedef infix-ospf-interface-type {
type enumeration {
enum broadcast {
description
"Specifies an OSPF broadcast multi-access network.";
}
enum point-to-point {
description
"Specifies an OSPF point-to-point network.";
}
}
}
deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol" {
@@ -367,11 +361,6 @@ module infix-routing {
}
}
deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:interface-type" {
deviate replace {
type infix-ospf-interface-type;
}
}
deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:auto-cost" {
deviate not-supported;
@@ -463,9 +452,12 @@ module infix-routing {
}
/* OSPF Area Interface */
deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:static-neighbors"
{
deviate not-supported;
deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:static-neighbors/ospf:neighbor" {
deviate add {
must "../../ospf:interface-type = 'point-to-multipoint' or ../../ospf:interface-type = 'non-broadcast'" {
error-message "Static neighbors are only applicable to point-to-multipoint or non-broadcast interface types.";
}
}
}
deviation "/rt:routing/rt:control-plane-protocols/rt:control-plane-protocol/ospf:ospf/ospf:areas/ospf:area/ospf:interfaces/ospf:interface/ospf:multi-areas" {
deviate not-supported;
+3
View File
@@ -0,0 +1,3 @@
MODULES=(
"infix-hardware -e gps"
)
+1
View File
@@ -1,4 +1,5 @@
MODULES=(
"infix-interfaces -e wifi"
"infix-hardware -e wifi"
"infix-if-type -e wifi"
)
+1 -1
View File
@@ -6,7 +6,7 @@ netd_SOURCES = src/netd.c src/netd.h src/config.c src/config.h
netd_CPPFLAGS = -D_DEFAULT_SOURCE -D_GNU_SOURCE -I$(srcdir)/src
netd_CFLAGS = -W -Wall -Wextra
netd_CFLAGS += $(libite_CFLAGS) $(libconfuse_CFLAGS) $(jansson_CFLAGS)
netd_LDADD = $(libite_LIBS) $(libconfuse_LIBS) $(jansson_LIBS)
netd_LDADD = $(libite_LIBS) $(libconfuse_LIBS) $(jansson_LIBS) $(EV_LIBS)
# Backend selection: FRR gRPC, FRR frr.conf, or Linux kernel
if HAVE_FRR_GRPC
+4 -4
View File
@@ -60,7 +60,7 @@ make install
netd uses [libconfuse](https://github.com/martinh/libconfuse) for configuration parsing, providing a clean and structured format.
Configuration files are placed in `/etc/netd/conf.d/` with the `.conf` extension. Files are processed in alphabetical order.
Configuration files are placed in `/etc/net.d/` with the `.conf` extension. Files are processed in alphabetical order.
### Configuration Format
@@ -219,10 +219,10 @@ rip {
### Configuration Files
Configuration files must be placed in `/etc/netd/conf.d/` with the `.conf` extension:
Configuration files must be placed in `/etc/net.d/` with the `.conf` extension:
```bash
/etc/netd/conf.d/
/etc/net.d/
├── 10-static.conf # Static routes
├── 20-rip.conf # RIP configuration
└── 99-local.conf # Local overrides
@@ -256,7 +256,7 @@ netd validates configuration on reload. Check syslog for errors.
```
┌─────────┐
│ confd │ Writes /etc/netd/conf.d/confd.conf
│ confd │ Writes /etc/net.d/confd.conf
└────┬────┘
│ SIGHUP
+11 -1
View File
@@ -1,5 +1,5 @@
AC_PREREQ(2.61)
AC_INIT([netd], [1.0.0], [https://github.com/kernelkit/infix/issues])
AC_INIT([netd], [1.1.0], [https://github.com/kernelkit/infix/issues])
AM_INIT_AUTOMAKE(1.11 foreign subdir-objects)
AM_SILENT_RULES(yes)
@@ -81,6 +81,16 @@ PKG_CHECK_MODULES([libite], [libite >= 2.6.1])
PKG_CHECK_MODULES([libconfuse], [libconfuse >= 3.0])
PKG_CHECK_MODULES([jansson], [jansson >= 2.0])
AC_CHECK_HEADER([ev.h],
[saved_LIBS="$LIBS"
AC_CHECK_LIB([ev], [ev_loop_new],
[EV_LIBS="-lev"],
[AC_MSG_ERROR("libev not found")])
LIBS="$saved_LIBS"],
[AC_MSG_ERROR("ev.h not found")]
)
AC_SUBST([EV_LIBS])
test "x$prefix" = xNONE && prefix=$ac_default_prefix
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+86 -41
View File
@@ -2,6 +2,8 @@
#include <errno.h>
#include <getopt.h>
#include <sys/inotify.h>
#include <ev.h>
#include <libite/lite.h>
#include "netd.h"
@@ -9,9 +11,6 @@
int debug;
static sig_atomic_t do_reload;
static sig_atomic_t do_shutdown;
static struct route_head active_routes = TAILQ_HEAD_INITIALIZER(active_routes);
static struct rip_config active_rip;
@@ -46,19 +45,7 @@ static int backend_apply(struct route_head *routes, struct rip_config *rip) {
}
#endif
static void sighup_handler(int sig)
{
(void)sig;
INFO("Got SIGHUP, reloading ...");
do_reload = 1;
}
static void sigterm_handler(int sig)
{
(void)sig;
do_shutdown = 1;
}
static ev_timer retry_w;
static void route_list_free(struct route_head *head)
{
@@ -118,7 +105,7 @@ static void rip_config_free(struct rip_config *cfg)
}
}
static void reload(void)
static void reload(struct ev_loop *loop)
{
struct route_head new_routes = TAILQ_HEAD_INITIALIZER(new_routes);
struct rip_redistribute *redist;
@@ -129,7 +116,7 @@ static void reload(void)
struct route *r;
int count = 0;
INFO("Reloading configuration");
DEBUG("Reloading configuration");
rip_config_init(&new_rip);
@@ -148,11 +135,16 @@ static void reload(void)
/* Apply config via backend */
if (backend_apply(&new_routes, &new_rip)) {
ERROR("Failed applying config via backend");
ERROR("Failed applying config via backend, retry in 5s");
route_list_free(&new_routes);
rip_config_free(&new_rip);
ev_timer_stop(loop, &retry_w);
ev_timer_set(&retry_w, 5., 0.);
ev_timer_start(loop, &retry_w);
pidfile(NULL);
return;
}
ev_timer_stop(loop, &retry_w);
route_list_free(&active_routes);
TAILQ_INIT(&active_routes);
@@ -214,26 +206,59 @@ static void reload(void)
}
}
INFO("Configuration reloaded");
pidfile(NULL);
}
static void inotify_cb(struct ev_loop *loop, ev_io *w, int revents)
{
char buf[sizeof(struct inotify_event) + NAME_MAX + 1];
(void)revents;
while (read(w->fd, buf, sizeof(buf)) > 0)
;
DEBUG("conf.d changed, triggering reload");
reload(loop);
}
static void sighup_cb(struct ev_loop *loop, ev_signal *w, int revents)
{
(void)w; (void)revents;
INFO("Got SIGHUP, reloading ...");
reload(loop);
}
static void sigterm_cb(struct ev_loop *loop, ev_signal *w, int revents)
{
(void)w; (void)revents;
ev_break(loop, EVBREAK_ALL);
}
static void retry_cb(struct ev_loop *loop, ev_timer *w, int revents)
{
(void)w; (void)revents;
reload(loop);
}
static int usage(int rc)
{
fprintf(stderr,
"Usage: netd [-dh]\n"
"Usage: netd [-dhv]\n"
" -d Enable debug (log to stderr)\n"
" -h Show this help text\n");
" -h Show this help text\n"
" -v Show version and exit\n");
return rc;
}
int main(int argc, char *argv[])
{
struct ev_loop *loop = EV_DEFAULT;
ev_signal sighup_w, sigterm_w, sigint_w;
ev_io inotify_w;
int log_opts = LOG_PID | LOG_NDELAY;
struct sigaction sa = { 0 };
int ifd = -1;
int c;
while ((c = getopt(argc, argv, "dhp:")) != -1) {
while ((c = getopt(argc, argv, "dhv")) != -1) {
switch (c) {
case 'd':
log_opts |= LOG_PERROR;
@@ -241,6 +266,9 @@ int main(int argc, char *argv[])
break;
case 'h':
return usage(0);
case 'v':
puts("v" PACKAGE_VERSION);
return 0;
default:
return usage(1);
}
@@ -248,15 +276,7 @@ int main(int argc, char *argv[])
openlog("netd", log_opts, LOG_DAEMON);
setlogmask(LOG_UPTO(LOG_INFO));
INFO("starting");
/* Set up signal handlers */
sa.sa_handler = sighup_handler;
sigaction(SIGHUP, &sa, NULL);
sa.sa_handler = sigterm_handler;
sigaction(SIGTERM, &sa, NULL);
sigaction(SIGINT, &sa, NULL);
INFO("v%s starting", PACKAGE_VERSION);
if (backend_init()) {
ERROR("Failed to initialize backend");
@@ -267,19 +287,44 @@ int main(int argc, char *argv[])
TAILQ_INIT(&active_routes);
rip_config_init(&active_rip);
/* Initial load */
do_reload = 1;
/* Signal watchers */
ev_signal_init(&sighup_w, sighup_cb, SIGHUP);
ev_signal_start(loop, &sighup_w);
while (!do_shutdown) {
if (do_reload) {
do_reload = 0;
reload();
}
pause();
ev_signal_init(&sigterm_w, sigterm_cb, SIGTERM);
ev_signal_start(loop, &sigterm_w);
ev_signal_init(&sigint_w, sigterm_cb, SIGINT);
ev_signal_start(loop, &sigint_w);
/* Retry timer — one-shot, started only on backend failure */
ev_timer_init(&retry_w, retry_cb, 0., 0.);
/* Watch conf.d for changes so we don't rely solely on signals */
mkdir(CONF_DIR, 0755);
ifd = inotify_init1(IN_CLOEXEC | IN_NONBLOCK);
if (ifd < 0) {
ERROR("inotify_init1: %s, falling back to signals only", strerror(errno));
} else if (inotify_add_watch(ifd, CONF_DIR,
IN_CLOSE_WRITE | IN_DELETE |
IN_MOVED_TO | IN_MOVED_FROM) < 0) {
ERROR("inotify_add_watch %s: %s", CONF_DIR, strerror(errno));
close(ifd);
ifd = -1;
} else {
ev_io_init(&inotify_w, inotify_cb, ifd, EV_READ);
ev_io_start(loop, &inotify_w);
}
/* Initial load */
reload(loop);
ev_run(loop, 0);
INFO("shutting down");
if (ifd >= 0)
close(ifd);
route_list_free(&active_routes);
rip_config_free(&active_rip);
backend_cleanup();
+1 -1
View File
@@ -21,7 +21,7 @@ extern int debug;
#define INFO(fmt, args...) LOG(LOG_INFO, fmt, ##args)
#define DEBUG(fmt, args...) do { if (debug) LOG(LOG_DEBUG, fmt, ##args); } while (0)
#define CONF_DIR "/etc/netd/conf.d"
#define CONF_DIR "/etc/net.d"
/* Nexthop types */
enum nh_type {
+39 -16
View File
@@ -4832,7 +4832,7 @@ def show_ospf_interfaces(json_data):
state = target_iface.get('state', 'down')
cost = target_iface.get('cost', 0)
priority = target_iface.get('priority', 1)
iface_type = target_iface.get('interface-type', 'unknown')
iface_type = target_iface.get('interface-type', '')
hello_interval = target_iface.get('hello-interval', 10)
dead_interval = target_iface.get('dead-interval', 40)
retransmit_interval = target_iface.get('retransmit-interval', 5)
@@ -4908,9 +4908,11 @@ def show_ospf_interfaces(json_data):
network_type_map = {
'point-to-point': 'POINTOPOINT',
'broadcast': 'BROADCAST',
'non-broadcast': 'NBMA'
'non-broadcast': 'NBMA',
'point-to-multipoint': 'POINTOMULTIPOINT',
'hybrid': 'POINTOMULTIPOINT'
}
network_type = network_type_map.get(iface_type, iface_type.upper())
network_type = network_type_map.get(iface_type, iface_type.upper() if iface_type else 'LOOPBACK')
print(f"{name} is up")
if ip_address:
@@ -4950,30 +4952,50 @@ def show_ospf_interfaces(json_data):
return
# Display table view (no specific interface)
hdr = f"{'INTERFACE':<12} {'AREA':<12} {'STATE':<10} {'COST':<6} {'PRI':<4} {'DR':<15} {'BDR':<15} {'NBRS':<5}"
print(Decore.invert(hdr))
type_display_map = {
'point-to-point': 'P2P',
'broadcast': 'Broadcast',
'non-broadcast': 'NBMA',
'point-to-multipoint': 'P2MP',
'hybrid': 'Hybrid'
}
def fmt_state(state):
if state in ('dr', 'bdr'):
return state.upper()
if state == 'dr-other':
return 'DROther'
return state.capitalize()
table = SimpleTable([
Column('INTERFACE'),
Column('AREA'),
Column('TYPE'),
Column('STATE'),
Column('COST', 'right'),
Column('PRI', 'right'),
Column('DR'),
Column('BDR'),
Column('NBRS', 'right')
])
for iface in all_interfaces:
name = iface.get('name', 'unknown')
area_id = iface.get('_area_id', '0.0.0.0')
state = iface.get('state', 'down')
iface_type = iface.get('interface-type', '')
cost = iface.get('cost', 0)
priority = iface.get('priority', 1)
dr_id = iface.get('dr-router-id', '-')
bdr_id = iface.get('bdr-router-id', '-')
neighbors = iface.get('neighbors', {}).get('neighbor', [])
nbr_count = len(neighbors)
# Capitalize state nicely
state_display = state.upper() if state in ['dr', 'bdr'] else state.capitalize()
if state == 'dr-other':
state_display = 'DROther'
table.row(name, area_id,
type_display_map.get(iface_type, iface_type.capitalize() if iface_type else '-'),
fmt_state(state),
cost, priority, dr_id, bdr_id, len(neighbors))
# Shorten router IDs for display
dr_display = dr_id if dr_id != '-' else '-'
bdr_display = bdr_id if bdr_id != '-' else '-'
print(f"{name:<12} {area_id:<12} {state_display:<10} {cost:<6} {priority:<4} {dr_display:<15} {bdr_display:<15} {nbr_count:<5}")
table.print()
def show_ospf_neighbor(json_data):
@@ -5527,7 +5549,8 @@ def main():
global UNIT_TEST
try:
json_data = json.load(sys.stdin)
raw = sys.stdin.read()
json_data = json.loads(raw) if raw.strip() else {}
except json.JSONDecodeError:
print("Error, invalid JSON input")
sys.exit(1)
+8 -1
View File
@@ -124,8 +124,15 @@ def add_areas(control_protocols):
interface["enabled"] = iface["ospfEnabled"]
if iface["networkType"] == "POINTOPOINT":
interface["interface-type"] = "point-to-point"
if iface["networkType"] == "BROADCAST":
elif iface["networkType"] == "BROADCAST":
interface["interface-type"] = "broadcast"
elif iface["networkType"] == "POINTOMULTIPOINT":
if iface.get("p2mpNonBroadcast", False):
interface["interface-type"] = "point-to-multipoint"
else:
interface["interface-type"] = "hybrid"
elif iface["networkType"] == "NBMA":
interface["interface-type"] = "non-broadcast"
if iface.get("state"):
# Wev've never seen "DependUpon", and has no entry in
+1 -1
View File
@@ -8,7 +8,7 @@ Firewall configuration suitable for end devices on untrusted networks.
image::basic.svg[align=center, scaledwidth=50%]
- Single zone configuration, "public", with action=drop
- Single zone configuration, "public-untrusted-net", with `action=drop`
- Allowed services: SSH (port 22), DHCPv6-client, mySSH (custom, port 222)
- All other ports (HTTP, HTTPS, Telnet, etc.) blocked
- Check that unused interfaces are automatically assigned to default zone
+12 -10
View File
@@ -5,7 +5,7 @@ Firewall configuration suitable for end devices on untrusted networks.
image::basic.svg[align=center, scaledwidth=50%]
- Single zone configuration, "public", with action=drop
- Single zone configuration, "public-untrusted-net", with `action=drop`
- Allowed services: SSH (port 22), DHCPv6-client, mySSH (custom, port 222)
- All other ports (HTTP, HTTPS, Telnet, etc.) blocked
- Check that unused interfaces are automatically assigned to default zone
@@ -47,7 +47,7 @@ with infamy.Test() as test:
target.put_config_dict("infix-firewall", {
"firewall": {
"default": "public",
"default": "public-untrusted-net",
"logging": "all",
"service": [{
"name": "mySSH",
@@ -69,7 +69,9 @@ with infamy.Test() as test:
"interface": [mgmt_if],
"service": ["ssh", "netconf", "restconf"]
}, {
"name": "public",
# 20-char name, exceeds old iptables-derived 17-char limit
# Verifies we allow long names with nftables, issue #1389
"name": "public-untrusted-net",
"description": "Public untrusted network",
"action": "drop",
"interface": [data_if],
@@ -80,7 +82,7 @@ with infamy.Test() as test:
# Wait for configuration to be activated
infamy.Firewall.wait_for_operational(target, {
"public": {"action": "drop"},
"public-untrusted-net": {"action": "drop"},
"mgmt": {"action": "accept"}
})
@@ -88,7 +90,7 @@ with infamy.Test() as test:
data = target.get_data("/infix-firewall:firewall")
fw = data["firewall"]
assert fw["default"] == "public"
assert fw["default"] == "public-untrusted-net"
services = {svc["name"]: svc for svc in fw.get("service", [])}
assert "mySSH" in services, "Custom service mySSH not found"
@@ -106,8 +108,8 @@ with infamy.Test() as test:
assert int(port_entry["lower"]) == 8080
zones = {zone["name"]: zone for zone in fw["zone"]}
assert "public" in zones, "Public zone not found in configuration"
public_zone = zones["public"]
assert "public-untrusted-net" in zones, "public-untrusted-net zone not found in configuration"
public_zone = zones["public-untrusted-net"]
assert public_zone["action"] == "drop"
assert data_if in public_zone["interface"]
assert "ssh" in public_zone["service"]
@@ -119,13 +121,13 @@ with infamy.Test() as test:
data = target.get_data("/infix-firewall:firewall")
fw = data["firewall"]
assert fw["default"] == "public", "Default zone should be 'public'"
assert fw["default"] == "public-untrusted-net", "Default zone should be 'public-untrusted-net'"
zones = {zone["name"]: zone for zone in fw["zone"]}
public_zone = zones["public"]
public_zone = zones["public-untrusted-net"]
assert unused_if in public_zone["interface"], \
f"Unused interface {unused_if} should be in default zone 'public', got interfaces: {public_zone['interface']}"
f"Unused interface {unused_if} should be in default zone 'public-untrusted-net', got interfaces: {public_zone['interface']}"
with infamy.IsolatedMacVlan(host_data) as ns:
ns.addip(HOST_IP)
+10
View File
@@ -10,6 +10,8 @@ Tests verifying standard routing protocols and configuration:
- OSPF with BFD (Bidirectional Forwarding Detection)
- OSPF default route advertisement and propagation
- OSPF debug logging configuration and verification
- OSPF point-to-multipoint hybrid (broadcast) interface type
- OSPF point-to-multipoint (non-broadcast) interface type with static neighbors
- RIP basic neighbor discovery and route exchange
- RIP passive interface configuration
- RIP route redistribution (connected, static, and OSPF)
@@ -46,6 +48,14 @@ include::ospf_debug/Readme.adoc[]
<<<
include::ospf_point_to_multipoint_hybrid/Readme.adoc[]
<<<
include::ospf_point_to_multipoint/Readme.adoc[]
<<<
include::rip_basic/Readme.adoc[]
<<<
+6
View File
@@ -29,6 +29,12 @@
- name: OSPF Debug Logging
case: ospf_debug/test.py
- name: OSPF Point-to-Multipoint Hybrid
case: ospf_point_to_multipoint_hybrid/test.py
- name: OSPF Point-to-Multipoint
case: ospf_point_to_multipoint/test.py
- name: RIP Basic
case: rip_basic/test.py
@@ -0,0 +1 @@
test.adoc
@@ -0,0 +1,49 @@
=== OSPF Point-to-Multipoint
ifdef::topdoc[:imagesdir: {topdoc}../../test/case/routing/ospf_point_to_multipoint]
==== Description
Verify OSPF point-to-multipoint (non-broadcast) interface type by
configuring three routers on a shared multi-access network with the
ietf-ospf 'point-to-multipoint' interface type and static neighbors.
This maps to FRR's 'point-to-multipoint non-broadcast' network type,
which requires manual neighbor configuration since there is no
multicast neighbor discovery.
R2 acts as the hub, bridging two physical links (link1, link2) into a
single broadcast domain (br0). R1 and R3 each connect to one of R2's
ports. The test verifies that all routers form OSPF adjacencies via
unicast, exchange routes, and that the interface type is correctly
reported as point-to-multipoint.
....
+------------------+ +------------------+
| R1 | | R3 |
| 10.0.1.1/32 | | 10.0.3.1/32 |
| (lo) | | (lo) |
+--------+---------+ +--------+---------+
| .1 | .3
| +------------------+ |
+----link1------+ R2 +------link2--------+
| 10.0.2.1/32 |
| (lo) |
| br0: 10.0.123.2 |
+------------------+
10.0.123.0/24
(P2MP non-broadcast / shared segment)
....
==== Topology
image::topology.svg[OSPF Point-to-Multipoint topology, align=center, scaledwidth=75%]
==== Sequence
. Set up topology and attach to target DUTs
. Configure targets
. Wait for OSPF routes
. Verify interface type is point-to-multipoint
. Verify connectivity between all DUTs
+341
View File
@@ -0,0 +1,341 @@
#!/usr/bin/env python3
"""OSPF Point-to-Multipoint
Verify OSPF point-to-multipoint (non-broadcast) interface type by
configuring three routers on a shared multi-access network with the
ietf-ospf 'point-to-multipoint' interface type and static neighbors.
This maps to FRR's 'point-to-multipoint non-broadcast' network type,
which requires manual neighbor configuration since there is no
multicast neighbor discovery.
R2 acts as the hub, bridging two physical links (link1, link2) into a
single broadcast domain (br0). R1 and R3 each connect to one of R2's
ports. The test verifies that all routers form OSPF adjacencies via
unicast, exchange routes, and that the interface type is correctly
reported as point-to-multipoint.
....
+------------------+ +------------------+
| R1 | | R3 |
| 10.0.1.1/32 | | 10.0.3.1/32 |
| (lo) | | (lo) |
+--------+---------+ +--------+---------+
| .1 | .3
| +------------------+ |
+----link1------+ R2 +------link2--------+
| 10.0.2.1/32 |
| (lo) |
| br0: 10.0.123.2 |
+------------------+
10.0.123.0/24
(P2MP non-broadcast / shared segment)
....
"""
import infamy
import infamy.route as route
from infamy.util import until, parallel
def config_target1(target, link, data):
target.put_config_dicts({
"ietf-interfaces": {
"interfaces": {
"interface": [
{
"name": link,
"enabled": True,
"ipv4": {
"forwarding": True,
"address": [{
"ip": "10.0.123.1",
"prefix-length": 24
}]
}
},
{
"name": data,
"enabled": True,
"ipv4": {
"forwarding": True,
"address": [{
"ip": "10.0.10.1",
"prefix-length": 24
}]
}
},
{
"name": "lo",
"enabled": True,
"ipv4": {
"address": [{
"ip": "10.0.1.1",
"prefix-length": 32
}]
}
}
]
}
},
"ietf-routing": {
"routing": {
"control-plane-protocols": {
"control-plane-protocol": [{
"type": "infix-routing:ospfv2",
"name": "default",
"ospf": {
"redistribute": {
"redistribute": [{
"protocol": "connected"
}]
},
"areas": {
"area": [{
"area-id": "0.0.0.0",
"interfaces": {
"interface": [{
"name": link,
"enabled": True,
"hello-interval": 1,
"dead-interval": 3,
"interface-type": "point-to-multipoint",
"static-neighbors": {
"neighbor": [
{"identifier": "10.0.123.2"},
{"identifier": "10.0.123.3"}
]
}
}, {
"name": "lo",
"enabled": True
}]
}
}]
}
}
}]
}
}
}
})
def config_target2(target, link1, link2):
target.put_config_dicts({
"ietf-interfaces": {
"interfaces": {
"interface": [
{
"name": "br0",
"type": "infix-if-type:bridge",
"enabled": True,
"ipv4": {
"forwarding": True,
"address": [{
"ip": "10.0.123.2",
"prefix-length": 24
}]
}
},
{
"name": link1,
"enabled": True,
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": link2,
"enabled": True,
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "lo",
"enabled": True,
"ipv4": {
"address": [{
"ip": "10.0.2.1",
"prefix-length": 32
}]
}
}
]
}
},
"ietf-routing": {
"routing": {
"control-plane-protocols": {
"control-plane-protocol": [{
"type": "infix-routing:ospfv2",
"name": "default",
"ospf": {
"redistribute": {
"redistribute": [{
"protocol": "connected"
}]
},
"areas": {
"area": [{
"area-id": "0.0.0.0",
"interfaces": {
"interface": [{
"name": "br0",
"enabled": True,
"hello-interval": 1,
"dead-interval": 3,
"interface-type": "point-to-multipoint",
"static-neighbors": {
"neighbor": [
{"identifier": "10.0.123.1"},
{"identifier": "10.0.123.3"}
]
}
}, {
"name": "lo",
"enabled": True
}]
}
}]
}
}
}]
}
}
}
})
def config_target3(target, link, data):
target.put_config_dicts({
"ietf-interfaces": {
"interfaces": {
"interface": [
{
"name": link,
"enabled": True,
"ipv4": {
"forwarding": True,
"address": [{
"ip": "10.0.123.3",
"prefix-length": 24
}]
}
},
{
"name": data,
"enabled": True,
"ipv4": {
"forwarding": True,
"address": [{
"ip": "10.0.30.1",
"prefix-length": 24
}]
}
},
{
"name": "lo",
"enabled": True,
"ipv4": {
"address": [{
"ip": "10.0.3.1",
"prefix-length": 32
}]
}
}
]
}
},
"ietf-routing": {
"routing": {
"control-plane-protocols": {
"control-plane-protocol": [{
"type": "infix-routing:ospfv2",
"name": "default",
"ospf": {
"redistribute": {
"redistribute": [{
"protocol": "connected"
}]
},
"areas": {
"area": [{
"area-id": "0.0.0.0",
"interfaces": {
"interface": [{
"name": link,
"enabled": True,
"hello-interval": 1,
"dead-interval": 3,
"interface-type": "point-to-multipoint",
"static-neighbors": {
"neighbor": [
{"identifier": "10.0.123.1"},
{"identifier": "10.0.123.2"}
]
}
}, {
"name": "lo",
"enabled": True
}]
}
}]
}
}
}]
}
}
}
})
with infamy.Test() as test:
with test.step("Set up topology and attach to target DUTs"):
env = infamy.Env()
R1 = env.attach("R1", "mgmt")
R2 = env.attach("R2", "mgmt")
R3 = env.attach("R3", "mgmt")
with test.step("Configure targets"):
_, R1link = env.ltop.xlate("R1", "link")
_, R1data = env.ltop.xlate("R1", "data")
_, R2link1 = env.ltop.xlate("R2", "link1")
_, R2link2 = env.ltop.xlate("R2", "link2")
_, R3link = env.ltop.xlate("R3", "link")
_, R3data = env.ltop.xlate("R3", "data")
parallel(config_target1(R1, R1link, R1data),
config_target2(R2, R2link1, R2link2),
config_target3(R3, R3link, R3data))
with test.step("Wait for OSPF routes"):
print("Waiting for OSPF routes from all routers")
until(lambda: route.ipv4_route_exist(R1, "10.0.2.1/32", proto="ietf-ospf:ospfv2"), attempts=200)
until(lambda: route.ipv4_route_exist(R1, "10.0.3.1/32", proto="ietf-ospf:ospfv2"), attempts=200)
until(lambda: route.ipv4_route_exist(R2, "10.0.1.1/32", proto="ietf-ospf:ospfv2"), attempts=200)
until(lambda: route.ipv4_route_exist(R2, "10.0.3.1/32", proto="ietf-ospf:ospfv2"), attempts=200)
until(lambda: route.ipv4_route_exist(R3, "10.0.1.1/32", proto="ietf-ospf:ospfv2"), attempts=200)
until(lambda: route.ipv4_route_exist(R3, "10.0.2.1/32", proto="ietf-ospf:ospfv2"), attempts=200)
with test.step("Verify interface type is point-to-multipoint"):
print("Checking OSPF interface type on all routers")
assert route.ospf_get_interface_type(R1, "0.0.0.0", R1link) == "point-to-multipoint"
assert route.ospf_get_interface_type(R2, "0.0.0.0", "br0") == "point-to-multipoint"
assert route.ospf_get_interface_type(R3, "0.0.0.0", R3link) == "point-to-multipoint"
with test.step("Verify connectivity between all DUTs"):
_, hport1 = env.ltop.xlate("PC", "data1")
_, hport2 = env.ltop.xlate("PC", "data2")
with infamy.IsolatedMacVlan(hport1) as ns1, \
infamy.IsolatedMacVlan(hport2) as ns2:
ns1.addip("10.0.10.2")
ns2.addip("10.0.30.2")
ns1.addroute("10.0.3.1/32", "10.0.10.1")
ns2.addroute("10.0.1.1/32", "10.0.30.1")
parallel(
lambda: ns1.must_reach("10.0.3.1"),
lambda: ns2.must_reach("10.0.1.1"),
)
test.succeed()
@@ -0,0 +1,39 @@
graph "3x1" {
layout="neato";
overlap="false";
esep="+20";
size=10
node [shape=record, fontname="DejaVu Sans Mono, Book"];
edge [color="cornflowerblue", penwidth="2", fontname="DejaVu Serif, Book"];
PC [
label="PC | { <mgmt1> mgmt1 | <data1> data1 | \n\n\n\n | <mgmt2> mgmt2 | <mgmt3> mgmt3 | <data2> data2 }",
pos="20,30!",
requires="controller",
];
R1 [
label="{ <mgmt> mgmt | <data> data | <link> link } | R1 \n 10.0.1.1/32 \n(lo)",
pos="160,60!",
requires="infix",
];
R2 [
label="{ <link1> link1 | <mgmt> mgmt | <link2> link2 } | R2 \n 10.0.2.1/32 \n(lo) \n(br0: 10.0.123.2/24)",
pos="160,30!",
requires="infix",
];
R3 [
label="{ <link> link | <mgmt> mgmt | <data> data } | R3 \n 10.0.3.1/32 \n(lo)",
pos="160,0!",
requires="infix",
];
PC:mgmt1 -- R1:mgmt [requires="mgmt", color="lightgray"]
PC:mgmt2 -- R2:mgmt [requires="mgmt", color="lightgray"]
PC:mgmt3 -- R3:mgmt [requires="mgmt", color="lightgray"]
PC:data1 -- R1:data [taillabel="10.0.10.2/24", headlabel="10.0.10.1/24"]
R3:data -- PC:data2 [taillabel="10.0.30.1/24", headlabel="10.0.30.2/24"]
R1:link -- R2:link1 [taillabel="10.0.123.1/24"]
R3:link -- R2:link2 [taillabel="10.0.123.3/24"]
}
@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Title: 3x1 Pages: 1 -->
<svg width="720pt" height="312pt"
viewBox="0.00 0.00 720.00 312.15" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(0.98 0.98) rotate(0) translate(4 314.02)">
<title>3x1</title>
<polygon fill="white" stroke="transparent" points="-4,4 -4,-314.02 729.56,-314.02 729.56,4 -4,4"/>
<!-- PC -->
<g id="node1" class="node">
<title>PC</title>
<polygon fill="none" stroke="black" points="0,-61.51 0,-248.51 91,-248.51 91,-61.51 0,-61.51"/>
<text text-anchor="middle" x="16.5" y="-151.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">PC</text>
<polyline fill="none" stroke="black" points="33,-61.51 33,-248.51 "/>
<text text-anchor="middle" x="62" y="-233.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt1</text>
<polyline fill="none" stroke="black" points="33,-225.51 91,-225.51 "/>
<text text-anchor="middle" x="62" y="-210.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">data1</text>
<polyline fill="none" stroke="black" points="33,-202.51 91,-202.51 "/>
<polyline fill="none" stroke="black" points="33,-130.51 91,-130.51 "/>
<text text-anchor="middle" x="62" y="-115.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt2</text>
<polyline fill="none" stroke="black" points="33,-107.51 91,-107.51 "/>
<text text-anchor="middle" x="62" y="-92.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt3</text>
<polyline fill="none" stroke="black" points="33,-84.51 91,-84.51 "/>
<text text-anchor="middle" x="62" y="-69.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">data2</text>
</g>
<!-- R1 -->
<g id="node2" class="node">
<title>R1</title>
<polygon fill="none" stroke="black" points="518.56,-240.52 518.56,-309.52 692.56,-309.52 692.56,-240.52 518.56,-240.52"/>
<text text-anchor="middle" x="543.56" y="-294.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
<polyline fill="none" stroke="black" points="518.56,-286.52 568.56,-286.52 "/>
<text text-anchor="middle" x="543.56" y="-271.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">data</text>
<polyline fill="none" stroke="black" points="518.56,-263.52 568.56,-263.52 "/>
<text text-anchor="middle" x="543.56" y="-248.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">link</text>
<polyline fill="none" stroke="black" points="568.56,-240.52 568.56,-309.52 "/>
<text text-anchor="middle" x="630.56" y="-286.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">R1 </text>
<text text-anchor="middle" x="630.56" y="-271.32" font-family="DejaVu Sans Mono, Book" font-size="14.00"> 10.0.1.1/32 </text>
<text text-anchor="middle" x="630.56" y="-256.32" font-family="DejaVu Sans Mono, Book" font-size="14.00">(lo)</text>
</g>
<!-- PC&#45;&#45;R1 -->
<g id="edge1" class="edge">
<title>PC:mgmt1&#45;&#45;R1:mgmt</title>
<path fill="none" stroke="lightgray" stroke-width="2" d="M91.5,-237.01C91.5,-237.01 518.56,-298.02 518.56,-298.02"/>
</g>
<!-- PC&#45;&#45;R1 -->
<g id="edge4" class="edge">
<title>PC:data1&#45;&#45;R1:data</title>
<path fill="none" stroke="cornflowerblue" stroke-width="2" d="M91.5,-214.01C91.5,-214.01 518.56,-275.02 518.56,-275.02"/>
<text text-anchor="middle" x="473.06" y="-278.82" font-family="DejaVu Serif, Book" font-size="14.00">10.0.10.1/24</text>
<text text-anchor="middle" x="137" y="-217.81" font-family="DejaVu Serif, Book" font-size="14.00">10.0.10.2/24</text>
</g>
<!-- R2 -->
<g id="node3" class="node">
<title>R2</title>
<polygon fill="none" stroke="black" points="485.56,-120.51 485.56,-189.51 725.56,-189.51 725.56,-120.51 485.56,-120.51"/>
<text text-anchor="middle" x="514.56" y="-174.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">link1</text>
<polyline fill="none" stroke="black" points="485.56,-166.51 543.56,-166.51 "/>
<text text-anchor="middle" x="514.56" y="-151.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
<polyline fill="none" stroke="black" points="485.56,-143.51 543.56,-143.51 "/>
<text text-anchor="middle" x="514.56" y="-128.31" font-family="DejaVu Sans Mono, Book" font-size="14.00">link2</text>
<polyline fill="none" stroke="black" points="543.56,-120.51 543.56,-189.51 "/>
<text text-anchor="middle" x="634.56" y="-173.81" font-family="DejaVu Sans Mono, Book" font-size="14.00">R2 </text>
<text text-anchor="middle" x="634.56" y="-158.81" font-family="DejaVu Sans Mono, Book" font-size="14.00"> 10.0.2.1/32 </text>
<text text-anchor="middle" x="634.56" y="-143.81" font-family="DejaVu Sans Mono, Book" font-size="14.00">(lo) </text>
<text text-anchor="middle" x="634.56" y="-128.81" font-family="DejaVu Sans Mono, Book" font-size="14.00">(br0: 10.0.123.2/24)</text>
</g>
<!-- PC&#45;&#45;R2 -->
<g id="edge2" class="edge">
<title>PC:mgmt2&#45;&#45;R2:mgmt</title>
<path fill="none" stroke="lightgray" stroke-width="2" d="M91.5,-119.01C91.5,-119.01 485.56,-155.01 485.56,-155.01"/>
</g>
<!-- R3 -->
<g id="node4" class="node">
<title>R3</title>
<polygon fill="none" stroke="black" points="518.56,-0.5 518.56,-69.5 692.56,-69.5 692.56,-0.5 518.56,-0.5"/>
<text text-anchor="middle" x="543.56" y="-54.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">link</text>
<polyline fill="none" stroke="black" points="518.56,-46.5 568.56,-46.5 "/>
<text text-anchor="middle" x="543.56" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
<polyline fill="none" stroke="black" points="518.56,-23.5 568.56,-23.5 "/>
<text text-anchor="middle" x="543.56" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data</text>
<polyline fill="none" stroke="black" points="568.56,-0.5 568.56,-69.5 "/>
<text text-anchor="middle" x="630.56" y="-46.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">R3 </text>
<text text-anchor="middle" x="630.56" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00"> 10.0.3.1/32 </text>
<text text-anchor="middle" x="630.56" y="-16.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">(lo)</text>
</g>
<!-- PC&#45;&#45;R3 -->
<g id="edge3" class="edge">
<title>PC:mgmt3&#45;&#45;R3:mgmt</title>
<path fill="none" stroke="lightgray" stroke-width="2" d="M91.5,-96.01C91.5,-96.01 518.56,-35 518.56,-35"/>
</g>
<!-- R1&#45;&#45;R2 -->
<g id="edge6" class="edge">
<title>R1:link&#45;&#45;R2:link1</title>
<path fill="none" stroke="cornflowerblue" stroke-width="2" d="M543.56,-240.02C543.56,-240.02 514.56,-190.01 514.56,-190.01"/>
<text text-anchor="middle" x="493.56" y="-228.82" font-family="DejaVu Serif, Book" font-size="14.00">10.0.123.1/24</text>
</g>
<!-- R3&#45;&#45;PC -->
<g id="edge5" class="edge">
<title>R3:data&#45;&#45;PC:data2</title>
<path fill="none" stroke="cornflowerblue" stroke-width="2" d="M518.56,-12C518.56,-12 91.5,-73.01 91.5,-73.01"/>
<text text-anchor="middle" x="137" y="-76.81" font-family="DejaVu Serif, Book" font-size="14.00">10.0.30.2/24</text>
<text text-anchor="middle" x="473.06" y="-15.8" font-family="DejaVu Serif, Book" font-size="14.00">10.0.30.1/24</text>
</g>
<!-- R3&#45;&#45;R2 -->
<g id="edge7" class="edge">
<title>R3:link&#45;&#45;R2:link2</title>
<path fill="none" stroke="cornflowerblue" stroke-width="2" d="M543.56,-70C543.56,-70 514.56,-120.01 514.56,-120.01"/>
<text text-anchor="middle" x="493.56" y="-73.8" font-family="DejaVu Serif, Book" font-size="14.00">10.0.123.3/24</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.4 KiB

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