Commit Graph
248 Commits
Author SHA1 Message Date
Joachim Wiberg 7b7baa0730 modem: expose location and last-change in operational state
Cellular modem location data (GPS coordinates, 3GPP cell info) was
previously CLI-only — 'show modem modem0' shelled out to modem-info
which queried mmcli on demand and rendered straight to terminal.
NETCONF/RESTCONF clients had no view into modem location, and there
was no way to tell how stale any modem-state field was.

This commit moves both into the YANG operational tree so they are
accessible through every northbound interface, not just the CLI.  It
is Phase 1 of the modem GPS / location integration plan; Phase 2 will
route the modem's NMEA TTY into the existing gpsd → chronyd pipeline
so cellular modems can also serve as an NTP fallback time source.

YANG (infix-hardware.yang, revision 2026-05-10):
  - modem-state/last-change (yang:date-and-time): freshness indicator
    for the modem-state subtree, bumped on each modemd poll cycle
  - modem-state/location-state container: source (gps|3gpp|...),
    latitude/longitude/altitude (decimal64 6/6/1 fraction-digits),
    cell-id/lac/tac/mcc/mnc, and its own last-change

Runtime path:
  - modemd's check_location() now writes
    /run/modemd/modemN/location/data.json with the full location data
    plus an RFC3339 last-change.  Atomic via tmp+rename.  Walks the
    mmcli output once instead of twice.
  - check() touches /run/modemd/modemN/state.json with a fresh
    last-change after each successful state poll.
  - yanger/infix_modem.py reads both files via HOST.read_json and
    folds them into the modem-state operational subtree.
  - cli_pretty show_modem_detail rewritten to consume the operational
    tree (same path as 'show modem' overview), with new 'Last Update'
    lines for both top-level state and location.
  - bin/show/modem() consolidated: both 'show modem' and
    'show modem REF' use get_json('/ietf-hardware:hardware') — no
    more direct modem-info subprocess call.

Cleanup along the way:
  - Removed the legacy /run/modemd/modemN/location/{up,down,disabled,
    failed} marker file writes — they had no readers anywhere in the
    tree.  In-memory self.location['state'] is kept purely as the
    edge-trigger for the 'Retrieved GPS location' log line.
  - Aligned now_rfc3339() output with yanger.common.YangDate (+00:00
    form, not Z) so consumers see one consistent yang:date-and-time
    format regardless of producer.
  - Fixed multi-modem SIM scoping in show_modem_detail: now derives
    sim<N> from modem<N> instead of picking the first SIM globally.

The bearer / hardware-revision / phone-number / supported-carrier
sections of 'show modem REF' are deliberately omitted for now —
those fields are not yet in the YANG tree.  Bearer details in
particular likely belong on the wwan interface
(ietf-interfaces:interfaces-state) rather than on the modem hardware
component, and can be addressed in a follow-up.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:51:02 +02:00
Joachim Wiberg f78f161dbe modem: migrate from infix-modem to ietf-hardware/ietf-interfaces
The initial modem import used a standalone infix-modem YANG module with
an integer-indexed list under /infix-modem:modems carrying a bearer
config mixed in with hardware config.  Infix has adopted the ietf-hardware
model to allow for a clearer separation of concerns, this commit aims to
improve on that situation by refactoring the modem model to use the same
architectural pattern already used for WiFi radios, GPS receivers, and
USB ports:

Hardware:
    /ietf-hardware:hardware/component[class=infix-hardware:modem]
    /ietf-hardware:hardware/component[class=infix-hardware:sim]
Interface:
    /ietf-interfaces:interfaces/interface[type=infix-if-type:modem]

Configuration split:
  modem component — admin-state (enable/disable), radio access mode,
                    frequency bands, location services, probe-timeout
  sim component   — PIN, PUK, carrier profile
  wwan interface  — APN, IP type, roaming, route-preference, auth

This also enables the modem to appear in 'show hardware' alongside
other hardware components, and to be managed over NETCONF/RESTCONF
using the same ietf-hardware RPCs used for USB and WiFi.

