Issue #1461 turned out to just be a flaky test, the change in this
commit only bumps the release date.
[skip ci]
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Add several entries that were missing from the original release notes,
most notably the SBSA watchdog fix for CN913x (Marvell Octeon) platforms
and the BPI-R3 watchdog fix, plus show keystore, ixll scan, show system
temperature, WiFi signal strength inversion fix, and follow command fix.
[skip ci]
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When a YANG model change breaks existing startup configs, a migration
script must be included or devices in the field may be left unbootable
after upgrade. Add a dedicated section explaining when scripts are
needed, where they live, and how they work.
Fixes#1459
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Unfortunatly the fix was entered in 25.10, but confd was not stepped
up until 25.11, so this should be for 25.10 but now it is for confd
version 1.6 (infix 25.11), as close as we can get.
this is a follwup for commit 7e37fc49a3
confd: prevent IP addresses on bridge ports
Bridge ports should not have IP addresses configured. The IP address
should be configured on the bridge interface itself, not its member ports.
Add YANG must expression to enforce this rule at configuration time.
Fixes#1122
Add a second discovery backend that reads mDNS neighbor data directly
from the sysrepo operational datastore via `copy operational-state -x
/mdns`, selectable with --backend operational.
Add an auto backend (the new default) that tries the operational data
first and falls back to avahi-browse if the `copy` command is
unavailable or mDNS is disabled (visible via "enabled": false in the
JSON). This makes the service work correctly in all configurations
without manual tuning.
Refactor TXT record parsing into parseTxt() and service/host assembly
into buildHosts(), shared by both backends. Extract fetchOpRoot() and
parseOperational() so scanOperational() and scanAuto() share the same
JSON fetch/decode and host-building logic without duplication.
Fix a bug where TXT values containing semicolons were truncated
(parts[9] → strings.Join(parts[9:], ";")), and apply decode() to TXT
values so avahi \DDD escapes are resolved. Add Apple device model
support via the am= (RAOP/AirPlay 1) and model= (AirPlay 2) TXT keys.
Display the last-updated timestamp in 24-hour format regardless of the
browser's locale.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Add reliable avahi client reconnect via explicit free+recreate, reduced
log verbosity (single 10s warning instead of 3×2s loop). Also, binary
TXT record filtering (UTF-8 + XML validity), and finally add a SIGHUP
handler for on-demand reconnect.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Infix now advertises _workstation._tcp, making devices appear
automatically in Windows Explorer's Network folder (Win 10 1709+).
Lead with this, show .local hostname usage for ping/SSH, and demote
the IPv6 multicast ping caveat to a note.
[skip ci]
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
statd now uses avahi-client for mDNS neighbor tracking, so the
native build needs libavahi-client-dev to satisfy pkg-config.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
has_fix() only checks that fix-mode is set (2d/3d), but altitude and
other fields may not yet be populated in the operational datastore when
gpsd is still processing its first NMEA cycles after boot. Calling
verify_position() immediately after has_fix() passes can therefore race
and fail with:
KeyError: 'altitude'
This manifests reliably on the second GPS receiver (gps1) after reboot,
because it is initialized slightly later than gps0 and hits the window
where fix-mode is set but altitude has not yet appeared.
not ok 11 - Verify gps1 position is near the coordinates
# Traceback (most recent call last):
# File "test/case/hardware/gps_simple/test.py", line 29, in verify_position
# alt = float(state["altitude"])
# ~~~~~^^^^^^^^^^^^
# KeyError: 'altitude'
Add has_position() to infamy/gps.py, which gates on fix-mode AND all
position fields (latitude, longitude, altitude, satellites-used) being
present. Replace the has_fix() polls in both the pre- and post-reboot
verify steps with has_position().
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Replace fragile SSH+jq approach for reading the chassis MAC with a
NETCONF query to ietf-hardware:hardware/component[name='mainboard'],
reading phys-address directly from the YANG model.
Also add until() polling to the chassis MAC and chassis+offset MAC
verification steps, consistent with the reset-to-default steps.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A service restart triggered by finit during sysrepo callbacks can drop
an in-flight HTTP connection, causing copy("candidate", "running") to
fail with RemoteDisconnected. Add retry logic consistent with the
existing PATCH retry pattern in put_config_dict().
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
test_reset() triggers a config reload which causes services such as
rousette to restart. Wait for the transport to become reachable again
before returning from attach(), preventing subsequent API calls from
racing with a still-restarting backend.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Add --log-level command line option to filter out log messages from
lower log levels. Then fix the annoying CzechLight warning message
and useless "NACM config validation" log. Then add audit trail as
we have in netopeer2-server, and finish off by stripping redundant
fields from log message: timestamp, identity, and log level.
Fixes#892
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The setting 'stratumweight 0.0' disables stratum in Chrony source
selection (pure distance-based), making client_stratum_selection
non-deterministic on a LAN. Setting it to 1.0 gives srv1 a 1-second
effective advantage per stratum level, which no realistic distance
fluctuation can overcome.
Also correct the YANG descriptions in infix-system and infix-ntp which
had the semantics backwards — claiming 0.0 "ensures lower stratum is
always preferred" when in fact higher values do that.
Fixes#1361
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
After a successful bootstrap confd writes a sentinel to /run/confd.boot
If Finit restarts confd — whether after a crash or a clean exit — the
sentinel is found and the destructive bootstrap phases are skipped:
- gen-config fork (factory/failure configs already exist)
- wipe_sysrepo_shm() (other daemons, e.g. statd, are live)
- sr_install_factory_config() (datastores are already initialised)
- sr_replace_config(NULL, NULL) (running datastore is consistent)
- bootstrap_config() / load startup-config (not needed; sysrepo has
the right state; plugins resync via SR_EV_ENABLED on re-subscribe)
On restart confd reconnects to sysrepo, re-initialises plugins (which
re-subscribe and receive SR_EV_ENABLED to resync with the live running
datastore), then enters the steady-state event loop.
The sentinel lives on tmpfs so a real reboot always produces a clean
slate. Crash-loop protection is delegated to Finit's max-restarts (10).
As a side-effect this also enables a future "run-once" mode for resource
constrained systems: confd can exit after bootstrap and the sentinel
ensures any later restart just re-attaches without re-bootstrapping.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Add a finit_enable/disable/reload() family in core.c that directly
manipulates Finit's service state without fork+exec overhead:
finit_enable(svc) -- create symlink in /etc/finit.d/enabled/
finit_disable(svc) -- remove symlink from /etc/finit.d/enabled/
finit_delete(svc) -- remove both symlink and service entirely
finit_reload(svc) -- utimensat() on .conf to schedule reload
Printf-style variants (finit_enablef/disablef/reloadf) handle
template instance names such as container@foo and hostapd@wlan0.
All systemf("initctl ... enable/disable/touch ...") call sites across
containers, dhcp-server, firewall, hardware, ntp, routing, services,
syslog, and system are converted to the new API.
As a related cleanup in services.c, drop the remaining srx_enabled()
calls in favour of reading the already-fetched config tree directly
via lydx_is_enabled(lydx_get_xpathf(config, ...)), eliminating the
last sysrepo round-trips from that module.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Previously svc_enadis() would call 'initctl enable + touch' for every
config change event, even when the service's enabled state was unchanged.
This caused rousette to be unnecessarily restarted on every test_reset(),
racing with the active RESTCONF connection on slow hardware.
Replace svc_enadis() and svc_change() with svc_enable() which only
manages nginx symlinks and calls 'initctl enable/disable' -- never touch.
Each handler now checks the diff for the specific leaf that changed:
- If /enabled appears in diff: call svc_enable() to start or stop it
- If other config leaves changed with service already enabled: touch only
This ensures rousette, ttyd, netbrowse, avahi, sshd, and lldpd are only
restarted when their configuration actually requires it.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Save a few CPU cycles by skipping a new dagger generation when no
interfaces have been modified/added/deleted.
Uses d->next_fp as the sentinel: NULL means no claim was made for this
transaction. dagger_evolve() and dagger_abandon() now NULL it after
fclose, so subsequent unclaimed transactions also get the clean early
return.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The operator sees Infix through YANG models and should not need to know
which library implements a given feature. Rename the public-facing
parts of the avahi module to use the mdns vocabulary:
- Log strings: "avahi: ..." → "mdns: ..."
- Public API: avahi_ctx_init/exit → mdns_ctx_init/exit
- Main type: struct avahi_ctx → struct mdns_ctx
- statd field: statd.avahi → statd.mdns
Internal types (struct avahi_neighbor, avahi_service, …) and file names
(avahi.c, avahi.h) are kept as-is — developers debugging at the C level
benefit from knowing the underlying implementation.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When the mdns service is stop-started (e.g. after a config change),
statd's avahi client fires AVAHI_CLIENT_FAILURE momentarily. With
AVAHI_CLIENT_NO_FAIL the client reconnects automatically, but the
immediate ERROR log is misleading:
ERROR: avahi: client failure: Daemon connection failed
New behavior:
- On AVAHI_CLIENT_FAILURE: start a 2 s deferred timer (no immediate log)
- Timer fires up to 3 times (~6 s total); on the 3rd attempt, check if
mDNS is enabled in the running config via a temporary sysrepo session
- Log ERROR only if the daemon is still down AND mDNS is enabled
- On AVAHI_CLIENT_S_RUNNING: cancel the timer, reset the counter, and
log NOTE "mDNS daemon reconnected" if a failure had been seen
This silences the error entirely when the operator has disabled mDNS
(expected), and defers it by ~6 s for a brief restart (self-heals
before the timer fires).
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Use same log frameworks as reset of confd
- Use existing primitives from libite + libsrx
- Drop remaining pthreads
- Coding style fixes
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Replace logging + logging.handlers with a lightweight syslog wrapper,
and argparse with manual argv parsing. On a sama7g54, this cuts yanger
startup from ~770ms to ~470ms by eliminating ~300ms of stdlib imports.
Also batch external command invocations:
- ietf_routing: two sysctl calls instead of two per interface
- ietf_hardware: one ls per hwmon device instead of six
- bridge: fetch mctl querier data once instead of once per VLAN
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Only install the keys on CHANGE event, fixes this annoying issue:
Nov 5 01:32:10 ix confd[2011]: Installing HTTPS gencert certificate "self-signed"
Nov 5 01:32:10 ix confd[2011]: Installing SSH host key "genkey".
Nov 5 01:32:11 ix confd[2011]: Installing HTTPS gencert certificate "self-signed
Nov 5 01:32:11 ix confd[2011]: Installing SSH host key "genkey".
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Use SR_SUBSCR_NO_THREAD for all subscriptions and integrate sysrepo
event pipes into a libev event loop. This eliminates approximately 30
per-subscription threads, reducing overhead on embedded ARM hardware.
A temporary poll-based "event pump" thread handles callback dispatch
during bootstrap (where sr_replace_config blocks waiting for callbacks),
then exits. After bootstrap, the single-threaded libev loop takes over
for steady-state event processing.
Note, the confd-test-mode plugin still requires use of threads so we do
not create deadlocks when calling sr_replace_config().
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Add x509-public-key-format identity to crypto-types
- Add certificate node to web services container
- Use certificate from ietf-keystore as web cert
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Neither the Raspberry Pi 2B or the Microchip SAMA7G54-EK board have WiFi
hardware by default so drop WiFi, and GPS, support to allow for smaller
builds with only the bare essentials in kernel and system.
Minimal builds in general don't need WiFi or GPS either, so let's disable
them from all. This may become a central theme going forward, keeping
the minimal builds ... minimal.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
netopeer2 and rousette were starting as soon as confd had a PID, while
confd was still loading the startup config via sr_replace_config(). This
held a write lock on the running datastore. A test calling test/reset
shortly after the NETCONF port opened would have its own sr_replace_config()
block on that lock for up to 60 s, at which point sysrepo timed out the
whole RPC with "SHM event 'rpc' processing timed out".
Fix by adding the usr/bootstrap condition to both management servers so
they don't accept connections until confd signals that bootstrap is complete.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Relocate probe of wifi radios from gen-hardware to 00-probe. This saves
one python invocation and some precious CPU cycles at boot.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Follow-up to 90f619b which first introduced the /etc/hostname.d concept.
This commit moves the setup of /etc/hostname.d to post-build.sh dropping
the initial call to the hostname activation script a bit, since it is
called anyway after bootstrap has finished. The scrip is also given a
bit of a refrehs, reducing overhead and needless log messages.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Allow confd to start even earlier at boot and call 'gen-config' as a
background task, pending on it to complete before we load the sysrepo
factory datastore.
Also, add Finit style progress to console so users can see the phases
of the bootstrap process.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Infix technically does not need to start dbus and dnsmasq before confd
has loaded the system startup-config. So we move it in time to save
some CPU cycles for confd & C:o.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
On single-core Cortex-A7, the YANG bootstrap and config loading is the
dominant boot bottleneck. The current sequence spawns three serial
phases (bootstrap, sysrepo-plugind, load), each performing independent
sr_connect()/sr_disconnect() cycles, and every sysrepoctl/sysrepocfg
invocation is a fork+exec that rebuilds SHM from scratch.
Replace all three with a single confd binary that does one sr_connect()
and performs all datastore operations in-process:
- Wipe stale /dev/shm/sr_* for a clean slate
- sr_install_factory_config() from the generated JSON
- Smart migration: compare config version via libjansson, only
fork+exec the migrate script when versions actually differ
- Load startup-config (or test-config) via lyd_parse_data() +
sr_replace_config(), mirroring what sysrepocfg -I does internally
- On failure: revert to factory-default, load failure-config, set
login banners (Fail Secure mode)
- On first boot: copy factory-default to running, export to file
- dlopen plugins and enter event loop
The bootstrap shell script is split: config generation (gen-hostname,
gen-interfaces, etc.) stays in the new gen-config script, while all
sysrepo operations move into the C daemon. The finit boot sequence
collapses from 5 stanzas to 2 (gen-config -> confd).
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Backport fixes from upstream post v4.16 release. Mainly to fix
mdns-alias crash+restart counter issue when avahi-daemon has to
be restarted. Finit did not properly clear the dependency that
mdns-alias had on avahi-daemon, causing it to crash and have its
restart counter incremented.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The v2025.01 release supports the Microchip SamA7G5* eval kit(s), which
means we can enjoy the same patch level of U-Boot as other Infix boards
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- The biggest changes are syncing with latest BusyBox (busybox-update-config)
- Disable optimize for size
- Enable feature "SH_NOFORK" which allows /bin/sh to call applet_main()
directly without having to fork+exec busybox
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
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>
Replace ERROR() with ERRNO() in all error paths following POSIX API
calls (fopen, rename, realloc, fmkpath, etc.), removing redundant
manual strerror(errno) formatting where present.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
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>
Set dhcp-authoritative so clients with unexpired leases are not NAKed
after a router crash or factory reset that clears the lease database.
Drop the untagged suppress directives for options 3 (router) and 6
(dns-server): they conflict with the global options confd writes to
dnsmasq.d/, causing spurious "Ignoring duplicate dhcp-option" warnings.
Per-subnet tagged options already suppress auto-detection, and without
an active dhcp-range there is nothing to suppress anyway.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Ensure we translate the hostname before we generate the udhcpc command
line options, otherwise we'll send '-x hostname:rpi-%m' to udhcpc.
Also update all board specific factory configs with the missing setting
'"value": "auto"' for the DHCP hostname option. This to match what we
already do when we infer options when enabling a DHCP client in the CLI.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
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>
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>
Add board support for the BananaPi BPi-R64 router board, based on the
MediaTek MT7622 SoC and MT7531 Gigabit Ethernet switch.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In a hybrid MBR the conventional layout (used by gdisk and others) is:
MBR[0] = 0xEE (GPT protective, covers whole disk)
MBR[1..3] = user-selected GPT partitions with legacy type codes
genimage currently appends the 0xEE entry after the data partitions,
producing the opposite order. This is fine for most platforms, but
breaks firmware that detects GPT by inspecting only MBR entry 0: seeing
a non-0xEE type there it falls into pure-MBR mode and cannot look up
GPT partitions by name.
The TF-A partition driver (drivers/partition/partition.c) exhibits
exactly this behaviour: load_mbr_header() copies entry[0] and checks
type == 0xEE to select between MBR and GPT mode. The MediaTek MT7622
platform (BananaPi BPI-R64) is a concrete example where this matters.
On the other hand, Raspberry Pi firmware scans all MBR slots for a
bootable FAT32 partition. If slot 0 holds a 0xEE protective entry the
firmware switches to GPT detection, looks for an EFI System Partition
UUID, and reports "no bootable partitions" when none is found.
Add an opt-in hdimage option `gpt-protective-first = true` that places
the 0xEE entry at slot 0 and shifts data partitions to slots 1..3.
The default (false) preserves the existing genimage behaviour so that
platforms like Raspberry Pi continue to work without any changes.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The Raspberry Pi 400 shares hardware with the RPi 4B but differs in one
important way: it has an internal keyboard and mouse connected through a
VIA Labs USB hub on the VL805 xHCI controller. Break the symlink to
raspberrypi,4-model-b and maintain a dedicated product directory.
Factory config changes from the 4B default:
- USB1/USB2/USB3 all unlocked: USB2 carries the internal keyboard hub
and USB3 the superspeed companion; all are unlocked as this is a
desktop device
- DHCP vendor-class corrected to "Raspberry Pi 400"
Also add interface-quirks.json for the eth0 PHY detach behaviour and
the smsc95xx broken flow-control quirk (inherited from the 4B config
but now explicit), and remove the spurious bootable flag from the
primary and secondary rootfs partitions in genimage.cfg.in.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Remove console=map:0 from the [pi4] section which was suppressing HDMI
output and disabling the display getty. Making it really difficult to
use it as a regular console.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Two related problems prevented devices behind an intermediate hub (e.g.
the VIA Labs hub on the RPi 400's VL805 xHCI) from being authorized
when confd unlocks a USB bus:
1. Cascade ordering: usb_authorize() ran nftw() with FTW_DEPTH, which
visits children before the root-hub entry. The hub was authorized
while authorized_default was still 2, so when the kernel probed the
hub's children it immediately denied them. Fix: write
authorized_default=1 on the bus before entering nftw.
2. Slow/async probe: hub port enumeration is asynchronous — devices
behind a hub may appear in sysfs after nftw has already finished.
Fix: add a udev rule that catches usb_device add events on buses
where authorized_default=1 is already set on any ancestor root hub
and authorizes them immediately.
The ATTRS{} matcher in udev walks the full sysfs parent chain, so
authorized_default=1 on the root hub is visible even for devices several
hubs deep. Buses still locked at authorized_default=0 are left alone.
Also expand the docstring in generic_usb_ports() to document the
design: each root hub gets its own uniquely-named entry (USB, or USB1/
USB2/... when multiple) so buses can be individually controlled, and
boards needing finer control should use DT usb-ports annotations.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Replace the costly read-only filter loop (awk+tr per line) with a
stderr redirect, use /sys/class/net/ instead of ip+jq, and batch
all sysctl writes into a single call.
Reduces boot time by ~4s on 32-bit Arm systems.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Calling tune2fs for ext4 partitions at boot costs more than one second
boot time on 32-bit Arm systems, with very little gain. Dropping this
restores the default periodic fsck *and* saves boot time.
Instead of calling sgdisk four times, call it only when resizing and
instead use sysfs to find named paritions. Saves seconds on boards
with weaker CPU and slow media.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
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>
The awk insertion path used getline to peek at the line right after the
"### Changes", but only printed it when NF == 0 (blank line). If the
section already had a non-blank entry (e.g. a Buildroot upgrade line),
getline consumed it silently and the kernel line was written in its
place.
Fix by adding the missing else branch so the consumed line is always
re-emitted — blank lines before the new entry, non-blank lines after it.
Also demote the missing-UNRELEASED guard from exit 1 to a warning with
return 0, so the workflow doesn't abort when a new release cycle hasn't
had its ChangeLog section opened yet.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Add three SSH-related commands to the operational CLI:
ssh [user <name>] [port <num>] <host>
Connect to a remote device over SSH, running as the
CLI user (not root) by dropping privileges before exec.
set ssh known-hosts <host> <keytype> <pubkey>
Pre-enroll a host public key received out-of-band (e.g.
via email after a factory reset) into ~/.ssh/known_hosts,
avoiding a TOFU prompt on first connect.
no ssh known-hosts <host>
Remove a stale host key entry using ssh-keygen -R, e.g.
after a device factory reset causes a key mismatch.
Tab completion is provided for key types (ssh-ed25519,
ecdsa-sha2-nistp256, etc.) and for known host names/IPs.
A new run_as_user() helper is introduced alongside the existing
run(), factoring out the fork+setuid+execvp pattern used by
infix_shell() so it can be shared across the SSH functions.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
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>
Always emit the "1..N" plan line before exiting with error so test
harnesses don't report "test error, no plan" for failed or aborted
tests.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
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>
network.local is a discovery/browse page, not a management interface.
Serving it over HTTP eliminates the self-signed certificate warning
browsers show for .local mDNS names without changing the security
posture of the actual device management pages (still HTTPS-only).
The new port-80 server_name block takes precedence over the catch-all
HTTP → HTTPS redirect in default.conf.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
avahi-browse returns 127.0.0.1 (or ::1) when resolving services on the
same machine netbrowse is running on. These addresses are meaningless
for display and misleading as click targets. Skip the entire 127.x/::1
range and link-local (fe80:) when choosing the preferred address for a
host card; the card addr field is simply omitted if no routable address
is seen.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- IP address shown in soft parens on the card header line, e.g.
"infix.local (192.168.1.10)"; IPv4 preferred over IPv6, link-local
skipped
- Product name and OS version (from mDNS TXT records "product=" and
"ov=") shown as a secondary line below the header when available
- Theme toggle icons changed from ◐/●/○ to ◐/☽/☀ (system/dark/light)
- browse.go: introduce Host struct (addr, product, version, other, svcs)
replacing the flat []Service map; scan() now returns map[string]Host
- Search also matches against IP, product, and version fields
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Apple devices (e.g. Apple TV) publish vv=1 in their AirPlay/RAOP TXT
records, causing a false positive with our Infix platform marker.
Tighten the filter to require vv=1 together with at least one management
service type (ssh, https, http, netconf, restconf), which Apple devices
never advertise. Keep on=Infix as a fallback for older firmware that
predates vv=1.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
avahi's parseable output uses \DDD decimal escape sequences, not octal.
The previous decoder treated them as octal, causing digits 8 and 9 to
fall through undecoded (e.g. \058 → ':' and \091 → '[' were shown
literally). Also handle \X non-digit escapes (e.g. \. → '.') used for
dots in service instance names.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Add a `hostname` leaf to the `mdns` YANG container with default `"%h"`,
allowing operators to override the avahi host-name used for mDNS A/AAAA
records without reflashing. The default expands to DEFAULT_HOSTNAME from
os-release, preserving existing behaviour for unconfigured deployments.
Format specifiers %h/%i/%m are supported via the existing hostnamefmt()
infrastructure, which is also fixed to copy the const fmt argument to a
local buffer before modification (UB when called with a libyang-owned
string).
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Use avahi's %h wildcard in service names so each device's hostname is
included, avoiding collision suffixes (#2, #3) when multiple Infix
devices are on the same network.
Skip TXT records whose JSON value is null rather than emitting empty
key= fields. Add _workstation._tcp (with chassis MAC) and
_device-info._tcp (with model= from product-name) as always-on records
tied to mDNS being active.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Simplify and consolidate generation of mdns service records from an
external script to C. This reduces fork + exec and saves two seconds
of boot time on single core Cortex-A7 systems.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Instead of publishing A/AAAA records for $(hostname).loocal with a CNAME
infix.local, we flip it around to take advantage of the mDNS conflict
resolution rules. This gives us infix.local for one device ont the LAN
and infix-2.local for the next.
Update all service records to *not* advertise hostname, but instead to
let Avahi imply that from the advertised A/AAAA and CNAME records.
Fixes#1387
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Introduce libfleet.sh and a new 'fleet' subcommand to ixll for managing
and operating enrolled Infix devices via RESTCONF.
Device configuration is stored in ~/.config/infix/config.json
(chmod 600): and organised by profile, allowing bulk operations across
groups of devices (e.g. all aarch64 targets).
New commands:
ixll fleet enroll [-d] [-p profile] [-u user] [-w password] <name> <address>
ixll fleet list
ixll fleet upgrade <name|profile> <url>
ixll fleet backup [-o dir] <name|profile>
ixll fleet reboot <name|profile>
Upgrade runs in parallel across a fleet and shows a live per-device
progress bar by polling the infix-system:install-bundle RPC and the
installer state from the YANG operational data store.
The global -A flag (admin/admin) is honoured as a credential fallback
for devices enrolled without an explicit password.
Also fix a pre-existing typo: ">2" → ">&2" in the error path.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch adds support for chronyd's stratumpweight both in the NTP
client (ietf-system) and client+server (ietf-ntp) should fix the flaky
NTP stratum test.
Also, make sure to *not* 'rm -rf /etc/chrony/conf.d/*' in system.c to
prevent clobbering settings potentially made in ntp.c
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This is a follow-up to c559b8f2 (new-frr) where netd now is responsible
for funneling static routes, as well as routes from DHCP clients, into
the kernel via Frr.
For this to work, in particular at boot, any DHCP client must wait for
netd to have started or any default routes learned will be lost.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
DNS does not allow CNAME records at an apex domain (e.g. kernelkit.org),
so GitHub Pages cannot reliably redirect kernelkit.github.io to it. A
www subdomain can carry a CNAME pointing directly to kernelkit.github.io,
giving GitHub full control over the mapping and making the redirect work.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The weird `if env | grep -q 'reset-volumes'` construct is due to Klish
not sanitizing names before constructing variables, which leads to env
variables with '-' in them, not allowed in POSIX sh.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
curl's SCP/SFTP backend (libssh2) does not support interactive password
prompting — it fails with an authentication error unless credentials are
supplied non-interactively.
Replace the curl path for SSH URIs with native scp(1), which inherits
the TTY and prompts the user for a password as expected. Both scp://
and sftp:// URIs are handled by parsing the URI into a [user@]host:path
argument. Port is extracted if present and passed via -P. If no user
is embedded in the URI, the -u flag value (remote_user) is used instead.
Host-key verification is skipped with -o StrictHostKeyChecking=no, the
same trade-off already made by the test framework.
When the destination URI ends with '/', a meaningful remote filename is
derived from the source: the datastore's on-disk filename (e.g.,
startup-config.cfg), the datastore short-name for in-memory stores, or
the source file's own basename for plain file copies.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Add input validation patterns to string-type leaves in container,
firewall, DHCP, and interface YANG models. Also use mkdtemp() for
temporary key files in keystore.
Signed-off-by: Mattias Walström <lazzer@gmail.com>
Any exception raised by fn() propagated immediately out of the retry
loop, effectively making until() a single-shot call the moment any
transient error occurred.
Fix by wrapping fn() in a try/except inside the loop and treating any
exception as a "not yet" result. The last exception is preserved and
re-raised if all attempts are exhausted, so failure output is still
meaningful. Also fix a missing newline at end of file.
Fixes#1403
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Python's urllib.request wraps OSError in URLError during the connection
phase, but NOT during response reading (getresponse()). This means a
timeout that fires after the TCP handshake completes, e.g. when a service
accepts the connection but hasn't sent a response yet, propagates as a
bare TimeoutError that bypasses the exception handler, killing the entire
until() retry loop on the first attempt.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Rename BR2_PACKAGE_NETD_FRR to BR2_PACKAGE_NETD_FRR_GRPC to match the
naming convention of the other FRR backends (VTYSH, CONF) and make the
intent self-evident.
Have the gRPC backend select BR2_PACKAGE_FRR_GRPC so FRR is built with
gRPC support when — and only when — this backend is chosen.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This is a simpler approach than both grpc and watchfrr. Since we only
really need dynamic handling of static routes (for DHCP), we can track
changes made and maintain a "diff engine" for the resulting frr.conf.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Not all systems are equally quick, let's give it while to set before
bailing out because we test too soon.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
With the latest backported fixes to Finit, we no longer need to remove
/run/netd.pid to trigger a reload (restart) of staticd.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This includes adding a netd-daemon since FRR has gone towards all
daemons should be configured from mgmtd using YANG, netd uses gRPC to
reconfigure in mgmtd
Signed-off-by: Enable grpc
This is a simple two port router board, with the same
WiFi chips as BPI-r3.
The bootloader shall be the same as the BPI-r3, the bootloader
now probes which of the two is booting by checking for the PHYS
that only exist on BPI-r3-mini.
This patch adds a background gps monitor to statd because the gpspipe
program, normally used to interface with gpsd, slows down access to the
operational datastore with *seconds*.
This background monitor is not load bearing for how chrony accesses the
gps + nmea information from gpsd, this is handled separately in SHM.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Enable gpsd and override package defaults to integrate in Infix.
- Sync with rules disabled downstream in Debian project to prevent
clashes with common vendor/device ids used for other device types
- Start gpsd instance with '-n' to ensure /dev/shm is udpated for chrony
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Add documentation noting that at least one side of a VETH pair must
remain in the host namespace. Both ends cannot be assigned to different
containers.
Updates:
- container.md: Added IMPORTANT note in Container Host Interface section
- infix-if-veth.yang: Added note in module description
- infix-if-container.yang: Added note in host identity description
Fixes: #947
Related: #941
Co-authored-by: troglobit <183517+troglobit@users.noreply.github.com>
Enable IPv6 forwarding on the left DUT's tunnel interface, matching
the IPv4 tunnel config. Without it, IPv6 packets are not forwarded
through the tunnel, causing all tunnel_basic IPv6 tests to fail.
Regression introduced when fixing issue #515 in 717c1c0.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Add Raspberry Pi 2B to the bootloader build matrix and raspberrypi-rpi2
to the SD card image builder, enabling full RPi 2B image creation.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Catch ARM 32-bit build regressions early by adding arm targets
to the familty of Infix image and release builds.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.