YANG changes:
  - infix-modem.yang removed (1089 lines, standalone module)
  - infix-hardware.yang: new modem and sim containers, modem-state and
    sim-state operational state, typedefs for bands/modes/location,
    notification status-update; actions restart/reset/send-sms are
    augmented directly on the component list entry (not inside container
    modem) to work around sysrepo NP-container parent validation — when
    checking a nested action's parent, sysrepo restricts its operational
    data fetch to the container path, excluding the sibling 'class' leaf
    needed to evaluate the container's 'when' condition, so the container
    is never instantiated and the parent check fails
  - infix-if-modem.yang: new submodule (same pattern as wifi/wireguard)
    adds the wwan bearer container to ietf-interfaces
  - infix-if-type.yang: new modem identity for wwan interface type
  - confd version bumped to 1.9

confd:
  - if-modem.c: new file replaces the stub modem_gen() in modem.c;
    generates dagger init scripts with probe-timeout wait loop and
    unconditional dummy wwan creation so downstream IP config succeeds
    when a USB modem is slow to enumerate at boot
  - hardware.c: start/stop/enable/disable modemd (and modem-manager)
    in response to admin-state changes on the modem hardware component;
    use finit_enable/disable consistently
  - hardware_cand_infer_class(): auto-set class for modemN/simN names
  - modem.c: stripped to RPC/notification forwarding only; the old
    genconf() / enable() / disable() logic is gone — hardware.c owns
    the lifecycle now
  - interfaces.c: remove wwan from wait-interface timeout (the modem
    interface appearance is managed by modemd, not confd's init scripts)
  - migrate/1.9: script fully migrates /infix-modem:modems to the new
    split model; each modem[N] becomes a modemN hardware component and
    simN sim component; each bearer becomes a wwanN interface (bearers
    numbered globally across modems); APN, IP type, roaming, preferred-
    mode, bands, location, PIN/PUK/carrier are all carried over; plain-
    text bearer credentials are moved to a named keystore symmetric-key
    (base64-encoded) referenced from bearer/authentication/password;
    apn-type, firewall-enabled, dns-enabled and default-route are
    dropped (no equivalent in the new model)

modemd:
  - load_config() replaces the infix-modem sysrepocfg call; reads from
    ietf-hardware (modem/sim config), ietf-interfaces (bearer config),
    and ietf-keystore (credentials) — three standard modules instead of
    one proprietary one; modems absent from sysrepo config but present
    in system.json are still started (physical detection wins)
  - Default route written to /etc/net.d/<iface>.conf (picked up by
    netd/staticd/zebra) instead of a direct 'ip route add'; routes are
    now visible to FRR for redistribution and metric-based failover
  - Addresses tagged with proto wwan (rt_addrprotos entry 7) for
    precise flush on disconnect without touching other address sources
  - _derive_gateway() handles point-to-point bearers where modem
    reports gateway as "--"; derives peer from link-scope subnet route
  - SimThread exits cleanly on platforms without /dev/simctrl
  - sim-setup, modem-info, modem-udev, modem-rpc, modem-sms all ported
    to the ietf-hardware/ietf-interfaces namespace

statd:
  - infix_modem.py now emits modem-state and sim-state into ietf-hardware
    component entries (modem0, sim0, ...) instead of a separate tree;
    sim-state reports physical slot, lock state, and SIM operator name
  - ietf_hardware.py: hardware component names deduplicated by rename
    (cpu → cpu, cpu1, ...) to prevent LY_EVALID when hwmon and thermal
    sysfs both normalise to the same sensor name
  - show hardware: Cellular Modems and SIM Cards tables added; sensor
    table width now adapts to the widest section in the output
  - 00-probe: USB modem detection writes to system.json["modem"], same
    source as wifi-radios, feeding gen-hardware which emits the
    ietf-hardware component entries at factory config generation time

CLI:
  - 'show modem [ref]': without ref shows Cellular Modems and SIM Cards
    tables (same data subset as 'show hardware'); with ref shows a full
    per-modem dump (hardware info, status, cellular, SIM, bearers, GPS)
  - 'modem restart <ref>': disconnect and reconnect all bearers without
    a full hardware reset
  - 'modem reset <ref>': factory-reset the modem firmware
  - 'modem sms <ref> <number> <message>': send an SMS via the modem
    (uses the signalling plane; no active data bearer required)
  - MODEMS PTYPE provides tab-completion reading modem names from
    /run/system.json

doc:
  - Add initial User Guide for modems
  - Update ChangeLog with modem news
  - Use absolute URLs in ChangeLog.  Relative links only work for in-tree
    references, not in release notes

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:50:58 +02:00
Joachim Wiberg ffe5ed1e32 statd, show: fix several operational data reporting bugs
Three bugs found while testing modem support on hardware:

ietf_system.py: "interface": null written to DNS server entries when
  no interface is associated, causing LY_EVALID in the ietf-system
  schema validator.  Only include the key when the interface name is
  non-empty.

ietf_system.py: empty list inserts (user [], server [], options [],
  search []) overwrote configured data in the operational store instead
  of leaving it intact.  Guard each insert so operational data only
  shadows configured data when there is something to report.

show system: CPU temperature reported only the first sensor named
  exactly "cpu", "soc", or "core".  Platforms with multiple thermal
  zones (e.g. BPI-R4 exposes cpu and cpu1) always showed only one
  reading.  Collect all sensors whose name matches a CPU/SoC prefix
  and report the maximum.

statd.c: yanger parse errors logged without model name or libyang
  error string, making failures hard to diagnose.  Include both.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:50:29 +02:00
Joachim Wiberg 314b0b425f Add cellular modem support via modemd daemon
Integrates the modem management subsystem, donated by Avvero Pty Ltd,
adapted to work on any platform without proprietary hardware (simctrl,
modules.json, /sys/class/sim/).

Components:
- package/feature-modem: Buildroot feature package pulling in modemd,
  ModemManager, libmbim, libqmi, and USB serial/MBIM/QMI kernel drivers
- package/modemd: Buildroot package for the modemd daemon and helpers
- src/modemd: modem management daemon — detects modems via ModemManager,
  connects bearers, configures IP addresses, handles SMS and location
- src/confd/src/modem.c: confd plugin — enables/disables modemd and
  modem-manager via sysrepo, forwards RPCs (restart/reset/send-sms)
- src/confd/src/interfaces.{c,h}: IFT_MODEM type for wwan* interfaces;
  confd manages address/route assignment, modem daemon owns link state
- src/confd/yang/confd/infix-modem.yang: YANG model for modem config and
  operational state (bearers, APN, bands, modes, location, SMS)
- src/statd/python/yanger/infix_modem.py: operational state collector
- patches/modem-manager: upstream patches for udev install path,
  multiplexed interface naming, and MBIM port trust from udev hint
  (the last fixes Dell DW5811e / Sierra EM7455 on cold boot)
- patches/libqmi: ignore sysfs in download mode

Platform portability fixes for boards without simctrl hardware:
- modem-info: fall back to /run/modems.json when /run/modules.json is
  absent; discover wwan interfaces via sysfs scan; provide synthetic SIM
  entry when /sys/class/sim/ is not present; fix dbg() to respect flag
- modemd: make --set-allowed-modes=any best-effort (some modems only
  support one mode combination and reject any change); skip mode set
  when current mode already matches requested mode
- sim-setup: guard simctrl open, return None when modules.json absent
  to skip SIM slot switching entirely on non-simctrl hardware

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:50:28 +02:00
Mattias Walström 61d4325d2c Wi-Fi: Add support for mesh-point (802.11s) 2026-06-05 14:54:53 +02:00
Joachim WibergandGitHub 1012759a41 Merge pull request #1495 from kernelkit/speed-duplex 2026-05-27 23:40:29 +02:00
Joachim Wiberg 65eb4c072a cli: tighten 'show interface' detail-view alignment
The Ethernet packet/RMON counters at the bottom of 'show interface
<name>' were appended with a wider label column than the operational
data above them, breaking visual alignment.  Group them under an
"Ethernet Statistics" section heading (Decore.title), same convention
as 'Available Networks' in the wifi scan view.

Narrow the operational-data label column from 20 to 19 chars so the
title bar exactly matches the heading text — a tighter and more
deliberately aligned look.  All labels in pr_iface fit within 19
chars except 'lacp system priority' (20); rename it to 'lacp sys
priority' for consistency with the other 'lacp ...' labels (lacp
aggregate id, lacp partner mac, ...) so the new field width works
universally.

Refresh CLI snapshots and doc samples to match.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-27 20:53:30 +02:00
Joachim Wiberg 7fa141178f cli: layered show interface, IEEE 802.3.2-2025 ethernet model
Import ieee802-ethernet-interface@2025-09-10.yang, from IEEE 802.3.2-2025,
and companion ieee802-ethernet-phy-type.yang, replacing the 2019 revision.
Operational interface speed moves to ietf-interfaces:speed, RFC 8343,
eth:speed is now obsolete.  Bump infix-interfaces.yang revision to track
the upgrade.

The CLI 'show interface' command renders interfaces as bottom-up layered
protocol rows.  Ethernet interfaces a new IEEE link-mode row (1000baseT,
10GbaseLR, ...) is added with 'duplex: full|half' in the DATA column.
Without link the ethernet row is the first row.  Tunnels and wifi follow
the same layering: gre/vxlan rows carry remote:/vni: tokens with optional
ethernet sub-row for the L2-bearing variants; wifi rows carry 'station' or
'access-point' ssid:, signal:, stations: tokens.

admin@bpi-76-8f-c2:/> show interface
⚑ INTERFACE   PROTOCOL      STATE       DATA
⇅ lo          loopback      UP
              ipv4                      127.0.0.1/8 (static)
              ipv6                      ::1/128 (static)
⇅ br0         bridge        DOWN
  │           ethernet                  32:2e:3f:76:8f:c2
  │           ipv4                      192.168.0.1/24 (static)
⇅ ├ lan0      bridge        LOWER-DOWN
⇅ ├ lan1      bridge        LOWER-DOWN
⇅ ├ lan2      bridge        LOWER-DOWN
⇅ └ lan3      bridge        LOWER-DOWN
⇅ gre0        gre           UP          remote: 198.51.100.7
              ipv4                      10.255.0.1/30 (static)
⇅ sfp1        ethernet      DOWN        ca:59:f0:77:80:5b
⇅ wan         1000baseT     UP          duplex: full
              ethernet                  32:2e:3f:76:8f:c2
              ipv4                      192.168.0.235/24 (dhcp)
              ipv6                      fe80::302e:3fff:fe76:8fc2/64 (link-layer)
⇅ wan.10      vlan          UP          vid: 10
  │           ipv4                      10.0.10.1/24 (static)
  └ wan
⇅ wan.10.20   vlan          UP          vid: 20
  │           ipv4                      10.0.10.20/28 (static)
  └ wan.10
⇅ wifi0       wifi          UP          station ssid: corp-net signal: good
              ethernet                  dc:a6:32:00:11:22
              ipv4                      192.168.7.42/24 (dhcp)

yanger populates phy-type and pmd-type from a static ETHTOOL link-mode
identity table keyed on (port, speed, duplex).  Both leaves are populated
for unambiguous media (copper, DAC, copper-T); for generic fiber where
the (port, speed, duplex) tuple can map to multiple PMDs (SR vs LR vs
ER, etc.) only the phy-type family identity is emitted — guessing the
PMD would be misleading.  cli_pretty prefers pmd-type (specific) and
falls back to phy-type (family) for display.

yanger also emits ietf-interfaces:speed and fixes a long-standing
'auto-negotation' typo (yanger had never matched ethtool's correctly-
spelled JSON field, so operational auto-negotiation always read
'unknown').

Filling the WG's gap on fixed-speed config
------------------------------------------

IEEE Std 802.3.2-2025 obsoleted the eth:speed leaf without providing a
config-true replacement; the standards-correct way to express what
older Infix configurations called 'fixed speed' is to restrict the set
of PMDs auto-negotiation may advertise.  Augment auto-negotiation with
two leaf-lists:

  auto-negotiation/advertised-pmd-types  config-true,  leaf-list of pmd-type
  ethernet/supported-pmd-types           config-false, leaf-list of pmd-type

Pinning a port to a single mode is now expressed as a single-entry
advertised-pmd-types list.  The kernel-supported set is exposed as
operational state for diagnosis — SFP/SFP+ cages report the inserted
module's capabilities, narrowing the list to a single PMD when the
optic only supports one mode (as suggested by @wkz in PR review).
When the supported list collapses to a single entry, yanger uses it
to refine the operational pmd-type leaf — more accurate than the
(port, speed, duplex) lookup for fiber.

confd C apply path (src/confd/src/ieee802-ethernet-interface.c)
translates each advertised pmd-type identity to the corresponding
ETHTOOL_LINK_MODE_*_BIT_*, ORs them into a mask, and emits
'ethtool --change <if> autoneg on advertise 0x<mask>'.  An empty
list keeps the historical default of advertising every supported
mode.  The (legacy) 'auto-negotiation/enable = false' + speed/duplex
branch is removed — it has no model representation any more.

cli_pretty's detail view gains 'advertised' and 'supported' rows
listing the PMDs in each set.  A new _pr_label_list() helper unifies
multi-row rendering across these new rows and the pre-existing
ipv4/ipv6 address rows.

The detailed interface view also gains a 'link mode' row carrying the
pmd-type / phy-type-derived label.

Migration of existing startup configurations
--------------------------------------------

Bump confd version 1.8 → 1.9 to trigger the migration on upgrade.
share/migrate/1.9/10-ethernet-advertise.sh translates old configs of
the form

  ethernet { auto-negotiation { enable false; } speed S; duplex D; }

into

  ethernet { auto-negotiation { advertised-pmd-types [PMD]; } duplex D; }

mapping (S, D) → PMD via a static lookup covering the copper-T speeds
the deprecated speed leaf historically supported (10/100/1000/2.5G/
5G/10G).  Interfaces that don't disable auto-negotiation, or that
lack a speed leaf, are passed through untouched.

Closes #530
Closes #805

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-27 20:53:29 +02:00
Mattias Walström aecb4546f8 yanger: expand VLAN ranges from bridge global output
bridge -j vlan global show can return VLAN ranges as
{"vlan": 1, "vlanEnd": 3} instead of individual entries.
The vlans dict was only keyed on the start value, causing
port VLANs 2 and 3 to be reported as "Unexpected".

Also fix typo in error message (brpvlans -> brpvlan).
2026-05-26 17:19:42 +02:00
Richard Alpe bcc2df7e20 statd: yanger: stop overwriting infix-containers 'command' leaf
The 'command' leaf is config, with a strict pattern that doesn't allow
'&', quotes or pipes.  Yanger was populating it from podman's full,
untruncated container command -- so any container whose entrypoint
uses shell metacharacters (e.g. sh -c "... && ...") failed YANG
validation.

The symptom: every operational read of /infix-containers:containers
returns SR_ERR_INTERNAL, which in turn fails the whole get-data on
the operational datastore.  This breaks case/misc/operational_all and
any RESTCONF/NETCONF read that touches containers.

This was introduced in 59028c4 ("Fix #1466: 'show container' shows no
output"), which added the operational, pattern-less 'cmdline' leaf
but left the old 'command' assignment in place.  Drop it -- 'cmdline'
already carries the full command line, and 'command' belongs to
running config.

Note: the failure can look intermittent across test runs because
podman storage is persistent.  It only triggers once a container with
a bad-pattern command ends up in 'podman ps -a', including stale or
exited leftovers from earlier runs.

Signed-off-by: Richard Alpe <richard@bit42.se>
2026-05-19 19:49:29 +02:00
Joachim Wiberg 6aed1f7df4 confd: add support for static ARP and neighbor cache
Add support for static ARP (IPv4) and neighbor cache (IPv6) entries per
interface.  Static entries are installed as permanent kernel neighbor
table entries that are never evicted by normal ARP/NDP aging.

Fixes #819

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-30 11:08:00 +02:00
Joachim Wiberg b1ad0f1656 package/mcd: bump and add support for per-bridge mcast router ports
Fixes #395

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-30 11:02:56 +02:00
Joachim Wiberg 45b06dd670 Initial support for IEEE 1588/802.1AS PTP/gPTP
Remaining work:
- phc2sys YANG model (infix-phc2sys.yang, instance-index + servo params)
- ts2phc YANG model (GPS/PPS → PHC → ptp4l GM path)
- timemaster coordination (Phase 3, after phc2sys YANG is stable)
- show ptp network (YANG action or background-polled topology container)
- CMLDS (requires upstream linuxptp + 802.1ASdm foundation)
- Full 12-bit sdoId, fault log, performance monitoring

Backported patches from linuxptp master:
- port: fix unicast negotiation recovery after FAULT_DETECTED
- udp: fix port-specific ptp/p2p_dst_ipv4 configuration
- pmc: avoid race conditions in agent update
- phc2sys: wait until pmc agent is subscribed (startup race)
- fix MAC driver incorrect SIOCGHWTSTAMP adjustment flags
- pmc_agent: longer update interval when not subscribed
- phc2sys: don't disable pmc agent with -s/-d/-w options
- port_signaling: respect ptp_minor_version in message header
- port: refresh link status on faults
- uds: copy server socket ownership in pmc clients (non-root pmc)
- uds: don't call chmod() on client socket
- port: allow mixing wildcard and exact clock identities
- Add pidfile support to ptp4l, phc2sys, and timemaster

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-23 14:19:09 +02:00
Joachim Wiberg d039af7234 Fix #1458: 'show ntp tracking' does not show reference id properly
admin@gateway:~$ chronyc tracking
Reference ID    : C23ACD14 (svl1.ntp.netnod.se)
Stratum         : 2
Ref time (UTC)  : Sun Apr 19 20:28:40 2026
System time     : 0.000000000 seconds fast of NTP time
Last offset     : -17.822519302 seconds
RMS offset      : 17.822519302 seconds
Frequency       : 1064.750 ppm slow
Residual freq   : +0.581 ppm
Skew            : 0.794 ppm
Root delay      : 0.018065268 seconds
Root dispersion : 0.000200240 seconds
Update interval : 0.0 seconds
Leap status     : Normal

vs

admin@gateway:/> show ntp tracking
Reference ID        : 194.58.205.20
Stratum             : 2
Ref time (UTC)      : Sun Apr 19 20:28:40 2026
System time         : 0.000000 seconds slow of NTP time
Last offset         : -17.822519302 seconds
RMS offset          : 17.822519302 seconds
Frequency           : 1064.750 ppm slow
Residual freq       : +0.581 ppm
Skew                : 0.794 ppm
Root delay          : 0.018065 seconds
Root dispersion     : 0.000188 seconds
Update interval     : 0.0 seconds
Leap status         : Normal

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-20 13:03:28 +02:00
Joachim Wiberg 59028c4800 Fix #1466: 'show container' shows no output
A container's command line, as reported by podman, may comtain environment
variables, which the current regexp (added in ed4fe58) does not support.

Extend the regexp to allow environment variables and add an operational,
config false, 'cmdline' leaf node to allow any characters to be reported
for the full command line in the operational output.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-20 13:02:37 +02:00
Joachim Wiberg e168633f4e statd: reliable avahi client reconnect
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>
2026-03-22 20:23:44 +01:00
Joachim Wiberg 7f2fbc8bbf statd: avahi: rename avahi subsystem to mdns
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>
2026-03-20 16:18:12 +01:00
Joachim Wiberg fee552196a statd: avahi: suppress transient mDNS daemon restart errors
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>
2026-03-20 16:18:11 +01:00
Joachim Wiberg d3c091e746 statd: optimize yanger invocation time and reduce command overhead
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>
2026-03-20 16:18:10 +01:00
Joachim Wiberg 9c2a90c07a statd: move start to runlevel 2 to save CPU cycles at bootstrap
Also, we don't need to start a logger process for statd, it behaves
nicely and uses syslog.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-03-20 16:18:03 +01:00
Mattias Walström 312b856fba ospf: add point-to-multipoint and hybrid interface type support 2026-03-10 12:44:47 +01:00
Joachim Wiberg 27a07d0179 statd: silence 'show firewall' when firewall is disabled
Fixes #1416

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-03-09 19:26:02 +01:00
Joachim Wiberg 2d9f973e82 statd: add operational support for mDNS neighbors
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-03-09 19:25:59 +01:00
Mattias Walström 57961ac0a5 GPS: Refactor, do not use hotplug depend and move to finit
Also remove caching of GPS data in operational, gpsd now depend
on its GPS device <dev/gps0> instead of hotplug magic.
2026-03-05 08:21:34 +01:00
Mattias WalströmandJoachim Wiberg c4f24caa94 yanger: Adapt to new stricter pattern for publish 2026-02-27 08:35:21 +01:00
Mattias WalströmandJoachim Wiberg 845e7c13fe yanger: Wi-Fi: Add missing radio component in operational 2026-02-24 06:59:27 +01:00
Joachim Wiberg 681251f899 statd: support gps reference clocks in 'show <hardware|ntp>'
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>
2026-02-10 16:49:40 +01:00
Joachim Wiberg 2b6588eaf4 cli: add 'show keystore' command to admin-exec
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-02-02 17:50:13 +01:00
Joachim Wiberg 129f92afdd statd: use IPv6 force_forwarding in operational state
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-01-30 09:11:41 +01:00
Mattias Walström fb89d47c90 yanger: Allow to read back SSIDs encoded with utf-8 2026-01-27 11:09:54 +01:00
Mattias Walström 2b5e4e92f1 cli_pretty: Wi-Fi: signal-strenght to text was inverted
Should be like this:
  ┌────────────┬────────────────────┐
  │ RSSI (dBm) │       Status       │
  ├────────────┼────────────────────┤
  │ ≥ -50      │ excellent (strong) │
  ├────────────┼────────────────────┤
  │ -60 to -51 │ good               │
  ├────────────┼────────────────────┤
  │ -70 to -61 │ poor               │
  ├────────────┼────────────────────┤
  │ < -70      │ bad (weak)         │
  └────────────┴────────────────────┘
2026-01-27 11:09:54 +01:00
Mattias Walström 01e82547f7 confd: Wi-Fi: Rename RSSI to signal-strength
RSSI is a vendor-specific relative index (0-255), while dBm is an
absolute power measurement. Since we report dBm values from iw,
rename the leaf to signal-strength for accuracy.
2026-01-27 11:09:51 +01:00
Joachim Wiberg 33f830b432 statd: add BSSID to table of available networks
Also, spruce up the table a bit.  Allow it to resize, let the SSID column
be flexible, and right-align column(s) with numbers.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-01-25 02:27:38 +01:00
Joachim Wiberg 6932939525 statd: convert 'show ntp [opt]' tables to SimpleTable
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-01-25 02:27:37 +01:00
Joachim Wiberg 87a754eab1 statd: Add rx/tx bitrate to WiFi station operational data
Extend the WiFi station mode with rx-speed and tx-speed leaves,
mirroring what already exists for AP mode connected stations.
Display bitrates in 'show interface <wifi>' detailed view.

Also standardize speed units to kbps/Mbps across the YANG model.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-01-24 19:17:48 +01:00
Joachim Wiberg 496eda7eb2 statd: remove double-close of file descriptor after fclose
When fdopen() succeeds, the FILE stream takes ownership of the file
descriptor.  Calling fclose() automatically closes the underlying fd, so
the subsequent close(fd) calls were double-close bugs that could cause
undefined behavior.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-01-24 18:08:32 +01:00
Mattias Walström 3aa912164a yanger: wifi: Refactor to only use iw data (except for scanning)
Before it was a mess with wpa_cli and hostapd_cli commands, but now
we have a iw => json tool (iw.py) so we can use iw to get the information.
2026-01-24 15:01:32 +01:00
Mattias Walström 0ac4c4ca6f yanger: show proper phy name for Wi-Fi phys 2026-01-23 13:03:58 +01:00
Mattias Walström 1f913b5c7e yang: wifi: Use correct type for counters 2026-01-23 13:03:57 +01:00
Joachim Wiberg e0ee26a6cb cli: expand 'show nacm [user NAME | group NAME]'
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-01-23 06:12:24 +01:00
Joachim Wiberg b6a7d0f294 cli: new admin-exec level command 'show nacm'
Show operational details about nacm and user//group mappings.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-01-23 06:12:21 +01:00
Joachim Wiberg 3c697ede67 statd: add optional min_width to columns in SimpleTable class
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-01-23 06:12:20 +01:00
Joachim Wiberg f23b14d15e statd: backport finit patch to fix 'show services'
Service descriptions or command arguments may contain special characters
that need to be escaped in JSON strings.

Example:

{
  ...
  "command": "udhcpc -f -p /run/dhcp-client-wan.pid -t 3 -T 5 -A 30 -a1000 -S -R -o -O 1 -O 3 -O 6 -O 12 -O 15 -O 28 -O 42 -i wan -V "NanoPi R2S"",
  ...
}

Also, wrap add_services() in a try/except instead of testing for keys.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-01-18 23:31:45 +01:00
Joachim Wiberg d105178992 statd: resize 'show hardware' tables to match 'show system' width
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-01-18 23:30:20 +01:00
Joachim Wiberg c23009d7a2 statd: fix 'show system' regression, broken in b826bcb
The table_width() class method was lost in b826bcb9d, so we take the
opportunit to refactor to SimpleTable.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-01-18 21:39:38 +01:00
Mattias Walström 7e5da21cf6 Add support for WireGuard
Almost full support for WireGuard

admin@server:/> show interface wg0
name                : wg0
type                : wireguard
index               : 10
mtu                 : 1420
operational status  : up
ipv4 addresses      : 10.0.0.1/24 (static)
ipv6 addresses      : fd00::1/64 (static)
peers               : 2

  Peer 1:
    public key        : ROaZyvJc5DzA2XUAAeTj2YlwDsy2w0lr3t+rWj2imAk=
    status            : UP
    endpoint          : 192.168.10.2:51821
    latest handshake  : 2025-12-09T22:51:38+00:00
    transfer tx       : 1412 bytes
    transfer rx       : 1324 bytes

  Peer 2:
    public key        : Om9CPLYdK3l93GauKrq5WXo/gbcD+1CeqFpobRLLkB4=
    status            : UP
    endpoint          : 2001:db8:3c4d:20::2:51822
    latest handshake  : 2025-12-09T22:51:38+00:00
    transfer tx       : 1812 bytes
    transfer rx       : 428 bytes
in-octets           : 1752
out-octets          : 3224

admin@server:/>
2026-01-09 11:11:32 +01:00
Mattias Walström 8e9fd27e24 yanger: hardware: Do not crash if failing to read /run/system.json 2026-01-09 11:08:32 +01:00
Mattias Walström 651a274470 yanger: Do not crash if fails to get ethernet links 2026-01-09 10:23:52 +01:00
Joachim WibergandGitHub 84688864ef Merge pull request #1343 from kernelkit/misc-wifi-fixes 2026-01-06 23:47:16 +01:00
Mattias Walström f86436e739 yanger: Fix wifi status
use sh -c to expand the *
2026-01-06 20:20:22 +01:00