Compare commits

...
108 Commits
Author SHA1 Message Date
Joachim WibergandGitHub 9a2f143d31 Merge pull request #1518 from kernelkit/releng
Prepare for v26.05.0
2026-05-29 10:24:27 +02:00
Joachim Wiberg 76cc1e8061 Update ChangeLog for v26.05.0 release
[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-29 10:18:56 +02:00
Joachim Wiberg 762915b703 doc: restyle mkdocs site after Chirpy blog theme
Material's defaults (Roboto, bluish slate dark mode) looked dull next
to the Chirpy-based kernelkit.org blog. Match its typography and colors
via extra.css, no engine change:

- Lato headings + Source Sans 3 body + system monospace for code
- Dark mode: neutral near-black background, soft-gray text, darker code
  blocks, Chirpy blue links (replacing Material's high-contrast slate)
- Light mode: warmer body text, blue links, tinted sidebars
- Keep the orange brand on the masthead; links use Chirpy blue

Set theme.font: false so Material no longer also fetches Roboto.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-29 10:07:56 +02:00
Joachim Wiberg 5fd5d1254a doc: fix missing images in test system arch.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-29 10:07:52 +02:00
Joachim WibergandGitHub 1012759a41 Merge pull request #1495 from kernelkit/speed-duplex 2026-05-27 23:40:29 +02:00
Joachim Wiberg 925a43dead cli: add 'show operational [path /X]' and path filter to config views
Extend the existing 'show <running|startup|factory>-config' family with an
optional 'path /XPATH' argument that maps straight to the underlying 'copy
-x' flag, and add 'show operational [path /XPATH]' for symmetry with the
configuration datastores.

  admin@example:/> show running-config path /ietf-interfaces:interfaces
  admin@example:/> show operational path /ietf-system:system-state

Also, improve error feedback from the copy command slightly.

Before:
  admin@example:~$ copy running -x /foo
  Error: (null) (5)
  Error: failed retrieving running-config data

After:
  admin@example:~$ copy running -x /foo
  Error: Couldn't parse path "/foo": Prefix "foo" not defined. (5)
  Error: failed retrieving running-config data

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-27 20:53:31 +02:00
Joachim Wiberg 6958c9bb1a show: relay cli-pretty's user-facing error messages
cli-pretty prints a friendly message on stdout before any sys.exit(1)
— 'Interface "w" not found', 'Error, top level "ietf-routing:routing"
missing', etc.  The wrapper used subprocess.run(..., check=True) and
on non-zero exit caught CalledProcessError, throwing away the captured
stdout and printing the generic exception message instead.

Drop the check=True / try-except dance, always relay stdout, and only
fall back to the generic 'Error running cli-pretty' line when the
subprocess crashed without producing any output.

Before:
  admin@bpi:/> show interface w
  Error running cli-pretty: Command '['/usr/libexec/statd/cli-pretty',
  'show-interfaces', '-n', 'w']' returned non-zero exit status 1.

After:
  admin@bpi:/> show interface w
  Interface "w" not found

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-27 20:53:31 +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 c3d17586fd doc: add vlan.md, update ChangeLog for the branch
Fix #1506: restore the VLAN interface documentation that was lost when
networking.md was split into per-topic pages.  Content adapted from the
v25.11.0 networking.md VLAN section, plus a new "Stacked (Q-in-Q)"
section showing `eth0.10.20`-style nesting and the layered `show
interface` rendering of the parent chain.

Update the interface-type table in networking.md to point at the new
vlan.md instead of the dangling ethernet.md#vlan-interfaces anchor.

ChangeLog: document the user-facing changes on this branch (YANG model
upgrade, layered show interface output, auto-negotation typo fix) and
the new VLAN documentation.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-27 20:53:30 +02:00
Joachim Wiberg 4c17a79de6 doc: refresh show interface samples and rename plural form
Update CLI samples across the documentation to the new layered
presentation: physical-medium row when linked (1000baseT/...), bare
MACs, and key: value DATA tokens.  Add a short prose block in
ethernet.md and iface.md explaining the layering.

Drop the historical 'show interfaces' (plural) form — removed from
klish years ago — from all user-facing examples and the landing page.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-27 20:53:29 +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ömandGitHub f7236fd59c Merge pull request #1517 from kernelkit/yanger-fix 2026-05-26 22:21:04 +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
Joachim WibergandGitHub 9b0837100c Merge pull request #1516 from kernelkit/bump-buildroot
Bump buildroot to 2025.02.14
2026-05-25 17:10:04 +02:00
Mattias Walström b650d91895 Bump buildroot to 2025.02.14
Just a lot of CVE fixes, full changelog:
https://github.com/buildroot/buildroot/blob/2025.02.x/CHANGES
2026-05-25 11:02:36 +02:00
Joachim WibergandGitHub 68e4dc3e9b Merge pull request #1514 from kernelkit/kernel-upgrade-668755b5-46cf-4c96-aff5-d1eea93ea004
Upgrade to kernel 6.18.33
2026-05-23 20:04:14 +02:00
ael-bot e8f14e1a06 Upgrade Linux kernel to 6.18.33 2026-05-23 16:23:53 +00:00
Joachim WibergandGitHub 230bd77623 Merge pull request #1513 from kernelkit/acer-license
Add missing license for new board
2026-05-23 18:10:07 +02:00
Joachim Wiberg 0bc998c24a board/aarch64: add missing license for new board
[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-23 16:05:10 +00:00
Joachim WibergandGitHub 6618bcdf1e Merge pull request #1511 from kernelkit/refactor-confd-deps
Refactor confd deps
2026-05-23 14:59:20 +02:00
Mattias Walström cf4de78d29 confd: move dhcp-client hostname dependency to core tracker
Move the hostname-triggers-dhcp-client logic from dhcp-client.c into
the centralized dep_hostname() dependency tracker.  When the hostname
changes, all interfaces with DHCP client configured are now added to
the diff by the core dependency resolver, so dhcp_client_change() picks
them up through its normal diff-based interface iteration.
2026-05-22 16:20:45 +02:00
Mattias Walström 555de63fd6 confd: add wireguard key dependency tracking
When keystore keys change, trigger regeneration of wireguard
interfaces that reference them:

 - Asymmetric key change: triggers interfaces using it as private-key
 - Symmetric key change: triggers interfaces using it as preshared-key
   (both at peers bag-level and individual peer-level)
2026-05-22 16:20:45 +02:00
Mattias Walström 9d4d521fa2 confd: split handle_dependencies() into focused helpers
Extract the monolithic handle_dependencies() into five smaller
functions, each handling one dependency type:

 - dep_symmetric_keys()    - key -> wifi secret
 - dep_asymmetric_keys()   - key -> ssh hostkey/web cert
 - dep_hostname()          - hostname -> dhcp-server/mdns
 - dep_wifi_interfaces()   - interface wifi -> radio hardware
 - dep_radio_components()  - radio hardware -> interface wifi

Also fixes a potential NULL dereference of dwifi before accessing
its access-point child, and removes redundant NULL checks for
YANG-guaranteed mandatory leaves (list keys, mandatory true).
2026-05-22 16:20:25 +02:00
Mattias WalströmandGitHub e994d976ff Merge pull request #1510 from kernelkit/fix-acer-connect
aarch64: board: Acer Connect Vero rename board
2026-05-20 12:50:16 +02:00
Mattias Walström 3fdbe15585 aarch64: board: Acer Connect Vero rename board
Fix so the board actually build when selected and rename the board
to the actual name `Acer Connect Vero W6m`
2026-05-20 11:19:12 +02:00
Tobias WaldekranzandGitHub eb2135bd15 Merge pull request #1509 from kernelkit/fix-flaky-container-tests
Fix operational get-data crash on containers with shell chars
2026-05-20 08:12:21 +02:00
Mattias WalströmandGitHub 5cf180b4d7 Merge pull request #1507 from kernelkit/add-vero
Add Acer Connect Vero W6m support
2026-05-19 20:10:37 +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
Mattias Walström 02a5079c6a doc: Changelog: Update with channel-width and the Acer Connect Vero W6m 2026-05-19 15:51:20 +02:00
Mattias Walström f39e62fdb1 feature-wifi: Only install files in romfs if enabled
Move from board romfs directory, to inside feature-wifi
2026-05-19 15:51:20 +02:00
Mattias Walström 87c2d3fc77 CI: Refactor build-image workflow
Reduce the number of duplication and try to simplify the flow.
2026-05-19 13:45:25 +02:00
Mattias WalströmandGitHub ab3594e124 Merge pull request #1508 from kernelkit/kernel-upgrade-c22791e9-8a8a-4420-a254-a84c8b6395ae
Upgrade to kernel 6.18.32
2026-05-19 13:40:06 +02:00
ael-bot 01cb60d125 Upgrade Linux kernel to 6.18.32 2026-05-19 07:01:40 +00:00
Mattias Walström 0c35a90841 doc: wifi: Document channel-width and security mode auto 2026-05-19 06:38:32 +02:00
Mattias Walström bfbf08943b mt7986: Add Acer Connect Vero w6 2026-05-19 06:38:32 +02:00
Mattias Walström 21fd80a71d confd: wifi: Fix WiFi 6E support
Was not correct handled before, a few assumptions was made,
but did not work in reality.

* Fix correct channels for WiFi 6E
* Add missing parameters required for 6ghz to work
2026-05-18 21:52:22 +02:00
Mattias Walström 64819075d5 WiFi: Add support for setting channel width 2026-05-18 09:27:03 +02:00
Joachim WibergandGitHub 2885112da8 Merge pull request #1502 from kernelkit/upgrade-frr
Upgrade FRR to 10.5.4

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-18 03:06:30 +02:00
Mattias Walström 48a1df4c67 confd: yang: Put some limits on custom mac addresses
Not correct MAC address for example multicast bit set,
caused `ip` to exit with failure code, resulting in
that configuration was not applied.
2026-05-17 18:27:45 +02:00
Mattias Walström ed6171f920 Upgrade FRR to 10.5.4
Summary of Changes:

bfdd:
    - cap IPv6 echo reflection to declared length
    - account for FP offset in echo length checks
    - fix recv errno filter logic in a few places
    - tighten SBFD reflector packet sanity checks
    - gate IPv6 echo reflection on known sessions
    - tighten auth header parsing skeleton
    - validate control packet length before session lookup

bgpd:
    - Fix memleak when configuring rd
    - Validate if NHC BGPID TLV value is non-zero
    - Avoid having a dangling pointer after we free NHC attribute
    - Check if BGPID NHC TLV exists when IPv6 next-hop is link-local
    - Do not allocate NHC TLV with an extra trailer
    - migrate timers during peer_xfer_conn to fix stale route cleanup
    - honor 'no activate' for dynamic neighbors in peer-group
    - Return immediately when dynamic capability action is not valid
    - Validate BGP role capability when handling it dynamically
    - fix neighbor IP comparison for IPv6 memcmp return values
    - Don't mark nexthop as changed if a set next-hop unchanged is applied
    - Return BGP_PEER_INTERNAL when first peer's as type is set to auto
    - Update peer sort cache when remote-as auto is used and AS number changed
    - Check dynamic capability action before validating ENHE capability
    - Do not allocate stream if route-refresh capability is not received
    - Move rpki strict check to bgp_accept()
    - Fix memory leak for nhc attribute if ipv6 is link-local address
    - Fix compilation for Debian 11 when printing uint64 values
    - Return zero labels if no BOS found and it's not a withdraw label
    - Fix signed overflow in hexstr2num()
    - Check the length also when parsing ENCAP attr sub-TLVs
    - Validate prefixlen before subtracting when parsing labeled unicast NLRI
    - Reset the stream to attr_start + attribute_len when WITHDRAWN
    - Revalidate locally originated routes against RPKI changes
    - Check if prefixlen is not 0 when parsing flowspec stuff
    - Prevent len_string going negative when trying to display flowspec entries
    - fix import vrf on non existing vrf
    - fix no vrf import command
    - Free hostname for FQDN capability if the parsing goes wrong
    - Validate MP_REACH_NLRI attribute against incorrect next-hop
    - Fix dynamic FQDN capability handling
    - Check if the remaining length for subtracting TLV length is enough
    - Fix the end pointer boundaries for dynamic graceful restart capability
    - Add missing returns when parsing enhanced route-refresh
    - Return original as-path when reconciling AS versus AS4
    - Do not process route-refresh for AFI/SAFI if it's not negotiated
    - Check if we are not overusing error_data buffer when unknown cap received
    - fix NHT for explicit link-local BGP peers
    - improve packet parsing for EVPN and ENCAP/VNC
    - Prevent heap use-after-free for tunnel encapsulation attribute
    - Return 0 if AS4 capability is malformed
    - close dynamic peer socket in ttl error path
    - fix logic handling EVPN_FLAG_DEFAULT_GW
    - avoid early return in MPLSVPN NLRI processing
    - remove unneeded asserts in packet reads

eigrpd:
    - fix byte order in Hello TLV decode functions
    - Handling for malformed update packets
    - enforce minimum TLV length in Hello handler
    - reject invalid prefix mask len
    - skip unknown and ignored TLVs
    - Improve packet validation

isisd:
    - Reject SRv6 Locator TLV with Loc-Size of zero
    - consume leftover bytes after FAD sub-sub-TLV loop
    - use correct min size values for srv6 subtlvs
    - improve validation of flex-algo decoder
    - Fix missing neighbor address Sub-TLVs after link-params change
    - add unit test for remove_excess_adjs() memory leak fix
    - fix memory leak in remove_excess_adjs()
    - fix edge condition in max_lsp_count computation

ldpd:
    - improve tlv validation in several places

lib:
    - Report IPv6 MTU and not IPv4 for if_update_state_mtu6
    - disable warning in zlog.c to match master

nhrpd:
    - stop debugging auth credentials
    - fix byte-order when comparing error code in shortcut path
    - guard against zbuf_pulln NULL on truncated packets
    - require auth for all received packet types
    - harden debug packet parsing against malformed input
    - validate AFI index in extension replies

ospf6d:
    - move log call out of priv block
    - remove asserts in packet-handling paths
    - fix issues in ospf6 auth trailer code

ospfd:
    - add LSA validation in the apiserver path
    - add validation in several places before accessing

pceplib:
    - validate during of_list TLV decoding

pimd:
    - fix NOCACHE MFC resync detection log, add vrf name too
    - use upstream-owned pim pointer in register and upstream timers
    - use upstream-owned pim pointer in MSDP update paths
    - avoid JP build deref through channel OIL
    - guard RP RPF-failure mroute delete on detached OIL
    - avoid null deref in upstream delete debug path
    - guard channel OIL detach against stale pointers
    - fix crash due to double free
    - Ensure igmp message is of proper size
    - Reject pim packets with a malformed header length
    - Fix out of bounds read in AutoRP code
    - igmpv3 never checks packet length and trusts the num-sources field
    - Do not allow a register-stop message if not received from the RP
    - Prevent received msg length from being larger than buffer
    - Remove unnecessary asserts
    - When receiving a register stop ensure we have enough data to read
    - Ensure a register packet has enough space to read S,G data
    - Ensure that header has space on packet

ripngd:
    - fix data handling in several places

tests:
    - Check if route-map with set nexthop unchanged does not prevent outgoing
    - Check if mixed peer-group remote-as types can be used with auto
    - Verify neighbor addr Sub-TLVs after link-params reset
    - Expect return code being 0, not -1 when AS4 is empty or ASN is 0

vrrpd:

    - replace some asserts
    - only support ethernet in GARP code
    - limit advertised timers to 12-bits

Signed-off-by: Mattias Walström <lazzer@gmail.com>
2026-05-16 20:56:56 +02:00
Joachim WibergandGitHub 689bd64b4d Merge pull request #1504 from kernelkit/kernel-upgrade-0ff65ffb-97d3-47f9-b02a-9328148ba88b
Upgrade to kernel 6.18.31
2026-05-16 10:29:49 +02:00
ael-bot dbdf5d9b78 Upgrade Linux kernel to 6.18.31 2026-05-16 06:06:55 +00:00
Joachim WibergandGitHub f13ee49f3c Merge pull request #1503 from kernelkit/kernel-upgrade-25c8ae89-19b4-443b-8ab6-78768210e119 2026-05-15 16:38:55 +02:00
ael-bot 1b34874d3d Upgrade Linux kernel to 6.18.30 2026-05-15 05:26:08 +00:00
Joachim WibergandGitHub 081491a380 Merge pull request #1500 from kernelkit/bump-9pm
Bump 9pm submodule
2026-05-12 14:50:40 +02:00
Joachim WibergandGitHub a19684c15c Merge pull request #1501 from kernelkit/misc
Misc
2026-05-12 14:47:33 +02:00
Joachim Wiberg f3183cd911 doc: update changelog
[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-12 13:39:18 +02:00
Joachim Wiberg e4203b0c9e package/finit: backport stale-pidfile and death-log fixes
Backport two fixes addressing a critical failure reported by a customer:
an unclean dbus-daemon exit leaves a lingering /run/messagebus.pid, the
daemon then refuse to start, and Finit's restart loop gives up.

0001 service: clean stale pidfile after unclean daemon exit
     Drop a daemon-owned (pid:!) pidfile when it still names the
     just-reaped PID and that PID is no longer alive.

0002 service: log signal name and core dumps in death message
     "by signal: 9" -> "killed by SIGKILL", with ", core dumped"
     when applicable.  Stronger breadcrumb for sudden deaths.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-12 13:38:49 +02:00
Joachim Wiberg 3be640409a confd: cache progress description and reprint on final status
The \r-overwrite of an in-progress line breaks when something else
writes to stderr between conout(3) and the final call, leaving blank
"[ OK ]" lines.  Cache the description and reprint it whole, so the
final status line is robust to intervening output.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-12 13:38:48 +02:00
Joachim Wiberg d393a10994 confd: skip neighbor/address flush for interfaces in container netns
When an interface has been handed off to a container it lives in
another netns, so `ip neigh/addr flush dev FOO` fails on the host.
The failure aborts dagger, and since interfaces_change() runs before
containers_change() in change_cb(), the container delete path is
never reached -- the stale container keeps the interface trapped in
its netns, breaking the next reconfiguration.

Guard both the neighbor and address flush exit scripts with
`if_nametoindex(ifname)` -- true exactly when the interface is in
the host netns, false for both "in a container" and "already gone".
This replaces the pre-existing `!cni_find(ifname) && if_nametoindex(
ifname)` guard at the addr site: cni_find() added no information
for this check and would popen(container find) for nothing when the
interface had been deleted entirely.

Also harden wrap() in /usr/sbin/container so a stale setup pidfile
doesn't short-circuit Finit's stop attempt -- kill the setup PID and
still ask podman to stop the container.

Fixes #1493

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-12 13:38:47 +02:00
Richard Alpe 5e6183eb4f Bump 9pm submodule
Signed-off-by: Richard Alpe <richard@bit42.se>
2026-05-12 11:49:45 +02:00
Mattias WalströmandGitHub 562435fac9 Merge pull request #1499 from kernelkit/kernel-upgrade-75b15a6e-2a9a-426d-acd1-6b77c0f9df19
Upgrade to kernel 6.18.29
2026-05-11 13:03:05 +02:00
ael-bot 21c070b928 Upgrade Linux kernel to 6.18.29 2026-05-11 07:13:25 +00:00
Joachim WibergandGitHub 23da086976 Merge pull request #1492 from kernelkit/kernel-upgrade-b951c1e9-f9f0-4f1f-be17-4ff16f7bb9c6
Upgrade to kernel 6.18.27
2026-05-09 10:04:12 +02:00
ael-bot 3c0c456bba Upgrade Linux kernel to 6.18.27 2026-05-07 06:22:32 +00:00
Mattias WalströmandGitHub f539da7e99 Merge pull request #1489 from kernelkit/disable-release-tests
Temporarily disable release regression tests
2026-05-04 10:05:45 +02:00
Joachim Wiberg 3a6e70ba26 .github: temporarily disable release regression tests
The regression tests do not pass for some reason, could be faulty test
runner (Lifeboat) -- container and DHCP tests failing since Apr 30), so
tests are disabled until the runner is fixed.

[skip ci]

Issue #1392

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-04 09:33:46 +02:00
Joachim WibergandGitHub 9406fd0e04 Merge pull request #1487 from kernelkit/releng 2026-04-30 18:53:48 +02:00
Joachim Wiberg 52ef3e2ded .github: set INFIX_RELEASE when running release tests
Without INFIX_RELEASE, make test resolves INFIX_ARTIFACT to the
unversioned infix-x86_64, but release builds produce versioned
artifacts (infix-x86_64-v26.04.0-rc1.qcow2 etc.), causing the
test environment to fail with "No such file or directory".

[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-30 18:34:35 +02:00
Joachim WibergandGitHub 3d1d73543e Merge pull request #1486 from kernelkit/release-tests
Run regression tests as part of release workflow
2026-04-30 16:08:51 +02:00
Tobias WaldekranzandGitHub 4c0996b52b Merge pull request #1483 from saba8814/fix/uboot-aux-env-first-var-import
fix: import first variable from auxiliary environment
2026-04-30 14:45:44 +02:00
Joachim Wiberg e49682645c .github: run regression tests as part of release workflow
Add an x86_64 regression test job to release.yml that runs after the
build and gates publishing — the release job now requires both build
and test to succeed.

Update test.yml's artifact restore step to use a glob so it handles
both the unversioned CI artifact name (infix-x86_64.tar.gz) and the
versioned release artifact name (infix-x86_64-26.04.0.tar.gz).

Fixes #1392

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-30 13:45:35 +02:00
Joachim WibergandGitHub a3c6ec0cd5 Merge pull request #1484 from kernelkit/releng
Release preparations
2026-04-30 13:14:04 +02:00
Joachim Wiberg 25fcfba0cb doc: update ChangeLog for v26.04.0 release
[skip ci]

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-30 11:08:02 +02:00
Joachim Wiberg 5defdfdeac doc: add section on dummy interfaces
Fixes #769

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-30 11:08:02 +02:00
Joachim Wiberg 624bfd927c doc: add section on static mutlicast filters
Fixes #790

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-30 11:08:01 +02:00
Joachim Wiberg 4d8b2e5370 confd: warn if multicast flooding is disabled
Fixes #520

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-30 11:08:01 +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 7dd746d586 Fix BPi-R64 onboard WiFi probing
The mt7622 soc has a built-in wmac, same driver as the mt7615, but
it lacked MODULE_DEVICE_TABLE() so udev could not autoload driver
and firmware.

This commit also adds the wmac+bluetooth specific firmware.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-30 11:07:31 +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
Ejub Sabic 29222e18e9 uboot: import first variable from auxiliary environment
The U-Boot env file is generated by
mkenvimage, which prefixes the variable data with a 4-byte CRC32 by default.
ixpreboot.sh previously imported it with `env import -b` as per uboot docs(-b assume binary format (’0’ separated, “00” terminated).),
which treats the buffer as raw binary and does not strip the CRC.
As a result the first variable's name is parsed a part of CRC.
Later variables import correctly because by then the parser is past the CRC.
Switching to `env import -c` as per uboot docs (-c assume checksum protected environment format.)
makes U-Boot validate and strip the CRC before parsing, so the first variable imports under its real name.

Tested on:
- QEMU

Signed-off-by: Ejub Sabic <ejub1946@outlook.com>
2026-04-29 23:27:37 +02:00
Joachim Wiberg f9ea5567c4 package/finit: bump to v4.17
https://github.com/finit-project/finit/releases/tag/4.17

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-29 17:33:14 +02:00
Joachim WibergandGitHub 413d8e4599 Merge pull request #1485 from kernelkit/bpi-r3-pcifixes
Bpi r3 pcifixes
2026-04-29 17:22:23 +02:00
Mattias Walström 507bb38bdc feature-wifi: Enable 802.11 mesh (802.11s) 2026-04-29 15:47:30 +02:00
Mattias Walström 5cb17d69d4 bpi-r3: Enable the PCI clock in device tree 2026-04-29 15:43:24 +02:00
Joachim WibergandGitHub 6c6dc7711e Merge pull request #1480 from saba8814/test/dhcp-client-hostname-not-resent
test & fix: add DHCPv4 client hostname resend regression test, fix  hostname resend
2026-04-28 19:46:47 +02:00
Ejub Sabic 4f2683090e doc: updated documentation for issue #1439
Signed-off-by: Ejub Sabic <ejub1946@outlook.com>
2026-04-28 18:06:49 +02:00
Ejub Sabic 08ca47fdab fix: dhcp client host name resend
Signed-off-by: Ejub Sabic <ejub1946@outlook.com>
2026-04-28 18:00:32 +02:00
Ejub Sabic 17965bf4cc test: add DHCPv4 client hostname resend regression test
Signed-off-by: Ejub Sabic <ejub1946@outlook.com>
2026-04-28 18:00:28 +02:00
Joachim WibergandGitHub 82ffb0f4bc Merge pull request #1481 from kernelkit/kernel-upgrade-28e7d3e7-b875-4444-a0ed-a6c18cefd76d
Upgrade to kernel 6.18.25
2026-04-28 12:39:25 +02:00
Joachim WibergandGitHub 2788eb6d1a Merge pull request #1482 from kernelkit/random-infamy-id-in-ci
test: avoid infamy0 race in CI by using random container names
2026-04-28 11:43:58 +02:00
Richard Alpe ba05c2e56d test: avoid infamy0 race in CI by using random container names
GitHub Actions sets $CI=true; treat it like -r so parallel jobs
don't all try to claim "infamy0" and clobber each other.
2026-04-28 10:06:04 +02:00
ael-bot c7cdf6b018 Upgrade Linux kernel to 6.18.25 2026-04-27 16:47:37 +00:00
Tobias WaldekranzandGitHub efa665de9c Merge pull request #1472 from kernelkit/gptp
ptp: initial support for IEEE 1588/802.1AS PTP/gPTP
2026-04-25 23:15:45 +02:00
Joachim Wiberg 4ece445c44 doc: update ChangeLog
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-24 14:30:09 +02:00
Joachim Wiberg e1e2ada4b4 confd: fix review comments and code cleanup
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-24 14:30:09 +02:00
Joachim Wiberg 95bd795347 test: add some basic ptp tests
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-24 14:29:58 +02:00
Joachim Wiberg 3426c2527b Add phc2sys companion service for BC/TC instances
On multi-chip DSA hardware (e.g., boards with multiple mv88e6xxx
chips), each switch chip has its own independent PHC device.  With
boundary_clock_jbod enabled, ptp4l starts but only disciplines the
active slave port's PHC — the others drift.

Automatically start phc2sys -a alongside any BC or TC instance using
hardware timestamping.  It subscribes to ptp4l's UDS socket, tracks
BMCA, and disciplines all non-active PHCs to match the active one.
On single-chip hardware it is a harmless no-op.

CLOCK_REALTIME is intentionally left untouched.  Syncing the system
clock to PTP (phc2sys -rr), feeding the PHC from GPS/NTP (ts2phc,
phc2sys reverse), and full multi-source coordination (timemaster) are
planned as follow-on phases; see the issue tracker for the roadmap.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-23 14:19:10 +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 73b6e5cc91 patches/ethtool: backport support for --json -T (show time stamping)
This is used by the next commit that adds initial support for PTP/gPTP.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-23 14:19:09 +02:00
Joachim Wiberg b93795c0aa board/common: add rauc upgrade bundle for ext4 images
NOTE: this is intended only for use on devboards like EspressoBin where
      the onboard bootloader only understands fat and ext2 file systems.
      To enable, use 'make apply-ext4'

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-23 14:19:09 +02:00
Joachim Wiberg 5979f4e3c9 board/aarch64: fix bpi-r4 dip switch values
Inverted values for eMMC and SPI NAND.  Also use ABCD instead of
Position as column name to match board markings.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-23 14:19:08 +02:00
Joachim Wiberg 2397e7684c board/aarch64: drag Marvell ESPRESSObin in from the cold
- Add a board README to explain how to get Infix running
- Update mkimage.sh to allow creating images without boot loader

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-23 14:19:07 +02:00
Joachim WibergandGitHub 43d6dbc63f Merge pull request #1478 from kernelkit/upgrade-buildroot 2026-04-23 13:00:41 +02:00
Mattias Walström 8ebdf9f119 Upgrade Buildroot to 2025.02.13 (LTS)
A lot of CVEs fixed.

Full changelog: https://github.com/buildroot/buildroot/blob/2025.02.x/CHANGES

Signed-off-by: Mattias Walström <lazzer@gmail.com>
2026-04-23 10:44:43 +02:00
Mattias WalströmandGitHub 3aef9930fe Merge pull request #1479 from kernelkit/kernel-upgrade-39c18ac9-3f99-4a96-bc62-daf538881c51
Upgrade to kernel 6.18.24
2026-04-23 09:50:44 +02:00
ael-bot 3ea1161f5f Upgrade Linux kernel to 6.18.24 2026-04-23 05:42:15 +00:00
Joachim WibergandGitHub 091618c527 Merge pull request #1476 from kernelkit/misc
Fix two regressions and add developer build helpers
2026-04-22 16:27:47 +02:00
Joachim WibergandGitHub 7647d2a542 Merge pull request #1477 from kernelkit/cosmetic-test-name-changes
test: normalize test case names
2026-04-21 21:47:49 +02:00
Richard Alpe f996dbd6ef test: lowercase minor words in test case names
Signed-off-by: Richard Alpe <richard@bit42.se>
2026-04-21 14:20:58 +02:00
Richard Alpe ff02190df8 test: normalize suite/case names to title case
Signed-off-by: Richard Alpe <richard@bit42.se>
2026-04-21 11:06:59 +02:00
Richard Alpe c6f7b61683 test: add names to cases called from top level suite
Signed-off-by: Richard Alpe <richard@bit42.se>
2026-04-21 11:06:57 +02:00
Joachim Wiberg dbc3ba0c83 doc: update ChangeLog
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-20 13:03:29 +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 2603b0ea1b Add support for developer config snippets
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-19 22:31:15 +02:00
Joachim Wiberg 4212a38c3b .github: bump GitHub Actions to Node.js 24 compatible versions
Fixes #1437

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-19 22:31:15 +02:00
Joachim Wiberg bb72cfd8e3 doc: add missing image to device discovery section
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-04-19 22:31:14 +02:00
410 changed files with 22341 additions and 3312 deletions
+3 -3
View File
@@ -16,7 +16,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Validate release version format
id: validate
@@ -170,7 +170,7 @@ jobs:
fi
- name: Upload signed artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: signed-infix-${{ steps.validate.outputs.file_version }}
path: ${{ steps.download_signed.outputs.signed_filename }}
@@ -212,4 +212,4 @@ jobs:
---
**Next Steps:** The signed release can now be distributed with cryptographic verification of authenticity.
EOF
EOF
+3 -3
View File
@@ -41,7 +41,7 @@ jobs:
ls -la ./
- name: Checkout infix repo
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.branch || github.ref }}
clean: true
@@ -96,7 +96,7 @@ jobs:
mv images ${{ steps.vars.outputs.dirname }}
tar cfz ${{ steps.vars.outputs.archive }} ${{ steps.vars.outputs.dirname }}/
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
path: output/${{ steps.vars.outputs.archive }}
name: artifact-${{ matrix.defconfig }}
@@ -108,7 +108,7 @@ jobs:
permissions:
contents: write
steps:
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v7
with:
pattern: "artifact-*"
merge-multiple: true
+123 -195
View File
@@ -1,4 +1,4 @@
name: Create SD Card & eMMC Images
name: Create Images
on:
workflow_dispatch:
@@ -15,15 +15,16 @@ on:
- bananapi-bpi-r64
- friendlyarm-nanopi-r2s
- microchip-sama7g54-ek
- acer-connect-vero-w
default: 'raspberrypi-rpi64'
jobs:
create-image:
name: Create SD Card Image for ${{ inputs.board }}
name: Create images for ${{ inputs.board }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
clean: true
fetch-depth: 0
@@ -50,234 +51,171 @@ jobs:
mkdir -p output/images
mkdir -p build
- name: Set bootloader and target based on board
- name: Set bootloaders and targets based on board
run: |
arch=
targets=
bootloader_sdcard=
bootloader_emmc=
case "${{ inputs.board }}" in
raspberrypi-rpi2)
echo "BOOTLOADER=rpi2-boot" >> $GITHUB_ENV
echo "ARCH=arm" >> $GITHUB_ENV
echo "BUILD_EMMC=false" >> $GITHUB_ENV
arch=arm
targets="sdcard"
bootloader_sdcard=rpi2-boot
;;
raspberrypi-rpi64)
echo "BOOTLOADER=rpi64-boot" >> $GITHUB_ENV
echo "ARCH=aarch64" >> $GITHUB_ENV
echo "BUILD_EMMC=false" >> $GITHUB_ENV
arch=aarch64
targets="sdcard"
bootloader_sdcard=rpi64-boot
;;
bananapi-bpi-r3)
echo "BOOTLOADER_SD=bpi-r3-sd-boot" >> $GITHUB_ENV
echo "BOOTLOADER_EMMC=bpi-r3-emmc-boot" >> $GITHUB_ENV
echo "ARCH=aarch64" >> $GITHUB_ENV
echo "BUILD_EMMC=true" >> $GITHUB_ENV
arch=aarch64
targets="sdcard emmc"
bootloader_sdcard=bpi-r3-sd-boot
bootloader_emmc=bpi-r3-emmc-boot
;;
bananapi-bpi-r4)
echo "BOOTLOADER_SD=bpi-r4-sd-boot" >> $GITHUB_ENV
echo "BOOTLOADER_EMMC=bpi-r4-emmc-boot" >> $GITHUB_ENV
echo "ARCH=aarch64" >> $GITHUB_ENV
echo "BUILD_EMMC=true" >> $GITHUB_ENV
arch=aarch64
targets="sdcard emmc"
bootloader_sdcard=bpi-r4-sd-boot
bootloader_emmc=bpi-r4-emmc-boot
;;
bananapi-bpi-r64)
echo "BOOTLOADER_SD=bpi-r64-sd-boot" >> $GITHUB_ENV
echo "BOOTLOADER_EMMC=bpi-r64-emmc-boot" >> $GITHUB_ENV
echo "ARCH=aarch64" >> $GITHUB_ENV
echo "BUILD_EMMC=true" >> $GITHUB_ENV
arch=aarch64
targets="sdcard emmc"
bootloader_sdcard=bpi-r64-sd-boot
bootloader_emmc=bpi-r64-emmc-boot
;;
acer-connect-vero-w)
arch=aarch64
targets="emmc"
bootloader_emmc=bpi-r3-emmc-boot
;;
friendlyarm-nanopi-r2s)
echo "BOOTLOADER=nanopi-r2s-boot" >> $GITHUB_ENV
echo "ARCH=aarch64" >> $GITHUB_ENV
echo "BUILD_EMMC=false" >> $GITHUB_ENV
arch=aarch64
targets="sdcard"
bootloader_sdcard=nanopi-r2s-boot
;;
microchip-sama7g54-ek)
echo "BOOTLOADER_SD=sama7g54-ek-sd-boot" >> $GITHUB_ENV
echo "BOOTLOADER_EMMC=sama7g54-ek-emmc-boot" >> $GITHUB_ENV
echo "ARCH=arm" >> $GITHUB_ENV
echo "BUILD_EMMC=true" >> $GITHUB_ENV
arch=arm
targets="sdcard emmc"
bootloader_sdcard=sama7g54-ek-sd-boot
bootloader_emmc=sama7g54-ek-emmc-boot
;;
*)
echo "Error: Unknown board ${{ inputs.board }}"
exit 1
;;
esac
echo "Arch: $ARCH for board: ${{ inputs.board }}"
if [ "$BUILD_EMMC" = "true" ]; then
echo "Building both SD and eMMC images"
echo "SD Bootloader: $BOOTLOADER_SD"
echo "eMMC Bootloader: $BOOTLOADER_EMMC"
else
echo "Building SD image only"
echo "Bootloader: $BOOTLOADER"
fi
echo "ARCH=$arch" >> $GITHUB_ENV
echo "TARGETS=$targets" >> $GITHUB_ENV
[ -n "$bootloader_sdcard" ] && echo "BOOTLOADER_SDCARD=$bootloader_sdcard" >> $GITHUB_ENV
[ -n "$bootloader_emmc" ] && echo "BOOTLOADER_EMMC=$bootloader_emmc" >> $GITHUB_ENV
echo "Arch: $arch for board: ${{ inputs.board }}"
echo "Targets: $targets"
[ -n "$bootloader_sdcard" ] && echo "SD bootloader: $bootloader_sdcard"
[ -n "$bootloader_emmc" ] && echo "eMMC bootloader: $bootloader_emmc"
- name: Download bootloader artifacts
run: |
# Download bootloader from latest-boot release tag
if [ "$BUILD_EMMC" = "true" ]; then
# Download both SD and eMMC bootloaders for boards that support both
echo "Downloading SD bootloader: ${BOOTLOADER_SD}"
gh release download latest-boot --pattern "*${BOOTLOADER_SD}*" --dir temp_bootloader_sd/
mkdir -p output_sd/images
cd temp_bootloader_sd/
tar -xzf *.tar.gz --strip-components=1 -C ../output_sd/images/
cd ../
rm -rf temp_bootloader_sd/
for target in $TARGETS; do
upper=$(printf '%s' "$target" | tr '[:lower:]' '[:upper:]')
bootloader_var="BOOTLOADER_${upper}"
bootloader="${!bootloader_var}"
temp_dir="temp_bootloader_${target}"
out_dir="output_${target}/images"
echo "Downloading eMMC bootloader: ${BOOTLOADER_EMMC}"
gh release download latest-boot --pattern "*${BOOTLOADER_EMMC}*" --dir temp_bootloader_emmc/
mkdir -p output_emmc/images
cd temp_bootloader_emmc/
tar -xzf *.tar.gz --strip-components=1 -C ../output_emmc/images/
cd ../
rm -rf temp_bootloader_emmc/
echo "Downloading ${target} bootloader: ${bootloader}"
mkdir -p "$out_dir"
gh release download latest-boot --pattern "*${bootloader}*" --dir "$temp_dir/"
tar -xzf "$temp_dir"/*.tar.gz --strip-components=1 -C "$out_dir/"
rm -rf "$temp_dir"
echo "SD bootloader files:"
ls -la output_sd/images/
echo "eMMC bootloader files:"
ls -la output_emmc/images/
else
# Single bootloader for boards that only support SD
gh release download latest-boot --pattern "*${BOOTLOADER}*" --dir temp_bootloader/
# Extract bootloader directly to output/images
cd temp_bootloader/
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/
cd ../
rm -rf temp_bootloader/
echo "Bootloader files extracted to output/images:"
ls -la output/images/
fi
echo "${target} bootloader files:"
ls -la "$out_dir/"
done
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Download Infix artifacts
run: |
# Download from latest Kernelkit Trigger workflow for main branch
gh run list --workflow=164295764 --branch=main --limit=1 --status=success --json databaseId --jq '.[0].databaseId' > latest_infix_run_id
INFIX_RUN_ID=$(cat latest_infix_run_id)
if [ "$BUILD_EMMC" = "true" ]; then
# Copy Infix artifacts to both SD and eMMC output directories
gh run download ${INFIX_RUN_ID} --name artifact-${ARCH} --dir temp_infix/
gh run download ${INFIX_RUN_ID} --name artifact-${ARCH} --dir temp_infix/
cd temp_infix/
tar -xzf *.tar.gz --strip-components=1 -C ../output_sd/images/
tar -xzf *.tar.gz --strip-components=1 -C ../output_emmc/images/
cd ../
rm -rf temp_infix/
for target in $TARGETS; do
out_dir="output_${target}/images"
mkdir -p "$out_dir"
tar -xzf temp_infix/*.tar.gz --strip-components=1 -C "$out_dir/"
echo "Infix files extracted to output_sd/images:"
ls -la output_sd/images/
echo "Infix files extracted to output_emmc/images:"
ls -la output_emmc/images/
else
# Single output directory for SD-only boards
gh run download ${INFIX_RUN_ID} --name artifact-${ARCH} --dir temp_infix/
echo "Infix files extracted to ${out_dir}:"
ls -la "$out_dir/"
done
# Extract Infix directly to output/images
cd temp_infix/
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/
cd ../
rm -rf temp_infix/
echo "Infix files extracted to output/images:"
ls -la output/images/
fi
rm -rf temp_infix/
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Verify extracted files
run: |
if [ "$BUILD_EMMC" = "true" ]; then
echo "Files available for SD image:"
ls -la output_sd/images/
for target in $TARGETS; do
echo "Files available for ${target} image:"
ls -la "output_${target}/images/"
echo ""
echo "Files available for eMMC image:"
ls -la output_emmc/images/
else
echo "Files available for mkimage.sh:"
ls -la output/images/
echo ""
echo "File types:"
file output/images/* || true
fi
done
- name: Create SD card image
- name: Create images
run: |
if [ "$BUILD_EMMC" = "true" ]; then
export BINARIES_DIR=$PWD/output_sd/images
export BUILD_DIR=$PWD/build
export BR2_EXTERNAL_INFIX_PATH=$PWD
export RELEASE=""
export INFIX_ID="infix"
./utils/mkimage.sh -t sdcard ${{ inputs.board }}
else
export BINARIES_DIR=$PWD/output/images
export BUILD_DIR=$PWD/build
export BR2_EXTERNAL_INFIX_PATH=$PWD
export RELEASE=""
export INFIX_ID="infix"
./utils/mkimage.sh -t sdcard ${{ inputs.board }}
fi
- name: Create eMMC image
if: ${{ env.BUILD_EMMC == 'true' }}
run: |
export BINARIES_DIR=$PWD/output_emmc/images
export BUILD_DIR=$PWD/build
export BR2_EXTERNAL_INFIX_PATH=$PWD
export RELEASE=""
export INFIX_ID="infix"
./utils/mkimage.sh -t emmc ${{ inputs.board }}
for target in $TARGETS; do
export BINARIES_DIR=$PWD/output_${target}/images
./utils/mkimage.sh -t "$target" ${{ inputs.board }}
done
- name: Verify created images
run: |
if [ "$BUILD_EMMC" = "true" ]; then
echo "SD card image:"
ls -lh output_sd/images/*-sdcard.img* 2>/dev/null || true
if ls output_sd/images/*-sdcard.img 1> /dev/null 2>&1; then
for img in output_sd/images/*-sdcard.img; do
echo "- $(basename $img)"
file "$img"
fdisk -l "$img" 2>/dev/null | head -20
done
fi
mkdir -p output/images
echo ""
echo "eMMC image:"
ls -lh output_emmc/images/*-emmc.img* 2>/dev/null || true
if ls output_emmc/images/*-emmc.img 1> /dev/null 2>&1; then
for img in output_emmc/images/*-emmc.img; do
echo "- $(basename $img)"
file "$img"
fdisk -l "$img" 2>/dev/null | head -20
done
fi
for target in $TARGETS; do
src_dir="output_${target}/images"
found=false
# Copy both images to output/images for artifact upload
mkdir -p output/images
cp output_sd/images/*-sdcard.img* output/images/ 2>/dev/null || true
cp output_emmc/images/*-emmc.img* output/images/ 2>/dev/null || true
else
echo "Contents of output/images after mkimage.sh:"
ls -lh output/images/
echo "${target} image:"
ls -lh "$src_dir"/*-"$target".img* 2>/dev/null || true
# Look for SD card image with pattern: *-sdcard.img
if ls output/images/*-sdcard.img 1> /dev/null 2>&1; then
echo "Found SD card image(s):"
for img in output/images/*-sdcard.img; do
echo "- $(basename $img)"
file "$img"
fdisk -l "$img" 2>/dev/null || true
done
else
echo "No SD card image found matching pattern: *-sdcard.img"
echo "Available files:"
ls -la output/images/
for img in "$src_dir"/*-"$target".img; do
[ -e "$img" ] || continue
found=true
echo "- $(basename "$img")"
file "$img"
fdisk -l "$img" 2>/dev/null || true
done
if [ "$found" = false ]; then
echo "No ${target} image found matching pattern: *-${target}.img"
echo "Available files in ${src_dir}:"
ls -la "$src_dir/"
exit 1
fi
fi
for artifact in "$src_dir"/*-"$target".img*; do
[ -e "$artifact" ] || continue
cp "$artifact" output/images/
done
echo ""
done
- name: Upload images as artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: images-${{ inputs.board }}
path: |
@@ -308,37 +246,27 @@ jobs:
- name: Generate summary
run: |
if [ "$BUILD_EMMC" = "true" ]; then
cat <<EOF >> $GITHUB_STEP_SUMMARY
# SD Card & eMMC Image Build Complete! 🚀
cat <<EOF >> $GITHUB_STEP_SUMMARY
# Image Build Complete! 🚀
**Board:** ${{ inputs.board }}
**Arch:** ${{ env.ARCH }}
**SD Bootloader:** ${{ env.BOOTLOADER_SD }}
**eMMC Bootloader:** ${{ env.BOOTLOADER_EMMC }}
**Targets:** ${{ env.TARGETS }}
**Bootloader Source:** latest-boot release
**Infix Source:** Latest workflow run on main
## Bootloaders
$(for target in $TARGETS; do
case "$target" in
sdcard) bootloader="$BOOTLOADER_SDCARD" ;;
emmc) bootloader="$BOOTLOADER_EMMC" ;;
esac
printf -- '- %s: %s\n' "$target" "$bootloader"
done)
## Created Images
$(find output/images/ -name "*.img" -o -name "*.img.bmap" | xargs ls -lh 2>/dev/null | awk '{print "- " $9 " (" $5 ")"}' || echo "- No images found")
## Download
Both SD card and eMMC images are available as workflow artifacts above and in the latest-boot release.
The generated images are available as workflow artifacts above and in the latest-boot release.
EOF
else
cat <<EOF >> $GITHUB_STEP_SUMMARY
# SD Card Image Build Complete! 🚀
**Board:** ${{ inputs.board }}
**Arch:** ${{ env.ARCH }}
**Bootloader:** ${{ env.BOOTLOADER }}
**Bootloader Source:** latest-boot release
**Infix Source:** Latest workflow run on main
## Created Images
$(find output/images/ -name "*.img" -o -name "*.img.bmap" | xargs ls -lh 2>/dev/null | awk '{print "- " $9 " (" $5 ")"}' || echo "- No images found")
## Download
The SD card image is available as a workflow artifact above.
EOF
fi
+3 -3
View File
@@ -23,7 +23,7 @@ jobs:
target: [aarch64, arm, x86_64]
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
clean: true
submodules: recursive
@@ -86,12 +86,12 @@ jobs:
ln -s ${{ steps.vars.outputs.dir }} images
tar cfz ${{ steps.vars.outputs.tgz }} ${{ steps.vars.outputs.dir }}
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: artifact-${{ matrix.target }}
path: output/*.tar.gz
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: artifact-disk-image-${{ matrix.target }}
path: output/images/*.qcow2
+2 -2
View File
@@ -80,7 +80,7 @@ jobs:
ls -la ./
- name: Checkout infix repo
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
repository: ${{ env.INFIX_REPO }}
ref: ${{ env.INFIX_BRANCH != '' && env.INFIX_BRANCH || github.ref }}
@@ -178,7 +178,7 @@ jobs:
ln -s ${{ steps.vars.outputs.dir }} images
tar cfz ${{ steps.vars.outputs.tgz }} ${{ steps.vars.outputs.dir }}
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
path: output/${{ steps.vars.outputs.tgz }}
name: artifact-${{ env.TARGET }}
+2 -2
View File
@@ -12,7 +12,7 @@ jobs:
steps:
- name: Check out infix repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
fetch-depth: 0
token: ${{ secrets.KERNEL_UPDATE_TOKEN }}
@@ -103,7 +103,7 @@ jobs:
- name: Create pull request
if: steps.check.outputs.new_release == 'true'
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
github-token: ${{ secrets.KERNEL_UPDATE_TOKEN }}
script: |
+3 -3
View File
@@ -16,7 +16,7 @@ jobs:
if: ${{github.repository_owner == 'kernelkit'}}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Fetch latest Coverity Scan MD5
id: var
env:
@@ -27,7 +27,7 @@ jobs:
-O coverity-latest.tar.gz.md5
echo "md5=$(cat coverity-latest.tar.gz.md5)" | tee -a $GITHUB_OUTPUT
- uses: actions/cache@v4
- uses: actions/cache@v5
id: cache
with:
path: coverity-latest.tar.gz
@@ -98,7 +98,7 @@ jobs:
https://scan.coverity.com/builds?project=${PROJECT_NAME}
- name: Upload build.log
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: coverity-build.log
path: cov-int/build-log.txt
+2 -2
View File
@@ -24,12 +24,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Python
uses: actions/setup-python@v4
uses: actions/setup-python@v6
with:
python-version: '3.x'
+2 -2
View File
@@ -33,7 +33,7 @@ jobs:
mtools
- name: Checkout infix repo
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
repository: ${{ github.repository }}
ref: ${{ github.ref }}
@@ -77,7 +77,7 @@ jobs:
ln -s Infix-x86_64 images
tar cfz Infix-x86_64.tar.gz Infix-x86_64
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
path: output/Infix-x86_64.tar.gz
name: artifact-x86_64
+1 -1
View File
@@ -44,7 +44,7 @@ jobs:
checkout:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- uses: kernelkit/actions/cache-restore@v1
with:
target: x86_64
+2 -2
View File
@@ -48,7 +48,7 @@ jobs:
contents: write
discussions: write
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
submodules: 'true'
@@ -78,7 +78,7 @@ jobs:
echo "pre=${{ steps.rel.outputs.pre }}"
echo "latest=${{ steps.rel.outputs.latest }}"
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v7
with:
pattern: "artifact-*"
merge-multiple: true
+14 -6
View File
@@ -43,6 +43,11 @@ on:
type: string
default: ''
description: 'Optional script to run after checkout (for spin customization)'
release:
required: false
type: string
default: ''
description: 'Release version (e.g. v26.04.0), sets INFIX_RELEASE so make test finds versioned artifacts'
secrets:
CHECKOUT_TOKEN:
required: false
@@ -61,7 +66,7 @@ jobs:
runs-on: [self-hosted, regression]
steps:
- name: Checkout infix repo
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
repository: ${{ env.INFIX_REPO }}
ref: ${{ env.INFIX_BRANCH != '' && env.INFIX_BRANCH || github.ref }}
@@ -93,7 +98,7 @@ jobs:
run: |
make ${{ env.TARGET }}_defconfig
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v7
with:
pattern: "artifact-*"
merge-multiple: true
@@ -105,12 +110,15 @@ jobs:
ls -l
mkdir -p output
mv ${name}-${target}.tar.gz output/
tarfile=$(ls ${name}-${target}*.tar.gz | head -1)
mv "$tarfile" output/
cd output/
tar xf ${name}-${target}.tar.gz
ln -s ${name}-${target} images
tar xf "$tarfile"
ln -s "${tarfile%.tar.gz}" images
- name: Regression Test ${{ env.TARGET }}
env:
INFIX_RELEASE: ${{ inputs.release }}
run: |
if [ -n "$NINEPM_CONF" ]; then
export NINEPM_PROJ_CONFIG="${GITHUB_WORKSPACE}/$NINEPM_CONF"
@@ -131,7 +139,7 @@ jobs:
make test-dir="$(pwd)/$TEST_PATH" test-report
- name: Upload Test Report as Artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: test-report
path: output/images/test-report.pdf
+1 -1
View File
@@ -78,7 +78,7 @@ jobs:
ls -la ./
- name: Checkout infix repo
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
repository: ${{ env.INFIX_REPO }}
ref: ${{ env.INFIX_BRANCH != '' && env.INFIX_BRANCH || github.ref }}
+1 -1
View File
@@ -22,7 +22,7 @@ jobs:
permissions:
contents: write
steps:
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v6
with:
pattern: "artifact-*"
merge-multiple: true
+22 -3
View File
@@ -9,8 +9,10 @@ O ?= output
# otherwise treat it as relative to ./buildroot.
override O := $(if $(filter /%,$O),$O,$(CURDIR)/$O)
config := $(O)/.config
bmake = $(MAKE) -C buildroot O=$(O) $1
config := $(O)/.config
bmake = $(MAKE) -C buildroot O=$(O) $1
SNIPPETS_DIR := $(CURDIR)/configs/snippets
MERGE_CONFIG := $(CURDIR)/buildroot/support/kconfig/merge_config.sh
all: $(config) buildroot/Makefile
@@ -26,6 +28,23 @@ $(config):
@echo "'make <board>_defconfig' before building an image."
@exit 1
apply-%: $(SNIPPETS_DIR)/%.conf | $(config)
@KCONFIG_CONFIG=$(config) $(MERGE_CONFIG) -m $(config) $<
@+$(call bmake,olddefconfig)
@echo "Applied snippet: $<"
list-snippets:
@echo "Available snippets (use 'make apply-<name>'):"
@ls $(SNIPPETS_DIR)/*.conf 2>/dev/null | sed 's|.*/||; s|\.conf$$||; s|^| |'
dev: | $(config)
@for s in $(SNIPPETS_DIR)/*.conf; do \
KCONFIG_CONFIG=$(config) $(MERGE_CONFIG) -m $(config) $$s; \
echo "Applied snippet: $$s"; \
done
@+$(call bmake,olddefconfig)
@+$(call bmake,all)
%: | buildroot/Makefile
@+$(call bmake,$@)
@@ -44,4 +63,4 @@ test:
buildroot/Makefile:
@git submodule update --init
.PHONY: all check coverity dep test cyclonedx
.PHONY: all check coverity dep test cyclonedx list-snippets dev
+1
View File
@@ -1,6 +1,7 @@
if BR2_aarch64
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/alder-alder/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/acer-connect-vero-w6m/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/bananapi-bpi-r3/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/bananapi-bpi-r4/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/aarch64/bananapi-bpi-r64/Config.in"
+2
View File
@@ -4,10 +4,12 @@ aarch64
Board Specific Documentation
----------------------------
- [Acer Connect Vero W6m](acer-connect-vero-w6m/)
- [Banana Pi BPi-R3](bananapi-bpi-r3/)
- [Banana Pi BPi-R4](bananapi-bpi-r4/)
- [Banana Pi BPi-R64](bananapi-bpi-r64/)
- [Marvell CN9130-CRB](marvell-cn9130-crb/)
- [Marvell ESPRESSObin](marvell-espressobin/)
- [Microchip SparX-5i PCB135 (eMMC)](microchip-sparx5-pcb135/)
- [NanoPi R2S](friendlyarm-nanopi-r2s/)
- [Raspberry Pi 64-bit](raspberrypi-rpi64/)
@@ -0,0 +1,6 @@
config BR2_PACKAGE_ACER_CONNECT_VERO_W6M
bool "Acer Connect Vero W6m"
depends on BR2_aarch64
select BR2_PACKAGE_BANANAPI_BPI_R3
help
Build Acer Connect Vero W6m
@@ -0,0 +1,13 @@
Copyright (c) 2026 The KernelKit Authors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -0,0 +1,131 @@
# Acer Connect Vero W6m
<img src="connect_vero_w6m_case.jpg" alt="Acer Connect Vero W6m" width=400 padding=10>
## Overview
The Acer Connect Vero W6m is a compact WiFi 6/6E router platform based
on the MediaTek MT7986A SoC. In Infix it is supported as an eMMC-based
target that reuses the factory secure boot chain while replacing the
system partitions with an Infix installation.
The Acer Connect Vero W6m is based on the same MT7986a SoC as the
BPI-R3, with tri-band WiFi (2.4 GHz + 5 GHz + 6 GHz) using a PCIe
MT7916 module and the SoC's built-in MT7976 DBDC radio.
## Default WiFi Layout
The factory configuration on this branch enables all three radios in AP
mode and bridges them into the default LAN bridge `br0`:
- `radio0` / `wifi0-ap`: 2.4 GHz, SSID `Infix`
- `radio1` / `wifi1-ap`: 6 GHz, SSID `Infix6G`
- `radio2` / `wifi2-ap`: 5 GHz, SSID `Infix5G`
6 GHz operation is enabled in the MT7915e driver configuration, and all
three APs use the same default passphrase `infixinfix` from the factory
configuration.
Secure boot is enabled on this device, so the factory bootloader
(partitions 1-4: bl2, u-boot-env, factory, fip) must not be modified.
Infix is installed by replacing partitions 5+ while keeping the
factory bootloader intact. The stock U-Boot chainloads the Infix
U-Boot from the first partition after fip.
## Prerequisites
- Serial console access (115200 8N1) — required to interrupt U-Boot.
Disassembly is needed to reach the UART header. See the [OpenWrt
Vero W6m page][vero-openwrt] for details.
- TFTP server on the local network with `u-boot.bin` for the initial
RAM boot.
- SSH access from the running Infix system to a host that stores
`infix-vero-w-emmc.img`.
- Ethernet cable connected between the PC and the Vero Internet/WAN
port.
- DHCP server running on the PC, serving addresses on that link during
installation.
- **Save the MAC addresses** from the stock U-Boot environment before
installing. Interrupt autoboot and run `printenv` to note down:
`2gMAC`, `5gMAC`, `6gMAC`, `LANMAC`, and `WANMAC`.
## Required Files
Prepare these files on a host reachable from the Vero:
1. **Infix Vero image:**
- [infix-vero-w-emmc.img][1] (Complete system image)
2. **eMMC bootloader** (extracted from):
- [bpi-r3-emmc-boot-2025.01-latest.tar.gz][2]
- Extract `u-boot.bin` from the tarball to your TFTP server
## Installing Infix
Connect the PC directly to the Vero Internet/WAN port before starting
the installation. The PC should provide DHCP service on that link so
the stock U-Boot and the temporary Infix system can reach the TFTP/SSH
host.
1. **RAM-load Infix U-Boot** from the stock U-Boot serial console
(hit any key to stop autoboot):
```
setenv serverip <TFTP_SERVER_IP>
setenv ipaddr <VERO_IP>
setenv bootmenu_default 7
tftpboot 0x46000000 u-boot.bin
go 0x46000000
```
`serverip` must point to your TFTP server and `ipaddr` must be a free
address for the Vero on the same subnet. `bootmenu_default 7`
bypasses secure boot verification. The Infix U-Boot will
automatically netboot the Infix system.
2. **From running Infix**, stream the image directly to eMMC:
```bash
ssh <USER>@<HOST> "dd if=/path/to/infix-vero-w-emmc.img bs=512 skip=17408 status=none" | \
dd of=/dev/mmcblk0 bs=512 seek=17408 conv=fsync
sync
```
This writes only the Infix partitions (starting after fip at sector
17408), leaving the factory bootloader and calibration data intact.
Do not interrupt the transfer; if it fails, rerun the command from
the beginning.
3. **Update the GPT** to replace stock partitions 5+ with the Infix
layout:
```bash
sudo sgdisk --zap-all /dev/mmcblk0
sudo sgdisk -a 1 \
-n2:8192:9215 -c2:u-boot-env \
-n3:9216:13311 -c3:factory \
-n4:13312:17407 -c4:fip \
-n5:17408:+32M -c5:infix-uboot \
-n6:0:+8M -c6:aux \
-n7:0:+250M -c7:primary \
-n8:0:+250M -c8:secondary \
-n9:0:+128M -c9:cfg \
-n10:0:+128M -c10:var \
-p /dev/mmcblk0
```
4. **Configure U-Boot to chainload Infix permanently** — reboot and
interrupt stock U-Boot again:
```
setenv bootmenu_default 7
setenv bootcmd 'mmc read 0x46000000 0x4400 0x10000; go 0x46000000'
saveenv
reset
```
The `bootcmd` reads the Infix U-Boot (at sector 0x4400/17408)
into RAM and jumps to it. After `reset`, Infix boots from eMMC.
[vero-openwrt]: https://openwrt.org/toh/acer/predator_vero_w6m
[1]: https://github.com/kernelkit/infix/releases/download/latest-boot/infix-vero-w-emmc.img
[2]: https://github.com/kernelkit/infix/releases/download/latest-boot/bpi-r3-emmc-boot-2025.01-latest.tar.gz
@@ -0,0 +1,2 @@
# Locally calculated
sha256 d48246c717b505cc11df95171f2fd548b389e1a463f1af4c68d0b69fe0d1009b LICENSE
@@ -0,0 +1,2 @@
$(eval $(ix-board))
$(eval $(generic-package))
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

@@ -0,0 +1 @@
dtb-y += mediatek/mt7986a-acer-connect-vero-w6m.dtb
@@ -0,0 +1,425 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
#include <dt-bindings/input/input.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/leds/common.h>
#include <dt-bindings/pinctrl/mt65xx.h>
#include <arm64/mediatek/mt7986a.dtsi>
/ {
chosen {
stdout-path = "serial0:115200n8";
infix {
/* Default admin user password: 'admin' */
factory-password-hash = "$5$mI/zpOAqZYKLC2WU$i7iPzZiIjOjrBF3NyftS9CCq8dfYwHwrmUK097Jca9A";
};
};
memory@40000000 {
reg = <0 0x40000000 0 0x20000000>;
device_type = "memory";
};
reg_1p8v: regulator-1p8v {
compatible = "regulator-fixed";
regulator-name = "fixed-1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-boot-on;
regulator-always-on;
};
reg_3p3v: regulator-3p3v {
compatible = "regulator-fixed";
regulator-name = "fixed-3.3V";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-boot-on;
regulator-always-on;
};
reg_5v: regulator-5v {
compatible = "regulator-fixed";
regulator-name = "fixed-5V";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
regulator-boot-on;
regulator-always-on;
};
gpio-keys {
compatible = "gpio-keys";
factory {
label = "factory";
linux,code = <KEY_RESTART>;
gpios = <&pio 9 GPIO_ACTIVE_LOW>;
};
wps {
label = "wps";
linux,code = <KEY_WPS_BUTTON>;
gpios = <&pio 10 GPIO_ACTIVE_LOW>;
};
};
};
&watchdog {
status = "okay";
};
&pio {
wifi_rst_hog: wifi-reset-hog {
gpio-hog;
gpios = <6 GPIO_ACTIVE_LOW>;
output-low;
line-name = "wifi-reset";
};
mmc0_pins_default: mmc0-pins {
mux {
function = "emmc";
groups = "emmc_51";
};
conf-cmd-dat {
pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
"EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
"EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
input-enable;
drive-strength = <MTK_DRIVE_4mA>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
};
conf-clk {
pins = "EMMC_CK";
drive-strength = <MTK_DRIVE_6mA>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
};
conf-ds {
pins = "EMMC_DSL";
bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
};
conf-rst {
pins = "EMMC_RSTB";
drive-strength = <MTK_DRIVE_4mA>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
};
};
mmc0_pins_uhs: mmc0-uhs-pins {
mux {
function = "emmc";
groups = "emmc_51";
};
conf-cmd-dat {
pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
"EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
"EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
input-enable;
drive-strength = <MTK_DRIVE_4mA>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
};
conf-clk {
pins = "EMMC_CK";
drive-strength = <MTK_DRIVE_6mA>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
};
conf-ds {
pins = "EMMC_DSL";
bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
};
conf-rst {
pins = "EMMC_RSTB";
drive-strength = <MTK_DRIVE_4mA>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
};
};
pcie_pins: pcie-pins {
mux {
function = "pcie";
groups = "pcie_pereset";
};
};
wf_2g_5g_pins: wf_2g_5g-pins {
mux {
function = "wifi";
groups = "wf_2g", "wf_5g";
};
conf {
pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4",
"WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6",
"WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10",
"WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1",
"WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0",
"WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8",
"WF1_TOP_CLK", "WF1_TOP_DATA";
drive-strength = <MTK_DRIVE_4mA>;
};
};
wf_dbdc_pins: wf-dbdc-pins {
mux {
function = "wifi";
groups = "wf_dbdc";
};
conf {
pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4",
"WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6",
"WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10",
"WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1",
"WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0",
"WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8",
"WF1_TOP_CLK", "WF1_TOP_DATA";
drive-strength = <MTK_DRIVE_4mA>;
};
};
i2c_pins: i2c-pins {
mux {
function = "i2c";
groups = "i2c";
};
};
};
&trng {
status = "okay";
};
&crypto {
status = "okay";
};
&uart0 {
status = "okay";
};
&i2c0 {
pinctrl-names = "default";
pinctrl-0 = <&i2c_pins>;
status = "okay";
};
&mmc0 {
status = "okay";
pinctrl-names = "default", "state_uhs";
pinctrl-0 = <&mmc0_pins_default>;
pinctrl-1 = <&mmc0_pins_uhs>;
bus-width = <0x08>;
max-frequency = <200000000>;
cap-mmc-highspeed;
mmc-hs200-1_8v;
mmc-hs400-1_8v;
hs400-ds-delay = <0x14014>;
vmmc-supply = <&reg_3p3v>;
vqmmc-supply = <&reg_1p8v>;
non-removable;
no-sd;
no-sdio;
#address-cells = <1>;
#size-cells = <0>;
card@0 {
compatible = "mmc-card";
reg = <0>;
block {
compatible = "block-device";
partitions {
block-partition-factory {
partname = "factory";
nvmem: nvmem-layout {
compatible = "fixed-layout";
#address-cells = <1>;
#size-cells = <1>;
eeprom_factory_0: eeprom@0 {
reg = <0x0 0x1000>;
};
precal_factory_1010: precal@1010 {
reg = <0x1010 0x62810>;
};
};
};
};
};
};
};
&pcie {
pinctrl-names = "default";
pinctrl-0 = <&pcie_pins>;
num-lanes = <1>;
status = "okay";
slot0: pcie@0,0 {
reg = <0x0000 0 0 0 0>;
#address-cells = <0x03>;
#size-cells = <0x02>;
pcie_wifi: wifi@0,0 {
compatible = "mediatek,mt76";
reg = <0x0000 0 0 0 0>;
};
};
};
&pcie_phy {
status = "okay";
};
&pcie_port {
clocks = <&clk40m>, <&topckgen CLK_TOP_PCIE_PHY_SEL>;
clock-names = "ref", "da_ref";
};
&eth {
status = "okay";
gmac0: mac@0 {
compatible = "mediatek,eth-mac";
reg = <0>;
phy-mode = "2500base-x";
fixed-link {
speed = <2500>;
full-duplex;
pause;
};
};
mdio: mdio-bus {
#address-cells = <1>;
#size-cells = <0>;
switch: switch@1f {
compatible = "mediatek,mt7531";
reg = <31>;
reset-gpios = <&pio 5 GPIO_ACTIVE_HIGH>;
ports {
#address-cells = <1>;
#size-cells = <0>;
swport0: port@0 {
reg = <0>;
phy-handle = <&swphy0>;
};
port@1 {
reg = <1>;
label = "lan1";
phy-handle = <&swphy1>;
};
port@2 {
reg = <2>;
label = "lan2";
phy-handle = <&swphy2>;
};
port@3 {
reg = <3>;
label = "lan3";
phy-handle = <&swphy3>;
};
port@6 {
reg = <6>;
label = "cpu";
ethernet = <&gmac0>;
phy-mode = "2500base-x";
fixed-link {
speed = <2500>;
full-duplex;
pause;
};
};
};
mdio {
#address-cells = <1>;
#size-cells = <0>;
swphy0: phy@0 {
reg = <0>;
mediatek,led-config = <
0x21 0x8008 /* BASIC_CTRL */
0x22 0x0c00 /* ON_DURATION */
0x23 0x1400 /* BLINK_DURATION */
0x24 0xc001 /* LED0_ON_CTRL */
0x25 0x0003 /* LED0_BLINK_CTRL */
0x26 0xc006 /* LED1_ON_CTRL */
0x27 0x003c /* LED1_BLINK_CTRL */
>;
};
swphy1: phy@1 {
reg = <1>;
mediatek,led-config = <
0x21 0x8008 /* BASIC_CTRL */
0x22 0x0c00 /* ON_DURATION */
0x23 0x1400 /* BLINK_DURATION */
0x24 0xc001 /* LED0_ON_CTRL */
0x25 0x0003 /* LED0_BLINK_CTRL */
0x26 0xc006 /* LED1_ON_CTRL */
0x27 0x003c /* LED1_BLINK_CTRL */
>;
};
swphy2: phy@2 {
reg = <2>;
mediatek,led-config = <
0x21 0x8008 /* BASIC_CTRL */
0x22 0x0c00 /* ON_DURATION */
0x23 0x1400 /* BLINK_DURATION */
0x24 0xc001 /* LED0_ON_CTRL */
0x25 0x0003 /* LED0_BLINK_CTRL */
0x26 0xc006 /* LED1_ON_CTRL */
0x27 0x003c /* LED1_BLINK_CTRL */
>;
};
swphy3: phy@3 {
reg = <3>;
mediatek,led-config = <
0x21 0x8008 /* BASIC_CTRL */
0x22 0x0c00 /* ON_DURATION */
0x23 0x1400 /* BLINK_DURATION */
0x24 0xc001 /* LED0_ON_CTRL */
0x25 0x0003 /* LED0_BLINK_CTRL */
0x26 0xc006 /* LED1_ON_CTRL */
0x27 0x003c /* LED1_BLINK_CTRL */
>;
};
};
};
};
};
&wifi {
nvmem-cells = <&eeprom_factory_0>, <&precal_factory_1010>;
nvmem-cell-names = "eeprom", "precal";
pinctrl-names = "default", "dbdc";
pinctrl-0 = <&wf_2g_5g_pins>;
pinctrl-1 = <&wf_dbdc_pins>;
status = "okay";
};
@@ -0,0 +1,263 @@
/* Factory EEPROM for MT7976 WMAC (DBDC) - Acer Connect Vero W */
/* Band 1 patched from 5GHz-only to 5GHz+6GHz selectable */
&wifi {
mediatek,eeprom-data = <
0x86790100 0x000c4326 0x60100000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x01000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000800 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x12525353 0x003c003f 0x3a100700 0x15030000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x0000be00 0x00000000
0x0000c100 0x00000000 0x00000000 0xc3000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000009 0x00000000 0x00000000
0x00000000 0x00000303 0x03030303 0x03030303
0x03030303 0x03030303 0x03040303 0x03040303
0x03040303 0x03040000 0x00161b18 0x1b1a1a1a
0x1a0d0008 0x0f0d0209 0x0e0d0209 0x0e0d0209
0x0e0c020a 0x0e0c020a 0x0e0c020a 0x0e0b020b
0x0e2b2b2b 0x2b222222 0x22222222 0x22222222
0x22222222 0x22222222 0x22000000 0x00000000
0x00000000 0x002a2a2a 0x2a282828 0x282a2a2a
0x2a282828 0x282a2a2a 0x2a282828 0x282a2a2a
0x2a282828 0x28000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x007f7f20 0x2530363c 0x41014847 0x4c52575c
0x7f7f7f7f 0x1b222a33 0x3a40014d 0x464c525a
0x5e7f7f7f 0x7f252834 0x3c424a01 0x4a4f555d
0x636e7f7f 0x7f7f202a 0x303b444a 0x014a5158
0x5f666e7f 0x7f7f7f7f 0x8080c5c5 0xd1d1dddd
0xe5e5f3f3 0x40408080 0xcfcfdbdb 0xe3e3efef
0xf7f74040 0x8080bfbf 0xcbcbd9d9 0xe5e5eded
0x40408080 0xb9b9c5c5 0xd3d3dfdf 0xe7e74040
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0xc0a0c0e0 0xfcfcafe0 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x02200220 0x02200220 0x02300230 0x02300230
0x02300230 0x02300230 0x02300230 0x02300230
0x02240224 0x02240224 0x02240224 0x02240224
0x02240224 0x02240224 0x02240224 0x02240224
0x000000c4 0xc4c4c4c4 0x0000c4c4 0xc4c4c1c1
0x008282c3 0xc3000000 0x00838300 0xc4c4c4c1
0xc1008282 0x8383c3c3 0xc2c10000 0x83838484
0xc4c4c4c1 0xc1008282 0x8383c4c4 0xc4c1c100
0x82828383 0xc4c4c4c1 0xc1008282 0x8383c4c4
0xc3c100c4 0x81c4c3c2 0x00818181 0xc4c4c3c2
0x00818282 0x00c4c4c2 0xc2008182 0x8200c4c4
0xc3c20081 0x82828484 0xc4c4c3c2 0x00818282
0x8484c4c4 0xc2c20081 0x82828484 0xc4c4c2c1
0x81828383 0x8585c4c4 0xc3c20081 0x82828484
0xc4c4c3c2 0x00818282 0x8484c4c4 0xc3c20081
0x82828484 0xc6c5c3c1 0x00c5c5c3 0xc2008182
0x828484c5 0xc5c3c200 0x81828284 0x84c4c4c3
0xc2008182 0x828484c4 0xc4c2c181 0x82838385
0x85c5c5c3 0xc2008182 0x828484c5 0xc5c3c200
0x81828284 0x84c5c5c3 0xc2008182 0x82848400
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x378a6e05 0x0ae64a6c 0x00000000 0x50050000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00b40000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x86828786 0x87c8cb8a 0x8380c982 0x00c8ca86
0x8383c583 0x83c1c58c 0x8883c78b 0x8780c28c
0x8485c682 0xc3c4c4c4 0xc5c6c7c8 0xcfcecdcc
0xcccdcec1 0xc1c1c1c2 0xc4c6c7ce 0xcecfcfcf
0xcecec6c7 0xc8c9caca 0xcbcbd2d2 0xd2d2d0ce
0xcc8100c1 0xc3c5c6c7 0xc8d0d0d1 0xd1d1d0cf
0xdeee6be7 0x5fede2eb 0xce08ce09 0xce0ace0a
0x4e0b4f0b 0x4f0c4f0c 0x4f0d4f0d 0x540a540b
0x540c540b 0x540c510a 0x510b510c 0xd10c510d
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0xde0fde10 0xde115e12
0xde12de12 0xde135e14 0x5e0cde0d 0xde0e5e10
0x5e105e10 0x5e11de11 0xde0ede0f 0xde10de11
0x5e12de12 0x5e135e13 0xde0f5e11 0x5e12de13
0x5e13de13 0xde14de14 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00848484 0x84848484 0x84000000 0x00e4d5d4
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
>;
};
@@ -0,0 +1,263 @@
/* Factory EEPROM for PCIe MT7916 radio - Acer Connect Vero W */
/* Offset 0xa0000 in the "factory" GPT partition on eMMC */
&pcie_wifi {
mediatek,eeprom-data = <
0x16790000 0x000c4326 0x60000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x50750000 0x07670700 0x00000400 0x50710000
0x00000000 0x00000400 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0xb101e748 0xf57f5e99
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000800 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x12924848 0x003e003f 0x3a100000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x81a3a380
0xa4910091 0x00910091 0x00910000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x000a0000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x0000c500 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000013 0x12120000 0x00000000
0x00000000 0x00000303 0x03030303 0x03030303
0x03030303 0x03030505 0x05050505 0x05050505
0x05050505 0x05050000 0x001b1919 0x19181818
0x180f0006 0x1c0e080a 0x170e080a 0x170d0809
0x170d020a 0x0e0d020a 0x0e0d020a 0x0e0b020a
0x0e22222c 0x2c2b2b2b 0x2b2b2b2b 0x2b2b2b2b
0x2b2b2b2b 0x2b2b2b2b 0x2b000000 0x00000000
0x00000000 0x001e201e 0x201e2020 0x201e201e
0x20201e20 0x20272929 0x29272727 0x27272929
0x29272727 0x27000000 0x00000000 0x00000000
0x00000000 0x00cdcfcf 0xcfcfcf00 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x007f7f20 0x2530363c 0x41014347 0x4c52575c
0x7f7f0000 0x00000000 0x00000000 0x00000000
0x0000007f 0x7f252834 0x3c424a01 0x4d4f555f
0x636e7f7f 0x7f7f202a 0x303b444a 0x014d5158
0x5f666e7f 0x7f7f7f7f 0x8080c5c5 0xcbcbd9d9
0xe1e1ebeb 0x40408080 0xcfcfdbdb 0xe3e3efef
0xf7f74040 0x8080c1c1 0xcdcdd5d5 0xe1e1eded
0x40408080 0xbbbbc7c7 0xcfcfdbdb 0xe7e74040
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0xb0900000 0x0000c0f0 0xf8000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x02000200 0x02000200 0x02000200 0x02000200
0x02000200 0x02000200 0x02000200 0x02000200
0x02000200 0x02000200 0x02000200 0x02000200
0x02000200 0x02000200 0x02000200 0x02000200
0x000000c6 0xc6c6c6c4 0x0000c5c5 0xc5c4c1c1
0x818383c3 0xc3c2c100 0x81848400 0xc5c5c4c1
0xc1818383 0x8585c3c3 0xc2c10081 0x84848686
0xc5c5c4c1 0xc1818383 0x8585c5c5 0xc4c1c181
0x83838585 0xc5c5c4c1 0xc1818383 0x8585c6c6
0xc4c300c6 0x00c6c4c3 0xc1008181 0xc6c6c4c3
0xc1008181 0x00c5c5c3 0xc2008182 0x8200c6c6
0xc4c3c100 0x81818686 0xc6c6c4c3 0xc1008181
0x8686c5c5 0xc3c20081 0x82828787 0xc5c5c3c2
0x00818282 0x8787c6c6 0xc4c3c100 0x81818686
0xc6c6c4c3 0xc1008181 0x8686c6c6 0xc4c3c100
0x81818686 0xc6c6c4c3 0x00c6c6c4 0xc3c10081
0x818686c6 0xc6c4c3c1 0x00818186 0x86c5c5c3
0xc2008182 0x828787c5 0xc5c3c281 0x82838388
0x88c6c6c4 0xc3c10081 0x818686c6 0xc6c4c3c1
0x00818186 0x86c6c6c4 0xc3c10081 0x81868600
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00b70000 0x00b70000 0x00000000 0x00000000
0x01000000 0x0000c400 0xb8008700 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0xc7c60000 0x89898987 0x87858381 0x898a8b8b
0x8a898785 0x88898988 0x87868584 0x00000000
0x00000000 0xcccfcecd 0xcdcacecd 0xcbcfcece
0xcfcfcfc7 0xcececdce 0xc7cfcec7 0xcfcfcfcf
0xcfcf0000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x7fe2f0e4 0x00000000 0xa4de24df 0xa4e0a4e1
0xa4e1a4de 0x24dfa4e0 0xa4e1a4e1 0xa4dea4df
0xa4e0a4e1 0xa4e1a4de 0xa4df24e0 0xa4e1a4e1
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0xde0fde0f 0xde0fde10
0xde11de11 0x5e12de12 0xde10de10 0xde10de11
0xde12de12 0xde13de13 0x5a085a09 0x5a0a5a0a
0x5a0a5a0a 0x5a0a5a0a 0x5a055a06 0x5a075a08
0x5a085a09 0x5a095a09 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00ded453
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
>;
};
@@ -0,0 +1,63 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/dts-v1/;
#include "mt7986a-acer-connect-vero-w6m-common.dtsi"
#include "mt7986a-acer-connect-vero-w6m-pcie-eeprom.dtsi"
/ {
model = "Acer Connect Vero W6m";
compatible = "acer,connect-vero-w", "mediatek,mt7986a";
aliases {
serial0 = &uart0;
led-boot = &led_status;
led-failsafe = &led_status;
led-running = &led_status;
led-upgrade = &led_status;
};
};
&i2c0 {
led-controller@30 {
compatible = "kinetic,ktd2026";
reg = <0x30>;
vin-supply = <&reg_5v>;
vio-supply = <&reg_3p3v>;
led_status: multi-led {
color = <LED_COLOR_ID_RGB>;
function = LED_FUNCTION_STATUS;
#address-cells = <1>;
#size-cells = <0>;
led@0 {
reg = <0>;
color = <LED_COLOR_ID_RED>;
};
led@1 {
reg = <1>;
color = <LED_COLOR_ID_GREEN>;
};
led@2 {
reg = <2>;
color = <LED_COLOR_ID_BLUE>;
};
};
};
};
&nvmem {
eeprom_factory_a0000: eeprom@a0000 {
reg = <0xa0000 0x1000>;
};
precal_factory_a1010: precal@a1010 {
reg = <0xa1010 0x62810>;
};
};
&swport0 {
label = "internet";
};
@@ -0,0 +1,86 @@
image cfg.ext4 {
empty = true
temporary = true
size = 128M
ext4 {
label = "cfg"
use-mke2fs = true
features = "uninit_bg"
extraargs = "-m 0 -i 4096"
}
}
image var.ext4 {
empty = true
temporary = true
size = 128M
ext4 {
label = "var"
use-mke2fs = true
features = "uninit_bg"
extraargs = "-m 0 -i 4096"
}
}
image #INFIX_ID##VERSION#-vero-w-#TARGET#.img {
hdimage {
partition-table-type = "gpt"
gpt-no-backup = true
}
/*
* Factory partitions (1-4) -- secure boot, do not overwrite.
* Offsets and sizes match the stock Acer GPT exactly.
* No image data is written, preserving factory content.
*/
partition u-boot-env {
offset = 8192s
size = 1024s
}
partition factory {
offset = 9216s
size = 4096s
}
partition fip {
offset = 13312s
size = 4096s
}
/* Infix U-Boot, chainloaded by stock bootloader */
partition infix-uboot {
offset = 17408s
image = "u-boot.bin"
size = 32M
}
partition aux {
partition-uuid = D4EF35A0-0652-45A1-B3DE-D63339C82035
image = "aux.ext4"
}
partition primary {
partition-type-uuid = 0FC63DAF-8483-4772-8E79-3D69D8477DE4
bootable = true
size = 250M
image = "rootfs.squashfs"
}
partition secondary {
partition-type-uuid = 0FC63DAF-8483-4772-8E79-3D69D8477DE4
bootable = true
size = 250M
image = "rootfs.squashfs"
}
partition cfg {
partition-uuid = 7aa497f0-73b5-47e5-b2ab-8752d8a48105
image = "cfg.ext4"
}
partition var {
partition-uuid = 8046A06A-E45A-4A14-A6AD-6684704A393F
image = "var.ext4"
}
}
@@ -0,0 +1,488 @@
{
"ieee802-dot1ab-lldp:lldp": {
"infix-lldp:enabled": true
},
"ietf-hardware:hardware": {
"component": [
{
"name": "USB",
"class": "infix-hardware:usb",
"state": {
"admin-state": "unlocked"
}
},
{
"class": "infix-hardware:usb",
"name": "USB2",
"state": {
"admin-state": "unlocked"
}
},
{
"name": "radio0",
"class": "infix-hardware:wifi",
"infix-hardware:wifi-radio": {
"country-code": "DE",
"band": "2.4GHz",
"channel": "auto"
}
},
{
"name": "radio1",
"class": "infix-hardware:wifi",
"infix-hardware:wifi-radio": {
"country-code": "DE",
"band": "6GHz",
"channel": "auto"
}
},
{
"name": "radio2",
"class": "infix-hardware:wifi",
"infix-hardware:wifi-radio": {
"country-code": "DE",
"band": "5GHz",
"channel": "auto"
}
}
]
},
"ietf-interfaces:interfaces": {
"interface": [
{
"name": "br0",
"type": "infix-if-type:bridge",
"ietf-ip:ipv4": {
"address": [
{
"ip": "192.168.0.1",
"prefix-length": 24
}
]
}
},
{
"name": "lan1",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "lan2",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "lan3",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv6": {},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "lo",
"type": "infix-if-type:loopback",
"ietf-ip:ipv4": {
"address": [
{
"ip": "127.0.0.1",
"prefix-length": 8
}
]
},
"ietf-ip:ipv6": {
"address": [
{
"ip": "::1",
"prefix-length": 128
}
]
}
},
{
"name": "internet",
"type": "infix-if-type:ethernet",
"ietf-ip:ipv4": {
"infix-dhcp-client:dhcp": {
"option": [
{
"id": "ntp-server"
},
{
"id": "broadcast"
},
{
"id": "domain"
},
{
"id": "hostname",
"value": "auto"
},
{
"id": "dns-server"
},
{
"id": "router"
},
{
"id": "netmask"
},
{
"id": "vendor-class",
"value": "Acer Connect Vero W"
}
]
}
},
"ietf-ip:ipv6": {
"infix-dhcpv6-client:dhcp": {
"option": [
{
"id": "ntp-server"
},
{
"id": "client-fqdn"
},
{
"id": "domain-search"
},
{
"id": "dns-server"
}
]
}
}
},
{
"name": "wifi0-ap",
"type": "infix-if-type:wifi",
"infix-interfaces:wifi": {
"radio": "radio0",
"access-point": {
"ssid": "Infix",
"security": {
"secret": "wifi"
}
}
},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "wifi1-ap",
"type": "infix-if-type:wifi",
"infix-interfaces:wifi": {
"radio": "radio1",
"access-point": {
"ssid": "Infix6G",
"security": {
"secret": "wifi"
}
}
},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
},
{
"name": "wifi2-ap",
"type": "infix-if-type:wifi",
"infix-interfaces:wifi": {
"radio": "radio2",
"access-point": {
"ssid": "Infix5G",
"security": {
"secret": "wifi"
}
}
},
"infix-interfaces:bridge-port": {
"bridge": "br0"
}
}
]
},
"ietf-keystore:keystore": {
"asymmetric-keys": {
"asymmetric-key": [
{
"name": "genkey",
"public-key-format": "infix-crypto-types:ssh-public-key-format",
"public-key": "",
"private-key-format": "infix-crypto-types:rsa-private-key-format",
"cleartext-private-key": "",
"certificates": {}
}
]
},
"symmetric-keys": {
"symmetric-key": [
{
"name": "wifi",
"cleartext-symmetric-key": "aW5maXhpbmZpeA==",
"key-format": "infix-crypto-types:passphrase-key-format"
}
]
}
},
"ietf-netconf-acm:nacm": {
"enable-nacm": true,
"read-default": "permit",
"write-default": "permit",
"exec-default": "permit",
"groups": {
"group": [
{
"name": "admin",
"user-name": [
"admin"
]
},
{
"name": "operator",
"user-name": []
},
{
"name": "guest",
"user-name": []
}
]
},
"rule-list": [
{
"name": "admin-acl",
"group": [
"admin"
],
"rule": [
{
"name": "permit-all",
"module-name": "*",
"access-operations": "*",
"action": "permit",
"comment": "Allow 'admin' group complete access to all operations and data."
}
]
},
{
"name": "operator-acl",
"group": [
"operator"
],
"rule": [
{
"name": "permit-system-rpcs",
"module-name": "ietf-system",
"rpc-name": "*",
"access-operations": "exec",
"action": "permit",
"comment": "Operators can reboot, shutdown, and set system time."
}
]
},
{
"name": "guest-acl",
"group": [
"guest"
],
"rule": [
{
"name": "deny-all-write+exec",
"module-name": "*",
"access-operations": "create update delete exec",
"action": "deny",
"comment": "Guests cannot change anything or exec rpcs."
}
]
},
{
"name": "default-deny-all",
"group": [
"*"
],
"rule": [
{
"name": "deny-password-access",
"path": "/ietf-system:system/authentication/user/password",
"access-operations": "*",
"action": "deny",
"comment": "No user except admins can access password hashes."
},
{
"name": "deny-keystore-access",
"module-name": "ietf-keystore",
"access-operations": "*",
"action": "deny",
"comment": "No user except admins can access cryptographic keys."
},
{
"name": "deny-truststore-access",
"module-name": "ietf-truststore",
"access-operations": "*",
"action": "deny",
"comment": "No user except admins can access trust store."
}
]
}
]
},
"ietf-netconf-server:netconf-server": {
"listen": {
"endpoints": {
"endpoint": [
{
"name": "default-ssh",
"ssh": {
"tcp-server-parameters": {
"local-bind": [
{
"local-address": "::"
}
]
},
"ssh-server-parameters": {
"server-identity": {
"host-key": [
{
"name": "default-key",
"public-key": {
"central-keystore-reference": "genkey"
}
}
]
}
}
}
}
]
}
}
},
"ietf-system:system": {
"hostname": "acer-connect-%m",
"ntp": {
"server": [
{
"name": "default",
"udp": {
"address": "pool.ntp.org"
}
}
]
},
"authentication": {
"user": [
{
"name": "admin",
"password": "$factory$",
"infix-system:shell": "bash"
}
]
},
"infix-system:motd-banner": "Li0tLS0tLS0uCnwgIC4gLiAgfCBJbmZpeCBPUyDigJQgSW1tdXRhYmxlLkZyaWVuZGx5LlNlY3VyZQp8LS4gdiAuLXwgaHR0cHM6Ly9rZXJuZWxraXQub3JnCictJy0tLSctJwo="
},
"infix-dhcp-server:dhcp-server": {
"option": [
{
"id": "ntp-server",
"address": "auto"
},
{
"id": "dns-server",
"address": "auto"
},
{
"id": "router",
"address": "auto"
}
],
"subnet": [
{
"subnet": "192.168.0.0/24",
"pool": {
"start-address": "192.168.0.100",
"end-address": "192.168.0.250"
}
}
]
},
"infix-firewall:firewall": {
"default": "wan",
"zone": [
{
"name": "lan",
"action": "accept",
"interface": [
"br0"
]
},
{
"name": "wan",
"action": "drop",
"interface": [
"internet"
],
"service": [
"dhcpv6-client"
]
}
],
"policy": [
{
"name": "lan-to-wan",
"action": "accept",
"ingress": [
"lan"
],
"egress": [
"wan"
],
"masquerade": true
}
]
},
"infix-meta:meta": {
"version": "1.7"
},
"infix-services:mdns": {
"enabled": true
},
"infix-services:ssh": {
"enabled": true,
"hostkey": [
"genkey"
],
"listen": [
{
"name": "ipv4",
"address": "0.0.0.0",
"port": 22
},
{
"name": "ipv6",
"address": "::",
"port": 22
}
]
},
"infix-services:web": {
"enabled": true,
"console": {
"enabled": true
},
"netbrowse": {
"enabled": true
},
"restconf": {
"enabled": true
}
}
}
+1
View File
@@ -6,6 +6,7 @@ config BR2_PACKAGE_BANANAPI_BPI_R3
select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK
select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7986
select BR2_PACKAGE_LINUX_FIRMWARE_AIROHA_EN8811H
select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7916
select SDCARD_AUX
help
Build Banana PI R3 support
+7 -5
View File
@@ -70,11 +70,11 @@ The BPI-R3 has a 4-position DIP switch that controls boot media:
<img align="right" src="bootstrap-switch.webp" alt="DIP switches" width=200 padding=10>
| Position | Mode | Description |
|----------|-------------|---------------------------------------|
| 0000 | SD card | Boot from microSD card |
| 0110 | eMMC | Boot from internal eMMC (recommended) |
| 1010 | SPI NAND | Boot from SPI NAND (advanced users) |
| ABCD | Mode | Description |
|------|----------|---------------------------------------|
| 0000 | SD card | Boot from microSD card |
| 0101 | SPI NAND | Boot from SPI NAND (advanced users) |
| 1001 | eMMC | Boot from internal eMMC (recommended) |
> [!NOTE]
> Switch position is read from left to right: "0" = OFF, "1" = ON.
@@ -150,6 +150,7 @@ From the U-Boot prompt:
usb start
fatload usb 0:1 0x50000000 infix-bpi-r3-emmc.img
setexpr blocks ${filesize} / 0x200
mmc dev 0
mmc write 0x50000000 0x0 ${blocks}
```
@@ -211,6 +212,7 @@ sync
2. Set boot switches to eMMC mode (see image above)
3. Power on
## Troubleshooting
### Board won't boot
@@ -19,4 +19,34 @@ possible to use dtbo in sysboot unless present in syslinux.conf
no-sd;
no-sdio;
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
card@0 {
compatible = "mmc-card";
reg = <0>;
partitions {
compatible = "gpt-partitions";
partition-factory {
partname = "factory";
nvmem-layout {
compatible = "fixed-layout";
#address-cells = <1>;
#size-cells = <1>;
eeprom_factory_wmac: eeprom@0 {
reg = <0x0 0x1000>;
};
eeprom_factory_pcie: eeprom@a0000 {
reg = <0xa0000 0x1000>;
};
};
};
};
};
};
@@ -24,6 +24,18 @@ https://github.com/openwrt/openwrt/blob/main/target/linux/mediatek/patches-6.12/
&secmon_reserved {
reg = <0 0x43000000 0 0x40000>;
};
/*
* The T-PHY's pcie-phy sub-node only claims clk40m ("ref") in the SoC
* dtsi. CLK_TOP_PCIE_PHY_SEL ("da_ref") is left unclaimed, so the
* kernel's clk_disable_unused late_initcall gates it — killing the
* PCIe REFCLK output to the endpoint mid-probe. Wire it here so the
* clock stays enabled while the PHY is active.
*/
&pcie_port {
clocks = <&clk40m>, <&topckgen CLK_TOP_PCIE_PHY_SEL>;
clock-names = "ref", "da_ref";
};
&cpu_thermal {
/delete-node/ trips;
/delete-node/ cooling-maps;
@@ -4,7 +4,7 @@ CONFIG_BOOTDELAY=2
CONFIG_ENV_IS_NOWHERE=y
# CONFIG_ENV_IS_IN_MMC is not set
CONFIG_MULTI_DTB_FIT=y
CONFIG_OF_LIST="mt7986a-bpi-r3-sd mt7986a-bpi-r3-emmc mt7986a-bpi-r3-mini"
CONFIG_OF_LIST="mt7986a-bpi-r3-sd mt7986a-bpi-r3-emmc mt7986a-bpi-r3-mini mt7986a-acer-connect-vero-w6m"
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
+15 -2
View File
@@ -14,7 +14,7 @@ The Banana Pi BPI-R64 is a networking board based on the MediaTek MT7622
- 8 GB eMMC storage
- microSD card slot
- MT7531 Gigabit Ethernet switch (4x LAN + 1x WAN)
- MT7603E built-in 2.4 GHz WiFi
- MT7622 WMAC built-in 2.4 GHz 802.11ac WiFi
- USB 3.0 port
- 2x Mini PCIe slots
@@ -24,7 +24,7 @@ Infix comes preconfigured with:
- **LAN ports** (lan0-lan3): Bridged for internal networking
- **WAN port**: DHCP client enabled for internet connectivity
- **WiFi** (wifi0-ap): Bridged to LAN (MT7615 PCIe card if fitted, otherwise MT7603E)
- **WiFi** (wifi0-ap): Bridged to LAN (MT7622 WMAC, 2.4 GHz; or MT7615 PCIe card if fitted)
## Boot Switch Reference
@@ -113,6 +113,19 @@ mmc partconf 0 1 1 0
## Platform Notes
### WiFi
The MT7622 SoC includes a built-in WMAC that provides 2.4 GHz 802.11b/g/n/ac
(2×2) — there is no 5 GHz capability from the onboard radio.
For dual-band operation, a PCIe card can be fitted in one of the two Mini PCIe
slots. The [Banana Pi BPI-MT7615][bpi-mt7615] is a purpose-built dual-band
(2.4 + 5 GHz, 802.11ac 4×4) module designed for BPI router boards and is a
natural fit. With it installed, Infix will use it in preference to the onboard
WMAC for the `wifi0-ap` interface.
[bpi-mt7615]: https://docs.banana-pi.org/en/BPI-MT7615/BananaPi_MT7615
### mmc0 = eMMC, mmc1 = SD
On MT7622, MSDC0 (mmc0) is the 8-bit eMMC controller and MSDC1 (mmc1) is the
+232
View File
@@ -0,0 +1,232 @@
# Marvell ESPRESSObin
<img src="espressobin.png" alt="The board" width=800 padding=10>
The [ESPRESSObin][0] is a single-board computer based on the [Marvell Armada
3720][1] (dual Cortex-A53, AArch64) SoC and the [Marvell 88E6341][2] (Topaz)
switch, oriented toward networking applications.
The board design is old but the switch offers full Linux support, including
advanced TSN features for [IEEE 1588-2019][3] (PTP) and [IEEE 802.1AS-2020][4]
(gPTP).
## Board Variants
The board has gone through several hardware revisions:
| Revision | Storage | Notes |
|------------|---------------------|--------------------------------|
| v1, v3, v5 | SPI NOR only | Obsolete; U-Boot always in SPI |
| v7 | SPI NOR + 4 GB eMMC | Current; SD and eMMC usable |
| Ultra | SPI NOR + 4 GB eMMC | High-end variant |
On **all revisions** the Boot ROM is hardwired to load U-Boot from SPI NOR
flash. There is no strap or jumper to make the Boot ROM load directly from an
SD card. The SD card (or eMMC on v7/Ultra) is used only for the operating
system.
## Building
The ESPRESSObin uses ext4 for its rootfs partitions rather than the default
squashfs, because the stock SPI U-Boot lacks squashfs and `blkmap` support.
The `ext4` configuration snippet enables this. Apply it once after selecting
the defconfig, then build and compose the SD card image:
```sh
make O=x-aarch64 aarch64_defconfig
make O=x-aarch64 apply-ext4
make O=x-aarch64
utils/mkimage.sh -r x-aarch64 marvell-espressobin
```
The resulting image (`x-aarch64/images/infix-espressobin-sdcard.img`) contains
a GPT disk with the standard Infix partition layout, using ext4 instead of the
read-only squashfs:
| Partition | Label | Contents |
|-----------|-----------|------------------------------|
| 1 | aux | RAUC upgrade state (ext4) |
| 2 | primary | Rootfs slot primary (ext4) |
| 3 | secondary | Rootfs slot secondary (ext4) |
| 4 | cfg | Persistent config (ext4) |
| 5 | var | Runtime data (ext4) |
## Writing to SD Card
```sh
dd if=infix-espressobin-sdcard.img of=/dev/sdX bs=4M status=progress conv=fsync
```
## Upgrading
The build produces `x-aarch64/images/infix-aarch64-ext4.pkg`, a RAUC bundle
containing the ext4 rootfs. Once the board is running Infix, upgrade over the
network in the usual way:
```
upgrade ftp://192.168.1.1/infix-aarch64-ext4.pkg
```
RAUC writes the new rootfs to the inactive slot, updates `BOOT_ORDER` in
`/mnt/aux/uboot.env`, and the next boot picks it up automatically.
> [!NOTE]
> Use `infix-aarch64-ext4.pkg`, not the standard `infix-aarch64.pkg`. The
> standard bundle contains a squashfs rootfs which the stock U-Boot cannot
> boot.
## Booting with the Stock SPI U-Boot
The stock Marvell U-Boot has `ext4load` and the standard variables
(`$kernel_addr`, `$fdt_addr`, `$loadaddr`, `$console`, `$image_name`,
`$fdt_name`) already set sensibly. Connect to the board's console port, the
micro USB connector, at 115200 8N1, interrupt autoboot, and paste the commands
below.
### Environment Variable Reference
These variables are pre-set in the stock U-Boot environment. Restore them
with these values if they are ever lost or corrupted:
```
setenv kernel_addr 0x5000000
setenv fdt_addr 0x4f00000
setenv loadaddr 0x5000000
setenv console 'console=ttyMV0,115200 earlycon=ar3700_uart,0xd0012000'
setenv image_name boot/Image
setenv extra_params quiet
```
`$fdt_name` selects the device tree for your specific board revision:
| Board revision | `fdt_name` value |
|----------------|-----------------------------------------------------|
| v3 / v5 | `boot/marvell/armada-3720-espressobin.dtb` |
| v7 | `boot/marvell/armada-3720-espressobin-v7.dtb` |
| Ultra | `boot/marvell/armada-3720-espressobin-ultra.dtb` |
| v3/v5 eMMC | `boot/marvell/armada-3720-espressobin-emmc.dtb` |
| v7 eMMC | `boot/marvell/armada-3720-espressobin-v7-emmc.dtb` |
```
setenv fdt_name boot/marvell/armada-3720-espressobin.dtb # adjust for your board
```
### Simple Boot
Fixed boot from the primary slot, useful for initial bring-up:
```
setenv bootcmd 'mmc dev 0; \
ext4load mmc 0:2 $kernel_addr $image_name; \
ext4load mmc 0:2 $fdt_addr $fdt_name; \
setenv bootargs $console root=PARTLABEL=primary rw rootwait $extra_params rauc.slot=primary; \
booti $kernel_addr - $fdt_addr'
saveenv
```
### Automatic Slot Selection (RAUC Integration)
The CLI `upgrade` command writes to the inactive slot and updates `uboot.env`
on the `aux` partition with the new boot order. On the next boot U-Boot reads
`BOOT_ORDER` from the aux partition and selects the appropriate slot. The
setup below also defines `bootcmd_primary`, `bootcmd_secondary`, and
`bootcmd_net` for manual use (see [Manual Slot Selection](#manual-slot-selection)
and [Netbooting](#netbooting)):
```
setenv bootcmd_boot \
'mmc dev 0; \
ext4load mmc 0:$bootpart $kernel_addr $image_name; \
ext4load mmc 0:$bootpart $fdt_addr $fdt_name; \
setenv bootargs $console root=PARTLABEL=$bootslot rw rootwait $extra_params rauc.slot=$bootslot; \
booti $kernel_addr - $fdt_addr'
setenv bootcmd_primary 'setenv bootpart 2; setenv bootslot primary; run bootcmd_boot'
setenv bootcmd_secondary 'setenv bootpart 3; setenv bootslot secondary; run bootcmd_boot'
setenv bootcmd_net \
'dhcp $kernel_addr $image_name; \
tftpboot $fdt_addr $fdt_name; \
setenv bootargs $console root=PARTLABEL=primary rw rootwait $extra_params rauc.slot=primary; \
booti $kernel_addr - $fdt_addr'
setenv bootcmd \
'setenv bootpart 2; setenv bootslot primary; setenv auxpart 1; \
if ext4load mmc 0:$auxpart $loadaddr /uboot.env; then \
env import -c $loadaddr $filesize BOOT_ORDER; \
fi; \
if test "$BOOT_ORDER" = "secondary primary" || \
test "$BOOT_ORDER" = "secondary primary net"; then \
setenv bootpart 3; setenv bootslot secondary; \
fi; \
if test "$BOOT_ORDER" = "net" || \
test "$BOOT_ORDER" = "net primary" || \
test "$BOOT_ORDER" = "net secondary primary"; then \
run bootcmd_net; \
fi; \
echo ">> Booting $bootslot from mmc 0:$bootpart ..."; \
run bootcmd_boot'
saveenv
```
### Manual Slot Selection
To boot a specific slot without waiting for the autoboot countdown, interrupt
the bootloader (press any key) and run one of the convenience commands defined
above:
```
run bootcmd_primary # boot from primary (partition 2)
run bootcmd_secondary # boot from secondary (partition 3)
run bootcmd_net # netboot via DHCP/TFTP
```
You can also force a permanent change to which slot boots next by setting
`BOOT_ORDER` directly from Linux (the change persists across reboots):
```sh
fw_setenv BOOT_ORDER "secondary primary" # next boot: secondary
fw_setenv BOOT_ORDER "primary secondary" # next boot: primary (default)
```
### Netbooting
The stock U-Boot supports TFTP. This is useful for testing a new kernel or
device tree without reflashing the SD card. Set up a TFTP server with the
contents of the Infix `boot/` directory (from the built rootfs at
`x-aarch64/target/boot/`) and configure the variables:
```
setenv serverip 192.168.1.1 # IP of your TFTP server
setenv ipaddr 192.168.1.100 # board IP (omit if using dhcp)
saveenv
```
Then netboot manually:
```
run bootcmd_net
```
`bootcmd_net` uses `dhcp` to obtain an IP address and the `$serverip` from
the DHCP server (option 66), then downloads `$image_name` and `$fdt_name`
via TFTP. The kernel mounts the primary SD card slot as root, so the SD
card must still be present.
To make netbooting the default on next boot (e.g. for iterative kernel
development), set `BOOT_ORDER` from Linux:
```sh
fw_setenv BOOT_ORDER "net primary secondary"
```
This causes `bootcmd` to attempt netboot first; on failure it falls through
to the primary slot on the SD card.
[0]: https://wiki.espressobin.net/
[1]: https://www.marvell.com/content/dam/marvell/en/public-collateral/embedded-processors/marvell-embedded-processors-armada-37xx-hardware-specifications.pdf
[2]: https://www.marvell.com/content/dam/marvell/en/public-collateral/switching/marvell-link-street-88E6341-product-brief.pdf
[3]: https://standards.ieee.org/ieee/1588/6825/
[4]: https://standards.ieee.org/ieee/802.1AS/7121/
Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

@@ -1,25 +0,0 @@
image cfg.ext4 {
ext4 {
label = "cfg"
}
empty = true
size = 16M
}
image sdcard.img {
hdimage {
}
partition rootfs {
partition-type = 0x83
image = "rootfs.ext4"
}
partition cfg {
partition-type = 0x83
image = "cfg.ext4"
}
}
# Silence genimage warnings
config {}
@@ -0,0 +1,61 @@
image cfg.ext4 {
empty = true
temporary = true
size = 128M
ext4 {
label = "cfg"
use-mke2fs = true
features = "uninit_bg"
extraargs = "-m 0 -i 4096"
}
}
# The /var partition will be expanded automatically at first boot
# to use the full size of the SD-card.
image var.ext4 {
empty = true
temporary = true
size = 128M
ext4 {
label = "var"
use-mke2fs = true
features = "uninit_bg"
extraargs = "-m 0 -i 4096"
}
}
image #INFIX_ID##VERSION#-espressobin-#TARGET#.img {
hdimage {
partition-table-type = "gpt"
}
# No bootloader partition: U-Boot lives in SPI NOR flash on all
# ESPRESSObin board revisions. The SD card carries the OS only.
partition aux {
partition-uuid = D4EF35A0-0652-45A1-B3DE-D63339C82035
image = "aux.ext4"
}
partition primary {
partition-type-uuid = 0FC63DAF-8483-4772-8E79-3D69D8477DE4
bootable = true
image = "rootfs.ext2"
}
partition secondary {
partition-type-uuid = 0FC63DAF-8483-4772-8E79-3D69D8477DE4
bootable = true
image = "rootfs.ext2"
}
partition cfg {
partition-uuid = 7aa497f0-73b5-47e5-b2ab-8752d8a48105
image = "cfg.ext4"
}
partition var {
partition-uuid = 8046A06A-E45A-4A14-A6AD-6684704A393F
image = "var.ext4"
}
}
+1
View File
@@ -5,6 +5,7 @@ source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-aux/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-qcow/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-gns3a/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-rauc/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-ext4-rauc/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-itb-dl-release/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-readme/Config.in"
@@ -0,0 +1,27 @@
config IMAGE_EXT4_RAUC
bool "RAUC upgrade bundle (ext4)"
depends on BR2_TARGET_ROOTFS_EXT2
select BR2_PACKAGE_HOST_RAUC
help
Create a RAUC upgrade bundle for targets using an ext4 rootfs
image. Intended for development boards whose bootloader does
not support squashfs.
config IMAGE_EXT4_RAUC_KEY
string "signing key"
depends on IMAGE_EXT4_RAUC
default "${BR2_EXTERNAL_INFIX_PATH}/board/common/signing-keys/development/infix.key"
help
Path to the private key, in PKCS#8 format, used to sign
the RAUC bundle; or a PKCS#11 URI.
config IMAGE_EXT4_RAUC_CERT
string "signing certificate"
depends on IMAGE_EXT4_RAUC
default "${BR2_EXTERNAL_INFIX_PATH}/board/common/signing-keys/development/infix.crt"
help
Path to the X509 certificate which will be associated with
the bundle signature.
NOTE: This cert MUST be included in the trust store of the
system on which this bundle is to be installed.
+27
View File
@@ -0,0 +1,27 @@
#!/bin/sh
set -e
ext2="${BINARIES_DIR}/rootfs.ext2"
pkg="${BINARIES_DIR}/${ARTIFACT}-ext4.pkg"
# RAUC internally uses the file extension to find a suitable install
# handler, hence the name must be .img
cp -f "${ext2}" "${WORKDIR}/rootfs.img"
cat >"${WORKDIR}/manifest.raucm" <<EOF
[update]
compatible=${COMPATIBLE}
version=${VERSION}
[bundle]
format=verity
[image.rootfs]
filename=rootfs.img
EOF
rauc --cert="${CERT}" --key="${KEY}" \
bundle "${WORKDIR}" "${pkg}.next"
mv "${pkg}.next" "${pkg}"
@@ -0,0 +1,10 @@
################################################################################
#
# image-ext4-rauc
#
################################################################################
IMAGE_EXT4_RAUC_DEPENDENCIES := host-rauc
IMAGE_EXT4_RAUC_CONFIG_VARS := KEY CERT
$(eval $(ix-image))
@@ -0,0 +1,3 @@
service <!> name:phc2sys :%i log:prio:daemon,tag:phc2sys-%i \
[2345] phc2sys -a -z /var/run/ptp4l-%i \
-- PHC synchronization for PTP instance %i
@@ -0,0 +1,3 @@
service <!> name:ptp4l :%i log:prio:daemon,tag:ptp4l-%i \
[2345] ptp4l -f /etc/linuxptp/ptp4l-%i.conf \
-- PTP instance %i
@@ -567,6 +567,59 @@ def probe_wifi_radios(out):
out["wifi-radios"].append(info)
def probe_ptp_capabilities(out):
"""Probe PTP timestamping capabilities per physical interface via ethtool --json -T.
Only physical interfaces (those with a 'device' sysfs symlink) are probed;
virtual interfaces such as bridges, VLANs, and tun/tap devices are skipped.
Results are stored under out["interfaces"][<ifname>]["ptp-capabilities"].
"""
net_base = "/sys/class/net"
if not os.path.exists(net_base):
return
ifaces = {}
for ifname in sorted(os.listdir(net_base)):
if ifname == "lo":
continue
# Physical interfaces have a 'device' symlink; virtual ones do not.
if not os.path.exists(os.path.join(net_base, ifname, "device")):
continue
try:
result = subprocess.run(
["ethtool", "--json", "-T", ifname],
capture_output=True, text=True, timeout=5
)
if result.returncode != 0:
continue
data = json.loads(result.stdout)[0]
except Exception:
continue
caps = {
"capabilities": data.get("capabilities", []),
"tx-types": data.get("tx-types", []),
"rx-filters": data.get("rx-filters", []),
}
# phc-index is -1 when no PHC is present; omit in that case.
phc = data.get("phc-index", -1)
if phc >= 0:
caps["phc-index"] = phc
# hwtstamp provider fields are present only on newer kernels/hardware.
if (idx := data.get("hwtstamp-provider-index")) is not None:
caps["hwtstamp-provider-index"] = idx
if (qual := data.get("hwtstamp-provider-qualifier")) is not None:
caps["hwtstamp-provider-qualifier"] = qual
ifaces[ifname] = {"ptp-capabilities": caps}
if ifaces:
out.setdefault("interfaces", {}).update(ifaces)
def main():
out = {
"vendor": None,
@@ -593,6 +646,7 @@ def main():
return err
probe_wifi_radios(out)
probe_ptp_capabilities(out)
if not out["factory-password-hash"]:
sys.stdout.write("\n\n\033[31mCRITICAL BOOTSTRAP ERROR\n" +
+4 -3
View File
@@ -652,7 +652,9 @@ wrap()
if [ "$cmd" = "stop" ]; then
# The setup phase may run forever in the background trying to fetch
# the image. It saves its PID in /run/containers/${name}.pid
# the image. It saves its PID in /run/containers/${name}.pid. Kill
# any in-flight setup, then fall through to podman stop -- a stale
# pidfile is not proof the container isn't running.
if [ -f "$pidfile" ]; then
pid=$(cat "$pidfile")
@@ -663,10 +665,9 @@ wrap()
fi
rm -f "$pidfile"
return 0
fi
# Only the 'podman stop' command takes -i and --timeout
# Only the 'podman stop' command takes -i (ignore missing) and --timeout
args="-i --timeout $timeout"
fi
+1 -1
View File
@@ -33,7 +33,7 @@ for tgt in "${boot_targets}"; do
setexpr ixmenu_n ${ixmenu_n} + 1
if load ${devtype} ${devnum}:${auxpart} ${loadaddr} /uboot.env; then
env import -b ${loadaddr} ${filesize} BOOT_ORDER DEBUG ethact BOARD_VARIANT
env import -c ${loadaddr} ${filesize} BOOT_ORDER DEBUG ethact BOARD_VARIANT
run ixvariant
fi
+3 -1
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.23"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.33"
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
@@ -75,6 +75,7 @@ BR2_PACKAGE_IPERF3=y
BR2_PACKAGE_IPROUTE2=y
BR2_PACKAGE_IPTABLES_NFTABLES=y
BR2_PACKAGE_IPUTILS=y
BR2_PACKAGE_LINUXPTP=y
BR2_PACKAGE_LLDPD=y
BR2_PACKAGE_MSTPD=y
BR2_PACKAGE_MTR=y
@@ -133,6 +134,7 @@ BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
BR2_PACKAGE_ALDER_ALDER=y
BR2_PACKAGE_ACER_CONNECT_VERO_W6M=y
BR2_PACKAGE_BANANAPI_BPI_R3=y
BR2_PACKAGE_BANANAPI_BPI_R4=y
BR2_PACKAGE_BANANAPI_BPI_R64=y
+2 -1
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.23"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.33"
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
@@ -68,6 +68,7 @@ BR2_PACKAGE_FRR=y
# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set
BR2_PACKAGE_IPROUTE2=y
BR2_PACKAGE_IPUTILS=y
BR2_PACKAGE_LINUXPTP=y
BR2_PACKAGE_LLDPD=y
BR2_PACKAGE_MSTPD=y
BR2_PACKAGE_NETCALC=y
+2 -1
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.23"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.33"
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
@@ -74,6 +74,7 @@ BR2_PACKAGE_FRR=y
BR2_PACKAGE_IPERF3=y
BR2_PACKAGE_IPROUTE2=y
BR2_PACKAGE_IPUTILS=y
BR2_PACKAGE_LINUXPTP=y
BR2_PACKAGE_LLDPD=y
BR2_PACKAGE_MSTPD=y
BR2_PACKAGE_MTR=y
+2 -1
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.23"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.33"
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
@@ -70,6 +70,7 @@ BR2_PACKAGE_FRR=y
# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set
BR2_PACKAGE_IPROUTE2=y
BR2_PACKAGE_IPUTILS=y
BR2_PACKAGE_LINUXPTP=y
BR2_PACKAGE_LLDPD=y
BR2_PACKAGE_MSTPD=y
BR2_PACKAGE_NETCALC=y
+1
View File
@@ -85,6 +85,7 @@ BR2_PACKAGE_IPERF3=y
BR2_PACKAGE_IPROUTE2=y
BR2_PACKAGE_IPTABLES_NFTABLES=y
BR2_PACKAGE_IPUTILS=y
BR2_PACKAGE_LINUXPTP=y
BR2_PACKAGE_LLDPD=y
BR2_PACKAGE_MSTPD=y
BR2_PACKAGE_MTR=y
+1
View File
@@ -0,0 +1 @@
BR2_TARGET_ENABLE_ROOT_LOGIN=y
+4
View File
@@ -0,0 +1,4 @@
BR2_TARGET_ROOTFS_EXT2=y
BR2_TARGET_ROOTFS_EXT2_4=y
BR2_TARGET_ROOTFS_EXT2_SIZE="512M"
IMAGE_EXT4_RAUC=y
+2 -1
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.23"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.33"
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
@@ -74,6 +74,7 @@ BR2_PACKAGE_IPERF3=y
BR2_PACKAGE_IPROUTE2=y
BR2_PACKAGE_IPTABLES_NFTABLES=y
BR2_PACKAGE_IPUTILS=y
BR2_PACKAGE_LINUXPTP=y
BR2_PACKAGE_LLDPD=y
BR2_PACKAGE_MSTPD=y
BR2_PACKAGE_MTR=y
+2 -1
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.23"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.33"
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
@@ -67,6 +67,7 @@ BR2_PACKAGE_FRR=y
# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set
BR2_PACKAGE_IPROUTE2=y
BR2_PACKAGE_IPUTILS=y
BR2_PACKAGE_LINUXPTP=y
BR2_PACKAGE_LLDPD=y
BR2_PACKAGE_MSTPD=y
BR2_PACKAGE_NETCALC=y
+104 -8
View File
@@ -3,21 +3,115 @@ Change Log
All notable changes to the project are documented in this file.
[v26.04.0][UNRELEASED] -
[v26.05.0][] - 2026-05-29
-------------------------
### Changes
- Upgrade Linux kernel to 6.18.23 (LTS)
- Add support for [Banana Pi BPI-R4][BPI-R4], quad-core Cortex-A73 router with
4x 2.5 GbE switching, dual 10 GbE SFP+. Variants BPI-R4-2g5 and BPI-R4P have
one SFP+ replaced by a 2.5 GbE RJ45, with optional PoE on the R4P
- Upgrade Linux kernel to 6.18.33 (LTS)
- Upgrade Buildroot to 2025.02.14 (LTS)
- Upgrade FRR to 10.5.4
- Add support for [Acer Connect Vero W6m][AcerConnectVero], a low-cost COTS
home router, based on the same hardware as [Banana Pi BPI-R3][BPI-R3], but
with a Wi-Fi 6E (6 GHz band) chip.
- Add configurable channel-width in Wi-Fi configuration.
- Upgrade `ieee802-ethernet-interface` YANG model to revision 2025-09-10 (IEEE
Std 802.3.2-2025), adding the standard `phy-type` and `pmd-type` operational
leaves. Speed is now exposed via `ietf-interfaces:speed` (bps, RFC 8343);
the now obsolete `eth:speed` is no longer returned
- Rework `show interface` summary output as layered protocol rows. When a
port has link, a physical-medium row (e.g. `1000baseT`, `10GbaseLR`) appears
above the `ethernet` row. VLAN, GRE, VXLAN and WiFi interfaces likewise get
one row per protocol layer, with type-specific data on each (`vid:`,
`remote:`, `vni:`, `station ssid:`, etc.), issue #530
- Add support for configurable auto-negotiation for Ethernet ports. A new
`advertised-pmd-types` leaf-list replaces the fixed speed idiom for pinned
link modes, issue #805. See the [Ethernet Interfaces][ethernet] section in
the User Guide for details. Existing configurations using fixed speed are
migrated automatically on upgrade
- Add support for configurable MDI/MDI-X pinout on Ethernet ports. Needed on
some PHYs where Auto-MDIX stops working once auto-negotiation is disabled
- New operational `supported-pmd-types` leaf-list on each Ethernet interface,
exposing the set of PMD types currently supported
- New CLI command `show operational`, and optional XPath filtering for this
and any of the other datastores, using `[path /path/to/subtree]`
- CLI `show` commands now surface human-friendly error messages instead of a
raw Python exceptions, e.g., `Interface "w" not found`
### Fixes
- N/A
- Fix #1493: container with a physical interface not properly removed when
switching to a configuration without containers
- Fix #1506: add documentation on how to configure VLAN interfaces, including
stacked (Q-in-Q) VLAN interfaces, in a dedicated `vlan.md`
- Handle unclean daemon exits better, e.g., `dbus-daemon` crashing and leaving
a stale pidfile behind, causing it to refuse to be restarted
- Fix occasional blank or garbled `[ OK ]` lines at startup
- Disallow multicast MAC addresses in custom MAC address configuration
- Fix broken Wi-Fi 6 GHz band configuration.
- Fix operational read of `/containers` failing and thereby aborting all
operational get-data, including RESTCONF/NETCONF reads — for containers
whose command contains shell metacharacters, e.g. `sh -c "... && ..."`
- WireGuard interfaces are now regenerated when a referenced keystore key
changes: the asymmetric `private-key`, and the symmetric `preshared-key` at
both peer-group and per-peer level
- Fix crash in operational data when a bridge has VLAN ranges configured: the
kernel may report ranges (e.g. `vlan 1 vlanEnd 3`) from `bridge vlan global
show`, which were not expanded, so `show interface` and other operational
reads failed. Ranges are now expanded and listed correctly
[ethernet]: ethernet.md#restricting-advertised-link-modes
[BPI-R3]: https://docs.banana-pi.org/en/BPI-R3/BananaPi_BPI-R3
[AcerConnectVero]: ../board/aarch64/acer-connect-vero-w6m/
[v26.04.0][] - 2026-04-30
-------------------------
### Changes
- Upgrade Linux kernel to 6.18.25 (LTS)
- Upgrade Buildroot to 2025.02.13 (LTS)
- Add support for per-bridge multicast router port in operational, issue #395
- Add support for static ARP (IPv4) and neighbor cache (IPv6) entries per
interface, issue #819. Static entries are installed as permanent kernel
neighbor table entries that are never evicted by normal ARP/NDP aging
- Add support for PTP/gPTP (IEEE 1588-2019 / 802.1AS) clock synchronization.
Supported clock types: Ordinary Clock, Boundary Clock, and Transparent Clock.
See the User Guide for configuration details
- Add support for [Banana Pi BPI-R4][BPI-R4], quad-core Cortex-A73 router with
4x 2.5 GbE switching, dual 10 GbE SFP+. Variants BPI-R4-2g5 and BPI-R4P have
one SFP+ replaced by a 2.5 GbE RJ45, with optional PoE on the R4P
- Update [Marvell ESPRESSObin][ESPRESSObin] board support. Allow booting with
stock U-Boot, which only supports ext4 rootfs partitions; to use, apply the
`ext4` developer snippet before building (`make apply-ext4 all`)
- Fix onboard WiFi support on the Banana Pi BPi-R64
### Fixes
- Fix #520: warn in syslog if multicast flooding is disabled
- Fix #769: document dummy interfaces in user guide
- Fix #790: document static multicast filters in user guide
- Fix #1439: changing hostname does not regenerate DHCP client conf until restart
- Fix #1458: `show ntp tracking` displaying a truncated Reference ID, e.g.,
`92.2` instead of `92.246.137.39`
- Fix #1466: `show container` showing no output for containers whose command
line includes environment variables
- Fix issue with IGMP queries sent with all-zeroes source MAC address
- Fix missing IGMP query startup burst when assuming IGMP querier role, as
defined in RFC3376 §8.6/§8.7
- Fix Raspberry Pi 4 and Pi 400 display instability after soft reboot.
Previously the touchscreen/DSI display required a full power cycle to
reinitialise correctly; it now works reliably after `reboot`. Please note,
you need a fairly up-to-date EEPROM version as well
- Fix [BPI-R4][] board README showing inverted DIP switch values for eMMC and
SPI NAND boot modes, which would prevent the board from booting correctly
- Fix [SAMA7G54][] U-Boot build system selection that caused build failures
- Fix [BPI-R3][] PCIe devices failing to initialize on boot due to a missing
clock definition in the device tree
[BPI-R4]: https://docs.banana-pi.org/en/BPI-R4/BananaPi_BPI-R4
[ESPRESSObin]: https://espressobin.net/
[SAMA7G54]: https://www.microchip.com/en-us/development-tool/ev21h18a
[v26.03.0][] - 2026-03-31
-------------------------
@@ -118,7 +212,7 @@ All notable changes to the project are documented in this file.
- Fix CLI `copy` command problem to copy to scp/sftp destinations
[BPI-R3-MINI]: https://wiki.banana-pi.org/Banana_Pi_BPI-R3_Mini
[BPI-R3-MINI]: https://docs.banana-pi.org/en/BPI-R3_Mini/BananaPi_BPI-R3_Mini
[SAMA7G54-EK]: https://www.microchip.com/en-us/development-tool/ev21h18a
[v26.01.0][] - 2026-02-03
@@ -2041,7 +2135,9 @@ Supported YANG models in addition to those used by sysrepo and netopeer:
- N/A
[buildroot]: https://buildroot.org/
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v26.03.0...HEAD
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v26.05.0...HEAD
[v26.05.0]: https://github.com/kernelkit/infix/compare/v26.04.0...v26.05.0
[v26.04.0]: https://github.com/kernelkit/infix/compare/v26.03.0...v26.04.0
[v26.03.0]: https://github.com/kernelkit/infix/compare/v26.02.0...v26.03.0
[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
+44 -2
View File
@@ -73,8 +73,8 @@ admin@example:/config/interface/br0/> <b>set bridge vlans vlan 20 tagged br0</b>
</code></pre>
To route or to manage via a VLAN, a VLAN interface needs to be created
on top of the bridge, see section [VLAN Interfaces](ethernet.md#vlan-interfaces)
for more on this topic.
on top of the bridge, see section [VLAN Interfaces](vlan.md) for more
on this topic.
> [!NOTE]
> In some use-cases only a single management VLAN on the bridge is used.
@@ -183,6 +183,48 @@ In this setup we have a lot more going on. Multiple multicast router
ports have been detected, and behind the scenes someone has also added
an IGMP/MLD fast-leave port.
### Static Multicast Filters
When IGMP/MLD snooping is in use, traffic for an unregistered group is
flooded to all ports until a receiver joins. For MAC multicast groups,
or for groups where snooping cannot learn membership automatically, you
can add static entries to the MDB that immediately restrict forwarding
to a given set of ports.
> [!NOTE]
> Snooping must be enabled on the bridge (or per VLAN) before static
> multicast filters can be configured.
On a plain (non-VLAN) bridge, add a static IPv4 or MAC multicast filter
like this:
<pre class="cli"><code>admin@example:/> <b>configure</b>
admin@example:/config/> <b>edit interface br0</b>
admin@example:/config/interface/br0/> <b>set bridge multicast-filters multicast-filter 224.1.1.1 ports e2</b>
admin@example:/config/interface/br0/> <b>set bridge multicast-filters multicast-filter 224.1.1.1 ports e3</b>
admin@example:/config/interface/br0/> <b>set bridge multicast-filters multicast-filter 01:00:5e:01:01:01 ports e2</b>
admin@example:/config/interface/br0/> <b>leave</b>
admin@example:/> <b>copy running-config startup-config</b>
</code></pre>
Each `ports` entry for the same group adds one port to the filter.
Receivers on all other ports will not see traffic for that group.
On a VLAN-filtering bridge the filter is scoped per VLAN:
<pre class="cli"><code>admin@example:/config/interface/br1/> <b>set bridge vlans vlan 10 multicast-filters multicast-filter 224.2.2.2 ports e5</b>
admin@example:/config/interface/br1/> <b>set bridge vlans vlan 10 multicast-filters multicast-filter 224.2.2.2 ports e6</b>
</code></pre>
To verify the MDB — both statically configured and dynamically learned
entries — use:
<pre class="cli"><code>admin@example:/> <b>show bridge mdb</b>
<span class="header">BRIDGE VID GROUP PORTS </span>
br0 224.1.1.1 e2, e3
br0 01:00:5e:01:01:01 e2
</code></pre>
### Terminology & Abbreviations
- **IGMP**: Internet Group Membership Protocol, multicast subscription
+1 -1
View File
@@ -164,7 +164,7 @@ interfaces {
}
}
admin@host-12-34-56:/config/interface/eth0/> leave
admin@host-12-34-56:/> show interfaces
admin@host-12-34-56:/> show interface
INTERFACE PROTOCOL STATE DATA
lo loopback UNKNOWN 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
+35 -5
View File
@@ -7,12 +7,12 @@ account, which is created based on credentials found in the VPD area --
for Qemu devices this is emulated using `qemu_fw_cfg`.
For developers this can be quite frustrating to be blocked from logging
in to debug the system. So we recommend enabling the `root` account in
the Buildroot `make menuconfig` system.
in to debug the system. The quickest way to enable root login is to
apply the `dev` configuration snippet:
make menuconfig
-> System configuration
-> [*]Enable root login with password
make apply-dev
See [Configuration Snippets](#configuration-snippets) for more details.
> [!IMPORTANT]
> Please see the [Contributing](#contributing) section, below, for
@@ -166,6 +166,36 @@ on Buildroot to finalize the target filesystem and generate the images.
The final `run` argument is explained below.
### Configuration Snippets
Infix ships a set of Kconfig fragments in `configs/snippets/` that can
be merged into your active `.config` on demand. This avoids polluting
defconfigs with settings that are only useful during development.
To see what snippets are available:
make list-snippets
To apply a single snippet to the current output directory:
make apply-dev # enable root login
make apply-ext4 # build an ext4 rootfs (needed for boards
# whose bootloader lacks squashfs support,
# e.g. Marvell ESPRESSObin)
The `apply-*` targets require an existing `.config` (i.e. you must have
already run a `make <board>_defconfig`). The snippet is merged using
Buildroot's `merge_config.sh`, so it behaves like `make menuconfig`:
unrelated settings are preserved, conflicting ones are overridden.
To apply **all** snippets at once and then build:
make dev
This is the recommended one-shot command for setting up a development
build from a freshly selected defconfig.
### YANG Model
When making changes to the `confd` and `statd` services, you will often
+4 -4
View File
@@ -109,11 +109,11 @@ When configuring, e.g., `dns-server`, or `router` options with the value
`auto`, the system uses the IP address from the interface matching the
subnet. For example:
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
<pre class="cli"><code>admin@example:/> <b>show interface</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
ipv4 192.168.1.1/24 (static)
eth1 ethernet UP 02:00:00:00:00:01
eth1 ethernet UP 02:00:00:00:00:01
ipv4 192.168.2.1/24 (static)
admin@example:/config/dhcp-server/subnet/192.168.1.0/24/> <b>edit option dns-server</b>
+184 -120
View File
@@ -1,52 +1,8 @@
# Ethernet Interfaces
This document covers VLAN interfaces, physical Ethernet interfaces,
and virtual Ethernet (VETH) pairs.
## VLAN Interfaces
Creating a VLAN can be done in many ways. This section assumes VLAN
interfaces created atop another Linux interface. E.g., the VLAN
interfaces created on top of the Ethernet interface or bridge in the
picture below.
![VLAN interface on top of Ethernet or Bridge interfaces](img/interface-vlan-variants.svg)
A VLAN interface is basically a filtering abstraction. When you run
`tcpdump` on a VLAN interface you will only see the frames matching the
VLAN ID of the interface, compared to *all* the VLAN IDs if you run
`tcpdump` on the lower-layer interface.
<pre class="cli"><code>admin@example:/> <b>configure</b>
admin@example:/config/> <b>edit interface eth0.20</b>
admin@example:/config/interface/eth0.20/> <b>show</b>
type vlan;
vlan {
tag-type c-vlan;
id 20;
lower-layer-if eth0;
}
admin@example:/config/interface/eth0.20/> <b>leave</b>
</code></pre>
The example below assumes bridge br0 is already created, see [VLAN
Filtering Bridge](bridging.md#vlan-filtering-bridge).
<pre class="cli"><code>admin@example:/> <b>configure</b>
admin@example:/config/> <b>edit interface vlan10</b>
admin@example:/config/interface/vlan10/> <b>set vlan id 10</b>
admin@example:/config/interface/vlan10/> <b>set vlan lower-layer-if br0</b>
admin@example:/config/interface/vlan10/> <b>leave</b>
</code></pre>
As conventions, a VLAN interface for VID 20 on top of an Ethernet
interface *eth0* is named *eth0.20*, and a VLAN interface for VID 10 on
top of a bridge interface *br0* is named *vlan10*.
> [!NOTE]
> If you name your VLAN interface `foo0.N` or `vlanN`, where `N` is a
> number, the CLI infers the interface type automatically.
This document covers physical Ethernet interfaces and virtual Ethernet
(VETH) pairs. For VLAN interfaces stacked on top of an Ethernet port
or bridge, see [VLAN Interfaces](vlan.md).
## Physical Ethernet Interfaces
@@ -56,111 +12,219 @@ top of a bridge interface *br0* is named *vlan10*.
Physical Ethernet interfaces provide low-level settings for speed/duplex as
well as packet status and [statistics](#ethernet-statistics).
By default, Ethernet interfaces defaults to auto-negotiating
speed/duplex modes, advertising all speed and duplex modes available.
In the example below, the switch would by default auto-negotiate speed
1 Gbit/s on port eth1 and 100 Mbit/s on port eth4, as those are the
highest speeds supported by H1 and H2 respectively.
By default, Ethernet interfaces defaults to auto-negotiating speed/duplex
modes, advertising all speed and duplex modes available. In the example
below, the switch would by default auto-negotiate speed 1 Gbps on port eth1
and 100 Mbps on port eth4, as those are the highest speeds supported by H1 and
H2 respectively.
![4-port Gbit/s switch connected to Gbit and Fast Ethernet Hosts](img/ethernet-autoneg.svg)
The speed and duplex status for the links can be listed as shown
below, assuming the link operational status is 'up'.
A quick at-a-glance view of the physical link is available in the summary
listing. When a port is up, a physical-layer row appears above the ethernet
row, naming the IEEE PMD type (e.g. `1000baseT`, `10GbaseLR`) in the PROTOCOL
column and the negotiated duplex in DATA. When the link is down the row is
omitted and the interface name falls onto the ethernet row.
<pre class="cli"><code>admin@example:/> <b>show interface</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth1 1000baseT UP duplex: full
ethernet 00:53:00:06:11:01
eth2 1000baseT UP duplex: full
ethernet 00:53:00:06:11:02
eth3 ethernet DOWN 00:53:00:06:11:03
eth4 100baseTX UP duplex: full
ethernet 00:53:00:06:11:04
...
</code></pre>
The detail view spells everything out, including auto-negotiation
state and the speed in Mbit/s.
<pre class="cli"><code>admin@example:/> <b>show interface eth1</b>
name : eth1
index : 2
mtu : 1500
operational status : up
auto-negotiation : on
duplex : full
speed : 1000
physical address : 00:53:00:06:11:01
ipv4 addresses :
ipv6 addresses :
in-octets : 75581
out-octets : 43130
name : eth1
index : 2
mtu : 1500
operational status : up
link mode : 1000baseT
auto-negotiation : on
duplex : full
speed : 1000
physical address : 00:53:00:06:11:01
ipv4 addresses :
ipv6 addresses :
in-octets : 75581
out-octets : 43130
...
admin@example:/> <b>show interface eth4</b>
name : eth4
index : 5
mtu : 1500
operational status : up
auto-negotiation : on
duplex : full
speed : 100
physical address : 00:53:00:06:11:04
ipv4 addresses :
ipv6 addresses :
in-octets : 75439
out-octets : 550704
name : eth4
index : 5
mtu : 1500
operational status : up
link mode : 100baseTX
auto-negotiation : on
duplex : full
speed : 100
physical address : 00:53:00:06:11:04
ipv4 addresses :
ipv6 addresses :
in-octets : 75439
out-octets : 550704
...
admin@example:/>
</code></pre>
### Configuring fixed speed and duplex
### Restricting advertised link modes
Auto-negotiation of speed/duplex mode is desired in almost all
use-cases, but it is possible to disable auto-negotiation and specify
a fixed speed and duplex mode.
Auto-negotiation is the right default for almost all links, but sometimes a
port has to come up at a fixed speed, usually when talking to old hardware
that won't auto-negotiate or does it badly. IEEE Std 802.3.2-2025 dropped
the old "turn off auto-negotiation, then set a fixed speed and duplex"
approach. Instead you restrict the set of PMD types the port may advertise:
list a single PMD and the link pins to that mode against any peer that
supports it.
> [!IMPORTANT]
> When setting a fixed speed and duplex mode, ensure both sides of the
> link have matching configuration. If speed does not match, the link
> will not come up. If duplex mode does not match, the result is
> reported collisions and/or bad throughput.
> [!NOTE]
> Earlier Infix releases needed `enable false` plus explicit `speed` and
> `duplex` leaves. IEEE Std 802.3.2-2025 retired the `eth:speed` leaf, so
> the speed now comes from the `advertised-pmd-types` entry instead.
> Existing `startup-config.cfg` files are migrated automatically on upgrade.
The example below configures port eth3 to fixed speed 100 Mbit/s
half-duplex mode.
Each entry in `auto-negotiation/advertised-pmd-types` is an IEEE PMD-type
identity (`ieee802-ethernet-phy-type:pmd-type-*`). The separate `duplex`
leaf controls half vs full duplex.
The example below pins port `eth3` to 100 Mbit/s half-duplex.
<pre class="cli"><code>admin@example:/> <b>configure</b>
admin@example:/config/> <b>edit interface eth3 ethernet</b>
admin@example:/config/interface/eth3/ethernet/> <b>set speed 0.1</b>
admin@example:/config/interface/eth3/ethernet/> <b>set auto-negotiation advertised-pmd-types pmd-type-100BASE-TX</b>
admin@example:/config/interface/eth3/ethernet/> <b>set duplex half</b>
admin@example:/config/interface/eth3/ethernet/> <b>set auto-negotiation enable false</b>
admin@example:/config/interface/eth3/ethernet/> <b>show</b>
auto-negotiation {
enable false;
advertised-pmd-types [ ieee802-ethernet-phy-type:pmd-type-100BASE-TX ];
}
duplex half;
speed 0.1;
admin@example:/config/interface/eth3/ethernet/> <b>leave</b>
admin@example:/>
</code></pre>
Speed metric is in Gbit/s. Auto-negotiation needs to be disabled in
order for fixed speed/duplex to apply. Only speeds `0.1`(100 Mbit/s)
and `0.01` (10 Mbit/s) can be specified. 1 Gbit/s and higher speeds
require auto-negotiation to be enabled.
List several PMDs to advertise all of them; auto-negotiation then settles
on the highest mode both ends support.
> [!IMPORTANT]
> When pinning a link mode, make sure both ends share at least one common
> (PMD, duplex) combination, otherwise the link will not come up.
#### Duplex and advertised modes
A PMD type like `10BASE-T` or `100BASE-TX` says nothing about duplex on its
own, but the kernel tracks half and full duplex as separate link modes.
Infix advertises both variants of every PMD you list, then narrows to one
duplex when the `duplex` leaf is set:
| `advertised-pmd-types` | `duplex` | Resulting advertised modes |
|----------------------------|----------|------------------------------------------|
| `[10BASE-T]` | _unset_ | `10baseT/Half` + `10baseT/Full` |
| `[10BASE-T]` | `full` | `10baseT/Full` |
| `[10BASE-T]` | `half` | `10baseT/Half` |
| `[10BASE-T, 100BASE-TX]` | _unset_ | all four half/full combinations |
| `[10BASE-T, 100BASE-TX]` | `full` | `10baseT/Full` + `100baseT/Full` |
| _unset_ | _unset_ | every mode the PHY supports (default) |
So `duplex` filters the PMDs you listed. PMDs with no half-duplex variant
(everything above 1 Gbps) only ever advertise full.
#### Disabling auto-negotiation
The method above keeps auto-negotiation on and only limits what it
advertises, so the peer still negotiates as usual. That doesn't help with
gear that won't negotiate at all, like some old switches or a back-to-back
copper link. For those, set `auto-negotiation/enable false` together with a
single `advertised-pmd-types` entry to force a fixed speed and duplex with
negotiation off:
<pre class="cli"><code>admin@example:/config/interface/eth3/ethernet/> <b>set auto-negotiation enable false</b>
admin@example:/config/interface/eth3/ethernet/> <b>set auto-negotiation advertised-pmd-types pmd-type-100BASE-TX</b>
admin@example:/config/interface/eth3/ethernet/> <b>set duplex full</b>
</code></pre>
With `enable false` you must list exactly one PMD: it sets the speed, and
the `duplex` leaf sets half or full. Leave `duplex` out and Infix uses
whatever the PMD supports, normally full.
Auto-MDIX usually rides along with auto-negotiation, so turning negotiation
off can leave both ends picking the same MDI/MDI-X pinout. The link then
comes up electrically but carries no traffic. When that happens, force
opposite pinouts with the `mdi-x` leaf — set one end true (MDI-X) and the
other false (MDI):
<pre class="cli"><code>admin@example:/config/interface/eth3/ethernet/> <b>set mdi-x false</b>
</code></pre>
Leaving `mdi-x` unset keeps Auto-MDIX in charge, which is correct whenever
auto-negotiation is on.
> [!NOTE]
> Whether `enable false` reaches the external PHY depends on the driver.
> Direct-attach NICs handle it directly. Switch user ports go through the
> switch driver, and some accept the request at the MAC but leave the PHY
> auto-negotiating: the kernel reports the configured speed while the wire
> runs at whatever was negotiated, and traffic stalls. If that happens,
> read the PHY's BMCR register (e.g. with `mdio` from `mdiotools`) to see
> what the PHY is actually doing.
The detail view exposes a `supported` block (operational state,
backed by the `supported-pmd-types` leaf-list) listing the PMD types
the kernel currently believes the interface can operate at. For
SFP/SFP+ cages this set reflects the inserted module: plug in a 10G
LR optic and `supported` will narrow to `10GbaseLR` only. Combined
with the operational `link mode` row above it, this makes it trivial
to confirm what an unknown transceiver actually is — no `ethtool -m`
round-trip needed.
<pre class="cli"><code>admin@example:/> <b>show interface eth13</b>
name : eth13
type : ethernet
operational status : up
link mode : 10GbaseLR
auto-negotiation : off
supported : 10GbaseLR
duplex : full
speed : 10000
...
</code></pre>
### Ethernet statistics
Ethernet packet statistics[^1] can be listed as shown below.
<pre class="cli"><code>admin@example:/> <b>show interface eth1</b>
name : eth1
index : 2
mtu : 1500
operational status : up
auto-negotiation : on
duplex : full
speed : 1000
physical address : 00:53:00:06:11:0a
ipv4 addresses :
ipv6 addresses :
in-octets : 75581
out-octets : 43130
eth-in-frames : 434
eth-in-multicast-frames : 296
eth-in-broadcast-frames : 138
eth-in-error-fcs-frames : 0
eth-in-error-oversize-frames : 0
eth-out-frames : 310
eth-out-multicast-frames : 310
eth-out-broadcast-frames : 0
eth-out-good-octets : 76821
eth-in-good-octets : 60598
name : eth1
index : 2
mtu : 1500
operational status : up
link mode : 1000baseT
auto-negotiation : on
duplex : full
speed : 1000
physical address : 00:53:00:06:11:0a
ipv4 addresses :
ipv6 addresses :
in-octets : 75581
out-octets : 43130
───────────────────
<b>Ethernet Statistics</b>
in-frames : 434
in-multicast-frames : 296
in-broadcast-frames : 138
in-error-fcs-frames : 0
in-error-oversize-frames : 0
out-frames : 310
out-multicast-frames : 310
out-broadcast-frames : 0
out-good-octets : 76821
in-good-octets : 60598
admin@example:/>
</code></pre>
+87
View File
@@ -1,3 +1,90 @@
/* Chirpy-style typography (must precede all other rules).
* Source Sans Pro was renamed "Source Sans 3" on Google Fonts; it is the
* same typeface. Lato is used for headings, matching www.kernelkit.org. */
@import url('https://fonts.googleapis.com/css2?family=Lato:wght@400;700;900&family=Source+Sans+3:ital,wght@0,400;0,600;0,700;1,400&display=swap');
/* ---- Fonts ---------------------------------------------------------------
* theme.font is disabled in mkdocs.yml, so we set Material's font vars here.
* Body: Source Sans 3, code: system monospace (same stack Chirpy uses). */
:root {
--md-text-font: "Source Sans 3";
--md-code-font: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New";
}
body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* Lato for all headings and the masthead site title. */
.md-typeset h1,
.md-typeset h2,
.md-typeset h3,
.md-typeset h4,
.md-typeset h5,
.md-typeset h6,
.md-header__title,
.md-nav__title {
font-family: "Lato", "Microsoft Yahei", sans-serif;
}
/* ---- Light mode (Chirpy "default" palette) ------------------------------- */
[data-md-color-scheme="default"] {
--md-typeset-color: #34343c;
--md-typeset-a-color: #0056b2; /* Chirpy blue links */
--md-accent-fg-color: #0056b2; /* link hover / active TOC */
--md-code-bg-color: #f6f8fa;
--md-code-fg-color: #3a3a3a;
}
[data-md-color-scheme="default"] .md-typeset h1,
[data-md-color-scheme="default"] .md-typeset h2,
[data-md-color-scheme="default"] .md-typeset h3,
[data-md-color-scheme="default"] .md-typeset h4,
[data-md-color-scheme="default"] .md-typeset h5,
[data-md-color-scheme="default"] .md-typeset h6 {
color: #2a2a2a;
}
/* Subtle tinted sidebars (left nav + right TOC), as on the blog. */
[data-md-color-scheme="default"] .md-sidebar {
background-color: #f6f8fa;
}
/* ---- Dark mode (Chirpy "dark" palette over Material's slate) ------------- */
[data-md-color-scheme="slate"] {
--md-default-bg-color: rgb(27 27 30); /* neutral near-black */
--md-default-fg-color: rgb(207 208 209); /* UI text */
--md-default-fg-color--light: rgb(175 176 177);
--md-default-fg-color--lighter: rgb(175 176 177 / 45%);
--md-default-fg-color--lightest: rgb(175 176 177 / 18%);
--md-typeset-color: rgb(175 176 177); /* body text */
--md-code-bg-color: #151515;
--md-code-fg-color: #b0b0b0;
--md-typeset-a-color: rgb(138 180 248); /* Chirpy blue links */
--md-accent-fg-color: rgb(168 199 250); /* brighter blue on hover */
}
[data-md-color-scheme="slate"] .md-typeset h1,
[data-md-color-scheme="slate"] .md-typeset h2,
[data-md-color-scheme="slate"] .md-typeset h3,
[data-md-color-scheme="slate"] .md-typeset h4,
[data-md-color-scheme="slate"] .md-typeset h5,
[data-md-color-scheme="slate"] .md-typeset h6 {
color: #cccccc;
}
/* Sidebars slightly lighter than the main background, as on the blog. */
[data-md-color-scheme="slate"] .md-sidebar {
background-color: #1e1e1e;
}
/* Inline code reads as a faint highlight rather than a dark block. */
[data-md-color-scheme="slate"] .md-typeset :not(pre) > code {
background-color: rgb(255 255 255 / 6%);
}
/* ---- Existing project styling -------------------------------------------- */
.md-header__title {
font-size: 1.1rem;
line-height: 2.6rem;
+56 -7
View File
@@ -61,13 +61,19 @@ admin@example:/config/interface/eth0/> <b>leave</b>
The operational status can be inspected to see both administrative and
actual link state:
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
INTERFACE PROTOCOL STATE DATA
eth0 ethernet <b>DISABLED</b> 02:00:00:00:00:00
eth1 ethernet UP 02:00:00:00:00:01
<pre class="cli"><code>admin@example:/> <b>show interface</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet <b>DISABLED</b> 02:00:00:00:00:00
eth1 1000baseT UP duplex: full
ethernet 02:00:00:00:00:01
...
</code></pre>
The rows are layered bottom-up by protocol: a physical-medium row (only
emitted when the link is up) on top, then the ethernet row carrying the
bare MAC, then any ipv4/ipv6 sub-rows. See [Ethernet](ethernet.md) for the
full set of summary fields.
## Description
@@ -84,9 +90,9 @@ The description is visible in the operational datastore and in `show`
commands:
<pre class="cli"><code>admin@example:/> <b>show interface eth0</b>
name : eth0
description : Uplink to core switch
index : 2
name : eth0
description : Uplink to core switch
index : 2
...
</code></pre>
@@ -138,6 +144,49 @@ admin@example:/config/interface/veth0a/> <b>set custom-phys-address chassis offs
</code></pre>
## Dummy Interface
A dummy interface is a virtual interface that is always administratively
and operationally UP, regardless of any physical link state. It can
hold IP addresses just like any other interface.
The two most common uses are:
- **Stable OSPF router-ID**: OSPF picks its router-ID from an interface
address. If that interface goes down, adjacencies can flap. Binding
the router-ID to a /32 address on a dummy avoids this.
- **Stable management address**: A /32 on a dummy gives the device a
permanent identity on the network, reachable as long as at least one
uplink is up and the address is redistributed into the routing domain.
> [!TIP]
> WiFi interfaces also use dummies as placeholders when the radio
> hardware is not detected at boot (e.g., a USB dongle that was
> unplugged). See [WiFi](wifi.md) for details.
### Example: Stable OSPF Router-ID
Create a dummy interface with a /32 address and use it as the OSPF
router-ID so that the ID never changes when physical ports bounce:
<pre class="cli"><code>admin@example:/> <b>configure</b>
admin@example:/config/> <b>edit interface lo0</b>
admin@example:/config/interface/lo0/> <b>set type dummy</b>
admin@example:/config/interface/lo0/> <b>set ipv4 address 192.0.2.1 prefix-length 32</b>
admin@example:/config/interface/lo0/> <b>leave</b>
admin@example:/config/> <b>edit routing control-plane-protocol ospfv2 name default ospf</b>
admin@example:/config/routing/…/ospf/> <b>set explicit-router-id 192.0.2.1</b>
admin@example:/config/routing/…/ospf/> <b>leave</b>
admin@example:/> <b>copy running-config startup-config</b>
</code></pre>
To also make the address reachable by other routers, redistribute
connected routes (or add `lo0` as an OSPF interface):
<pre class="cli"><code>admin@example:/config/routing/…/ospf/> <b>set redistribute connected</b>
</code></pre>
[^1]: A YANG deviation was previously used to make it possible to set
`phys-address`, but this has been replaced with the more flexible
`custom-phys-address`.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

+99 -39
View File
@@ -117,11 +117,11 @@ will be ignored. For details on how to enable the NTP client, see the
![Switch example (eth0 and lo)](img/ip-address-example-switch.svg)
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
<pre class="cli"><code>admin@example:/> <b>show interface</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
ipv6 fe80::ff:fe00:0/64 (link-layer)
lo ethernet UP 00:00:00:00:00:00
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
admin@example:/>
@@ -153,13 +153,13 @@ admin@example:/config/interface/eth0/ipv4/> <b>diff</b>
+ }
+}
admin@example:/config/interface/eth0/ipv4/> <b>leave</b>
admin@example:/> <b>show interfaces</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
admin@example:/> <b>show interface</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
ipv4 169.254.1.3/16 (random)
ipv4 10.0.1.1/24 (static)
ipv6 fe80::ff:fe00:0/64 (link-layer)
lo ethernet UP 00:00:00:00:00:00
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
admin@example:/>
@@ -188,12 +188,12 @@ admin@example:/config/interface/eth0/ipv4/autoconf/> <b>leave</b>
admin@example:/config/> <b>edit interface eth0 ipv4</b>
admin@example:/config/interface/eth0/ipv4/> <b>set dhcp</b>
admin@example:/config/interface/eth0/ipv4/> <b>leave</b>
admin@example:/> <b>show interfaces</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
admin@example:/> <b>show interface</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
ipv4 10.1.2.100/24 (dhcp)
ipv6 fe80::ff:fe00:0/64 (link-layer)
lo ethernet UP 00:00:00:00:00:00
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
admin@example:/>
@@ -235,11 +235,11 @@ admin@example:/config/> <b>edit interface eth0 ipv6</b>
admin@example:/config/interface/eth0/ipv6/> <b>set dhcp</b>
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
admin@example:/> <b>show interface</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
ipv6 2001:db8::42/128 (dhcp)
ipv6 fe80::ff:fe00:0/64 (link-layer)
lo ethernet UP 00:00:00:00:00:00
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
admin@example:/>
@@ -291,10 +291,10 @@ on the interface.
admin@example:/config/> <b>edit interface eth0 ipv6</b>
admin@example:/config/interface/eth0/ipv6/> <b>set enabled false</b>
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
admin@example:/> <b>show interfaces</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
lo ethernet UP 00:00:00:00:00:00
admin@example:/> <b>show interface</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
admin@example:/>
@@ -308,12 +308,12 @@ admin@example:/>
admin@example:/config/> <b>edit interface eth0 ipv6</b>
admin@example:/config/interface/eth0/ipv6/> <b>set address 2001:db8::1 prefix-length 64</b>
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
admin@example:/> <b>show interfaces</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
admin@example:/> <b>show interface</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
ipv6 2001:db8::1/64 (static)
ipv6 fe80::ff:fe00:0/64 (link-layer)
lo ethernet UP 00:00:00:00:00:00
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
admin@example:/>
@@ -330,12 +330,12 @@ advertised by the router (here 2001:db8:0:1::0/64) and the interface
identifier. The resulting address is of type *link-layer*, as it is
formed based on the interface identifier ([ietf-ip.yang][2]).
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
<pre class="cli"><code>admin@example:/> <b>show interface</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
ipv6 2001:db8:0:1:0:ff:fe00:0/64 (link-layer)
ipv6 fe80::ff:fe00:0/64 (link-layer)
lo ethernet UP 00:00:00:00:00:00
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
admin@example:/>
@@ -348,11 +348,11 @@ below.
admin@example:/config/> <b>edit interface eth0 ipv6</b>
admin@example:/config/interface/eth0/ipv6/> <b>set autoconf create-global-addresses false</b>
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
admin@example:/> <b>show interfaces</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
admin@example:/> <b>show interface</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
ipv6 fe80::ff:fe00:0/64 (link-layer)
lo ethernet UP 00:00:00:00:00:00
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
admin@example:/>
@@ -366,12 +366,12 @@ admin@example:/>
By default, the auto-configured link-local and global IPv6 addresses
are formed from a link-identifier based on the MAC address.
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
<pre class="cli"><code>admin@example:/> <b>show interface</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
ipv6 2001:db8:0:1:0:ff:fe00:0/64 (link-layer)
ipv6 fe80::ff:fe00:0/64 (link-layer)
lo ethernet UP 00:00:00:00:00:00
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
admin@example:/>
@@ -385,12 +385,12 @@ possible to specify use of a random identifier ([ietf-ip.yang][2] and
admin@example:/config/> <b>edit interface eth0 ipv6</b>
admin@example:/config/interface/eth0/ipv6/> <b>set autoconf create-temporary-addresses true</b>
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
admin@example:/> <b>show interfaces</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
admin@example:/> <b>show interface</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0 ethernet UP 02:00:00:00:00:00
ipv6 2001:db8:0:1:b705:8374:638e:74a8/64 (random)
ipv6 fe80::ad3d:b274:885a:9ffb/64 (random)
lo ethernet UP 00:00:00:00:00:00
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
admin@example:/>
@@ -435,6 +435,66 @@ admin@example:/config/interface/eth0/> <b>leave</b>
admin@example:/>
</code></pre>
## ARP and Neighbor Cache
Static ARP entries (IPv4) and neighbor cache entries (IPv6) can be
configured per interface. The most common reasons to do so are:
- **Security** — prevent ARP/NDP spoofing by locking critical hosts
(e.g., a default gateway) to their known MAC addresses
- **Reliability** — ensure reachability of a host even when ARP/NDP
traffic is suppressed or filtered (e.g., across a strict firewall)
Dynamic entries are learned automatically by the kernel using ARP and
Neighbor Discovery Protocol (NDP), and are visible as read-only
operational state alongside the static ones.
### Static IPv4 ARP Entry
<pre class="cli"><code>admin@example:/> <b>configure</b>
admin@example:/config/> <b>edit interface eth0 ipv4</b>
admin@example:/config/interface/eth0/ipv4/> <b>set neighbor 192.168.1.100 link-layer-address 00:11:22:33:44:55</b>
admin@example:/config/interface/eth0/ipv4/> <b>diff</b>
+interfaces {
+ interface eth0 {
+ ipv4 {
+ neighbor 192.168.1.100 {
+ link-layer-address 00:11:22:33:44:55;
+ }
+ }
+ }
+}
admin@example:/config/interface/eth0/ipv4/> <b>leave</b>
admin@example:/>
</code></pre>
### Static IPv6 Neighbor Entry
<pre class="cli"><code>admin@example:/> <b>configure</b>
admin@example:/config/> <b>edit interface eth0 ipv6</b>
admin@example:/config/interface/eth0/ipv6/> <b>set neighbor 2001:db8::100 link-layer-address 00:11:22:33:44:55</b>
admin@example:/config/interface/eth0/ipv6/> <b>diff</b>
+interfaces {
+ interface eth0 {
+ ipv6 {
+ neighbor 2001:db8::100 {
+ link-layer-address 00:11:22:33:44:55;
+ }
+ }
+ }
+}
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
admin@example:/>
</code></pre>
The full neighbor table — including dynamically learned entries (origin:
*dynamic*) — is available as operational state via NETCONF or RESTCONF.
> [!NOTE]
> Static neighbor entries take effect immediately on `leave` (commit).
> They are installed as *permanent* entries in the kernel neighbor table,
> which means they are never evicted by the normal ARP/NDP aging process.
[1]: https://www.rfc-editor.org/rfc/rfc3442
[2]: https://www.rfc-editor.org/rfc/rfc8344
[3]: https://www.rfc-editor.org/rfc/rfc8981
+66 -66
View File
@@ -87,34 +87,34 @@ Like other interfaces, link aggregates are also available in the general
interfaces overview in the CLI admin-exec context. Here is the above
static mode aggregate:
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
<pre class="cli"><code>admin@example:/> <b>show interface</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
.
.
.
lag0 lag UP static: balance-xor, hash: layer2
│ ethernet UP 00:a0:85:00:02:00
├ eth7 lag ACTIVE
└ eth8 lag ACTIVE
lag0 lag UP static: balance-xor, hash: layer2
│ ethernet UP 00:a0:85:00:02:00
├ eth7 lag ACTIVE
└ eth8 lag ACTIVE
</code></pre>
Same aggregate, but in LACP mode:
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
<pre class="cli"><code>admin@example:/> <b>show interface</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
.
.
.
lag0 lag UP lacp: active, rate: fast (1s), hash: layer2
│ ethernet UP 00:a0:85:00:02:00
├ eth7 lag ACTIVE active, short_timeout, aggregating, in_sync, collecting, distributing
└ eth8 lag ACTIVE active, short_timeout, aggregating, in_sync, collecting, distributing
lag0 lag UP lacp: active, rate: fast (1s), hash: layer2
│ ethernet UP 00:a0:85:00:02:00
├ eth7 lag ACTIVE active, short_timeout, aggregating, in_sync, collecting, distributing
└ eth8 lag ACTIVE active, short_timeout, aggregating, in_sync, collecting, distributing
</code></pre>
@@ -124,45 +124,45 @@ In addition to basic status shown in the interface overview, detailed
LAG status can be inspected:
<pre class="cli"><code>admin@example:/> <b>show interface lag0</b>
name : lag0
index : 25
mtu : 1500
operational status : up
physical address : 00:a0:85:00:02:00
lag mode : static
lag type : balance-xor
lag hash : layer2
link debounce up : 0 msec
link debounce down : 0 msec
ipv4 addresses :
ipv6 addresses :
in-octets : 0
out-octets : 2142
name : lag0
index : 25
mtu : 1500
operational status : up
physical address : 00:a0:85:00:02:00
lag mode : static
lag type : balance-xor
lag hash : layer2
link debounce up : 0 msec
link debounce down : 0 msec
ipv4 addresses :
ipv6 addresses :
in-octets : 0
out-octets : 2142
</code></pre>
Same aggregate, but in LACP mode:
<pre class="cli"><code>admin@example:/> <b>show interface lag0</b>
name : lag0
index : 24
mtu : 1500
operational status : up
physical address : 00:a0:85:00:02:00
lag mode : lacp
lag hash : layer2
lacp mode : active
lacp rate : fast (1s)
lacp aggregate id : 1
name : lag0
index : 24
mtu : 1500
operational status : up
physical address : 00:a0:85:00:02:00
lag mode : lacp
lag hash : layer2
lacp mode : active
lacp rate : fast (1s)
lacp aggregate id : 1
lacp system priority: 65535
lacp actor key : 9
lacp partner key : 9
lacp partner mac : 00:a0:85:00:03:00
link debounce up : 0 msec
link debounce down : 0 msec
ipv4 addresses :
ipv6 addresses :
in-octets : 100892
out-octets : 111776
lacp actor key : 9
lacp partner key : 9
lacp partner mac : 00:a0:85:00:03:00
link debounce up : 0 msec
link debounce down : 0 msec
ipv4 addresses :
ipv6 addresses :
in-octets : 100892
out-octets : 111776
</code></pre>
Member ports provide additional status information:
@@ -184,21 +184,21 @@ Member ports provide additional status information:
Example member port status:
<pre class="cli"><code>admin@example:/> <b>show interface eth7</b>
name : eth7
index : 8
mtu : 1500
operational status : up
physical address : 00:a0:85:00:02:00
lag member : lag0
lag member state : active
lacp aggregate id : 1
lacp actor state : active, short_timeout, aggregating, in_sync, collecting, distributing
lacp partner state : active, short_timeout, aggregating, in_sync, collecting, distributing
link failure count : 0
ipv4 addresses :
ipv6 addresses :
in-octets : 473244
out-octets : 499037
name : eth7
index : 8
mtu : 1500
operational status : up
physical address : 00:a0:85:00:02:00
lag member : lag0
lag member state : active
lacp aggregate id : 1
lacp actor state : active, short_timeout, aggregating, in_sync, collecting, distributing
lacp partner state : active, short_timeout, aggregating, in_sync, collecting, distributing
link failure count : 0
ipv4 addresses :
ipv6 addresses :
in-octets : 473244
out-octets : 499037
</code></pre>
+5 -5
View File
@@ -109,13 +109,13 @@ CLI can be entered from shell in the same way as for SSH.
See the 'help' command for an introduction to the system
admin@example:/> <b>show interfaces</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
lo ethernet UP 00:00:00:00:00:00
admin@example:/> <b>show interface</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
e1 ethernet LOWER-DOWN 00:53:00:06:03:01
e2 ethernet LOWER-DOWN 00:53:00:06:03:02
e1 ethernet LOWER-DOWN 00:53:00:06:03:01
e2 ethernet LOWER-DOWN 00:53:00:06:03:02
...
admin@example:/>
</code></pre>
+1 -1
View File
@@ -47,7 +47,7 @@ other traffic would be bridged as usual.
|----------|----------------------------|--------------------------------------------------------------|
| [bridge](bridging.md) | infix-if-bridge | SW implementation of an IEEE 802.1Q bridge |
| [ip](ip.md) | ietf-ip, infix-ip | IP address to the subordinate interface |
| [vlan](ethernet.md#vlan-interfaces) | infix-if-vlan | Capture all traffic belonging to a specific 802.1Q VID |
| [vlan](vlan.md) | infix-if-vlan | Capture all traffic belonging to a specific 802.1Q VID |
| [lag](lag.md) | infix-if-lag | Link aggregation, static and IEEE 802.3ad (LACP) |
| lo | ietf-interfaces | Software loopback interface |
| [eth](ethernet.md#physical-ethernet-interfaces) | ieee802-ethernet-interface | Physical Ethernet device/port |
+461
View File
@@ -0,0 +1,461 @@
# PTP — Precision Time Protocol
The Precision Time Protocol (PTP), defined in IEEE 1588-2019, synchronises
clocks across a network to sub-microsecond accuracy. Where NTP (Network Time
Protocol) aims at millisecond accuracy over wide-area networks, PTP is
designed for local-area networks and relies on hardware timestamping in the
network interface to eliminate software-induced jitter.
PTP works by exchanging timestamped messages between devices. A *grandmaster
clock* — elected by the **Best TimeTransmitter Clock Algorithm (BTCA)** based
on priority, clock class, and accuracy — distributes time to the rest of the
network. Each synchronising device measures the one-way message delay to its
time-transmitter and continuously adjusts its local clock to compensate.
> [!NOTE]
> The IEEE 1588g-2022 amendment to IEEE 1588-2019 introduced the terms
> *timeTransmitter* and *timeReceiver* as replacements for the former
> *master* and *slave* terminology, and *Best TimeTransmitter Clock
> Algorithm (BTCA)* in place of *BMCA*. This document uses the updated
> terms throughout. You may even see the short forms transmitter and
> receiver here and in online documentation.
## Clock roles
Every device in a PTP network takes one of the following roles:
| Role | Description |
|----------------------------|---------------------------------------------------------------------------------------------|
| **Grandmaster (GM)** | Network-wide time source; elected by BTCA |
| **Time-transmitter** | Sends Sync messages downstream on a port |
| **Time-receiver** | Synchronises to a time-transmitter on a port |
| **Boundary Clock (BC)** | Terminates PTP on each port; acts as time-receiver upstream and time-transmitter downstream |
| **Transparent Clock (TC)** | Passes PTP messages while correcting the residence-time delay accumulated in the device |
An **Ordinary Clock (OC)** has a single PTP port and is either a
time-transmitter (acting as a grandmaster candidate) or a time-receiver
(a leaf node synchronising to the network).
## PTP profiles
A **PTP profile** (as defined in IEEE 1588-2019 §3.1) is a document that
specifies a consistent set of required, permitted, and prohibited PTP
options for a particular application domain — much like a dialect of the
protocol. Examples from the standards world include profiles for power
utilities (IEC/IEEE C37.238), telecom (ITU-T G.8265.1), and
Time-Sensitive Networks.
Each profile sets a unique value in the `majorSdoId` field of PTP message
headers — a 4-bit identifier that lets devices distinguish traffic belonging
to different profiles on the same link. Profile also determines the network
transport (UDP or Ethernet) and the delay measurement mechanism.
Currently, two profiles are supported via the `profile` leaf in `default-ds`:
| `profile` | Standard | majorSdoId | Transport | Delay |
|----------------------|-------------------|:----------:|-----------|----------------|
| `ieee1588` (default) | IEEE 1588-2019 | `0x0` | UDP/IPv4 | `e2e` or `p2p` |
| `ieee802-dot1as` | IEEE 802.1AS-2020 | `0x1` | L2 | `p2p` |
The **gPTP** (generalized Precision Time Protocol) profile from IEEE 802.1AS-2020
is used in **TSN** (Time-Sensitive Networking) and **AVB** (Audio/Video Bridging)
applications. Setting `profile ieee802-dot1as` applies all protocol-mandatory
settings automatically — Layer 2 transport, P2P delay measurement, 802.1AS
multicast addressing, path trace, follow-up information, and neighbour propagation
delay thresholds. The user still configures `priority1`, `priority2`,
`domain-number`, `time-receiver-only`, and timer interval leaves.
The `ieee1588` profile leaves transport and delay mechanism user-configurable
per port.
## Delay mechanisms
PTP measures the link delay between neighbours using one of two mechanisms:
- **End-to-End (E2E)**: Each time-receiver measures the delay to the
grandmaster by sending a `DELAY_REQ` message upstream. Simple to
configure; works with any network topology.
- **Peer-to-Peer (P2P)**: Each port measures its delay to its *immediate
neighbour* independently using `PDELAY_REQ` messages. Enables faster
path-delay updates and is required by the gPTP profile.
## Data Sets
IEEE 1588 organises protocol state into named **Data Sets (DS)** — each a
collection of related attributes for one aspect of a PTP instance. You
will encounter these directly in the CLI and in the `show ptp` output:
| Data Set | CLI node | Contents |
|------------------|----------------|----------------------------------------------------------|
| Default DS | `default-ds` | Instance identity, clock class, priority, domain number |
| Current DS | `current-ds` | Live offset-from-GM, mean path delay, steps-removed |
| Parent DS | `parent-ds` | Grandmaster identity and quality attributes |
| Time Properties DS | `time-properties-ds` | UTC offset, leap-second flags, time source |
| Port DS | `port-ds` | Per-port state, delay mechanism, message intervals |
## Domains
A **PTP domain** (0255) is a logical partition of the network. Devices
only synchronise with others in the same domain. Running multiple
instances on the same device — one per domain, or one per profile — is
fully supported; each instance is independent.
Each PTP instance is identified on the network by its
`(domain-number, profile)` pair, which must be unique across all instances
on a device.
> [!NOTE]
> The `show ptp` offset values reflect **PHC** (PTP Hardware Clock)
> synchronisation only. A PHC is the hardware clock exposed by the network
> interface; it tracks the PTP grandmaster but is independent of the Linux
> system clock, which currently is **not** automatically adjusted.
## Ordinary Clock (time-receiver)
A typical time-receiver Ordinary Clock, synchronising on interface
`eth0` using the default IEEE 1588 profile:
<pre class="cli"><code>admin@example:/> <b>configure</b>
admin@example:/config/> <b>edit ptp instance 0</b>
admin@example:/config/ptp/instance/0/> <b>set default-ds domain-number 0</b>
admin@example:/config/ptp/instance/0/> <b>set default-ds time-receiver-only true</b>
admin@example:/config/ptp/instance/0/> <b>edit port 1</b>
admin@example:/config/ptp/…/0/port/1/> <b>set underlying-interface eth0</b>
admin@example:/config/ptp/…/0/port/1/> <b>leave</b>
</code></pre>
## Ordinary Clock (time-transmitter / grandmaster)
A grandmaster clock with high priority, domain 0:
<pre class="cli"><code>admin@example:/config/> <b>edit ptp instance 0</b>
admin@example:/config/ptp/instance/0/> <b>set default-ds domain-number 0</b>
admin@example:/config/ptp/instance/0/> <b>set default-ds priority1 1</b>
admin@example:/config/ptp/instance/0/> <b>set default-ds priority2 1</b>
admin@example:/config/ptp/instance/0/> <b>edit port 1</b>
admin@example:/config/ptp/…/0/port/1/> <b>set underlying-interface eth0</b>
admin@example:/config/ptp/…/0/port/1/> <b>leave</b>
</code></pre>
Lower `priority1` values win in the BTCA. A clock with `priority1 1` will
be preferred over the default `128` in any compliant network.
## Boundary Clock
A Boundary Clock terminates PTP on each port and re-originates it. Add one
port per interface:
<pre class="cli"><code>admin@example:/config/> <b>edit ptp instance 0</b>
admin@example:/config/ptp/instance/0/> <b>set default-ds instance-type bc</b>
admin@example:/config/ptp/instance/0/> <b>set default-ds domain-number 0</b>
admin@example:/config/ptp/instance/0/> <b>edit port 1</b>
admin@example:/config/ptp/…/0/port/1/> <b>set underlying-interface eth0</b>
admin@example:/config/ptp/…/0/port/1/> <b>end</b>
admin@example:/config/ptp/instance/0/> <b>edit port 2</b>
admin@example:/config/ptp/…/0/port/2/> <b>set underlying-interface eth1</b>
admin@example:/config/ptp/…/0/port/2/> <b>leave</b>
</code></pre>
> [!TIP]
> PTP port numbers are assigned sorted by `port-index`, so `port-index 1`
> becomes PTP port 1, `port-index 2` becomes PTP port 2, and so on.
## Transparent Clock
Transparent Clocks correct timestamps end-to-end without terminating PTP.
Use `instance-type p2p-tc` for a P2P TC (preferred in TSN networks) or
`instance-type e2e-tc` for an E2E TC:
<pre class="cli"><code>admin@example:/config/> <b>edit ptp instance 0</b>
admin@example:/config/ptp/instance/0/> <b>set default-ds instance-type p2p-tc</b>
admin@example:/config/ptp/instance/0/> <b>set default-ds domain-number 0</b>
admin@example:/config/ptp/instance/0/> <b>edit port 1</b>
admin@example:/config/ptp/…/0/port/1/> <b>set underlying-interface eth0</b>
admin@example:/config/ptp/…/0/port/1/> <b>end</b>
admin@example:/config/ptp/instance/0/> <b>edit port 2</b>
admin@example:/config/ptp/…/0/port/2/> <b>set underlying-interface eth1</b>
admin@example:/config/ptp/…/0/port/2/> <b>leave</b>
</code></pre>
> [!NOTE]
> For Transparent Clocks the delay mechanism is determined globally by the
> `instance-type` (`p2p-tc` → P2P, `e2e-tc` → E2E). Per-port
> `delay-mechanism` settings have no effect for TC instances.
## gPTP / IEEE 802.1AS
The gPTP profile is used in TSN and AVB applications. Setting
`profile ieee802-dot1as` applies all protocol-mandatory options from
IEEE 802.1AS-2020 automatically — Layer 2 transport, P2P delay
measurement, 802.1AS multicast addressing, and related protocol features.
<pre class="cli"><code>admin@example:/config/> <b>edit ptp instance 0</b>
admin@example:/config/ptp/instance/0/> <b>set default-ds profile ieee802-dot1as</b>
admin@example:/config/ptp/instance/0/> <b>set default-ds domain-number 0</b>
admin@example:/config/ptp/instance/0/> <b>set default-ds time-receiver-only true</b>
admin@example:/config/ptp/instance/0/> <b>edit port 1</b>
admin@example:/config/ptp/…/0/port/1/> <b>set underlying-interface eth0</b>
admin@example:/config/ptp/…/0/port/1/> <b>leave</b>
</code></pre>
> [!NOTE]
> The `ieee802-dot1as` profile enforces Layer 2 transport and P2P delay
> measurement globally, as required by IEEE 802.1AS-2020. Per-port
> `delay-mechanism` settings have no effect for 802.1AS instances.
## Multiple Instances
Multiple PTP instances can run simultaneously, one per domain or profile
combination. Each instance must have a unique `(domain-number, profile)`
pair and an independent set of ports:
<pre class="cli"><code>admin@example:/config/> <b>edit ptp instance 0</b>
admin@example:/config/ptp/instance/0/> <b>set default-ds domain-number 0</b>
admin@example:/config/ptp/instance/0/> <b>set default-ds profile ieee1588</b>
admin@example:/config/ptp/instance/0/> <b>edit port 1</b>
admin@example:/config/ptp/…/0/port/1/> <b>set underlying-interface eth0</b>
admin@example:/config/ptp/…/0/port/1/> <b>end</b>
admin@example:/config/ptp/instance/0/> <b>end</b>
admin@example:/config/ptp/> <b>edit instance 1</b>
admin@example:/config/ptp/instance/1/> <b>set default-ds domain-number 0</b>
admin@example:/config/ptp/instance/1/> <b>set default-ds profile ieee802-dot1as</b>
admin@example:/config/ptp/instance/1/> <b>edit port 1</b>
admin@example:/config/ptp/…/1/port/1/> <b>set underlying-interface eth1</b>
admin@example:/config/ptp/…/1/port/1/> <b>leave</b>
</code></pre>
## Port states
Each PTP port progresses through a state machine. The current state is
shown in the `show ptp` port table:
| State | Meaning |
|------------------------|----------------------------------------------------------------|
| `initializing` | Port is starting up, not yet ready to exchange messages |
| `faulty` | A fault condition has been detected on this port |
| `disabled` | Port is administratively disabled |
| `listening` | Awaiting `ANNOUNCE` messages; BTCA has not yet resolved |
| `pre-time-transmitter` | Transitioning towards time-transmitter state |
| `time-transmitter` | Port is acting as time-transmitter on this link |
| `passive` | Another port on this device is already time-transmitter |
| `uncalibrated` | Receiving sync; local clock not yet locked to time-transmitter |
| `time-receiver` | Port is locked and tracking its time-transmitter |
A port in `uncalibrated` will typically transition to `time-receiver`
within a few seconds once the clock servo has converged.
## Monitoring
> [!TIP] Use the ++question++ key in the CLI
> The `show ptp` command has sub-commands — tap ++question++ after
> `show ptp` to see them, or use ++tab++ to complete.
### Show all PTP instances
<pre class="cli"><code>admin@example:/> <b>show ptp</b>
<b>PTP Instance 0</b> Ordinary Clock · domain 0
────────────────────────────────────────────────────────────────────
Clock identity : AA-BB-CC-FF-FE-00-11-22
Grandmaster : DD-EE-FF-FF-FE-33-44-55
Priority1/Priority2 : 128 / 128
GM Priority1/Priority2 : 1 / 1
Clock class : cc-time-receiver-only
GM clock class : cc-primary-sync
Time source : gnss
PTP timescale : yes
UTC offset : 37 s
Time traceable : yes
Freq. traceable : yes
Offset from GM : -42 ns
Mean path delay : 1250 ns
Steps removed : 1
────────────────────────────────────────────────────────────────────
Ports
<span class="header">PORT INTERFACE STATE DELAY LINK DELAY (ns)</span>
1 eth0 <span class="ok">time-receiver</span> E2E 0
────────────────────────────────────────────────────────────────────
Message Statistics (▼ rx ▲ tx)
<span class="header">PORT INTERFACE SYNC ▼ SYNC ▲ ANN ▼ ANN ▲ PD ▼ PD ▲</span>
1 eth0 42 0 15 0 0 0
</code></pre>
Port state is colour-coded: green for `time-transmitter` and `time-receiver`
(actively synchronising), yellow for transient states (`listening`,
`uncalibrated`, `pre-time-transmitter`), and red for fault states (`faulty`,
`disabled`). The *Message Statistics* section is omitted when no counts are
available.
### Show a specific instance
<pre class="cli"><code>admin@example:/> <b>show ptp 0</b>
</code></pre>
## Tuning port intervals
Adjust announcement, sync, and delay-request intervals per port. Values
are expressed as log₂ of the interval in seconds (e.g. `-3` = 125 ms,
`0` = 1 s, `1` = 2 s):
<pre class="cli"><code>admin@example:/config/ptp/…/0/port/1/> <b>set port-ds log-announce-interval 0</b>
admin@example:/config/ptp/…/0/port/1/> <b>set port-ds log-sync-interval -3</b>
admin@example:/config/ptp/…/0/port/1/> <b>set port-ds log-min-delay-req-interval 0</b>
admin@example:/config/ptp/…/0/port/1/> <b>set announce-receipt-timeout 3</b>
</code></pre>
`announce-receipt-timeout` is a count of announce intervals, not a duration
in seconds. With `log-announce-interval 0` (1 s) and
`announce-receipt-timeout 3`, a port waits 3 s without receiving an
`ANNOUNCE` before declaring the time-transmitter lost and returning to
`listening`.
## Message exchange
PTP distributes time using a small set of messages, all of which carry
hardware timestamps at the network interface:
| Message | Timestamped | Purpose |
|-------------------------|:-----------:|-----------------------------------------------------|
| `ANNOUNCE` | No | Advertises clock quality for BTCA election |
| `SYNC` | Yes | Carries transmitter timestamp to receivers |
| `FOLLOW_UP` | No | Carries precise `t1` in two-step mode |
| `DELAY_REQ` | Yes | Receiver-initiated E2E delay measurement |
| `DELAY_RESP` | No | Time-transmitter reply to `DELAY_REQ` |
| `PDELAY_REQ` | Yes | Initiates P2P neighbour-delay measurement |
| `PDELAY_RESP` | Yes | Neighbour reply to `PDELAY_REQ` |
| `PDELAY_RESP_FOLLOW_UP` | No | Carries precise `PDELAY_RESP` `t3` in two-step mode |
In **one-step** mode the timestamp is embedded directly into each `SYNC`
message as it leaves the wire, eliminating the need for `FOLLOW_UP`.
In **two-step** mode the `SYNC` carries a placeholder and the precise
transmit timestamp arrives in a subsequent `FOLLOW_UP`. Hardware
timestamping gives high accuracy in both modes; one-step reduces message
overhead at the cost of more demanding hardware support.
## Message format
Every PTP message begins with a common 34-octet header, regardless of type.
The structure below follows the traditional IETF bit-field layout: each row
is four octets wide, bit 7 (MSB) is on the left and bit 0 (LSB) on the
right within each octet.
```
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0-3 |trSpec |msgType| rsv | ver | messageLength |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4-7 | domainNumber | minorSdoId | flags |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8-15 | |
+ correctionField +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16-19 | messageTypeSpecific |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20-27 | |
+ clockIdentity +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
28-31 | portNumber | sequenceId |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
32-33 | controlField | logMsgIntvl |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
```
- **`trSpec`** (`transportSpecific`, bits 74 of octet 0): 4-bit profile
identifier. `0x0` = IEEE 1588, `0x1` = gPTP (802.1AS). Set implicitly
by the `profile` configuration leaf.
- **`msgType`** (`messageType`, bits 30 of octet 0): `0x0` SYNC ·
`0x1` DELAY_REQ · `0x2` PDELAY_REQ · `0x3` PDELAY_RESP ·
`0x8` FOLLOW_UP · `0x9` DELAY_RESP · `0xA` PDELAY_RESP_FOLLOW_UP ·
`0xB` ANNOUNCE.
- **`rsv`** (reserved, bits 74 of octet 1): Set to zero; ignored on
receipt.
- **`ver`** (`versionPTP`, bits 30 of octet 1): PTP version; `2` for
IEEE 1588-2008 and IEEE 1588-2019.
- **`messageLength`** (octets 23): Total message length in octets,
including the header.
- **`domainNumber`** (octet 4): PTP domain; receivers silently discard
messages that do not match their configured domain.
- **`minorSdoId`** (octet 5): Reserved in IEEE 1588-2008; carries a
profile sub-identifier in IEEE 1588-2019.
- **`flags`** (octets 67): Per-message flags — includes the two-step
flag (set when a FOLLOW_UP will follow a SYNC), UTC offset valid, and
leap-second indicators.
- **`correctionField`** (octets 815): Accumulated path correction in
nanoseconds × 2¹⁶. Transparent Clocks add their measured residence
time and link delay here as they forward each message, so the final
time-receiver can subtract the total accumulated delay.
- **`messageTypeSpecific`** (octets 1619): Reserved in IEEE 1588-2008;
carries message-type-specific data in IEEE 1588-2019.
- **`clockIdentity`** (octets 2027): EUI-64 identity of the sending
clock — the value shown as "Clock identity" in `show ptp`.
- **`portNumber`** (octets 2829): Port number of the sender within its
clock; together with `clockIdentity` it forms the unique
`sourcePortIdentity`.
- **`sequenceId`** (octets 3031): Increments with each message; used to
match a DELAY_REQ to its DELAY_RESP.
- **`controlField`** (octet 32): Deprecated in PTPv2; set to fixed
values per message type for backward compatibility with PTPv1.
- **`logMsgIntvl`** (`logMessageInterval`, octet 33): Log₂ of the
expected interval between messages of this type; `0x7F` means not
applicable.
The `transportSpecific` and `domainNumber` fields are the quickest way to
verify on the wire that a device is using the profile and domain you
configured.
### Decoding with Wireshark
Wireshark decodes PTP messages automatically, expanding every header field
and message-type-specific payload in the packet tree. PTP travels over
two UDP ports — 319 for event messages (SYNC, DELAY_REQ, PDELAY_REQ and
their responses) and 320 for general messages (ANNOUNCE, FOLLOW_UP) — as
well as directly over Ethernet (EtherType `0x88F7`) when layer-2 transport
is in use.
Use the display filter `ptp` to isolate PTP traffic:
```
ptp
```
To narrow down to a specific domain or profile (exact field names can be
verified in Wireshark via **View → Internals → Supported Protocols**,
filtering for `ptp`):
```
ptp.v2.domainnumber == 0
ptp.v2.transportspecific == 1
```
This makes it straightforward to confirm which grandmaster a port is
tracking, verify that `correctionField` is being updated by a Transparent
Clock, or diagnose why the BTCA is not electing the expected grandmaster.
## Glossary
| Abbreviation | Expansion | Notes |
|--------------|--------------------------------------|-------------------------------------------------------------------|
| AVB | Audio/Video Bridging | IEEE 802.1 precursor to TSN; real-time AV over Ethernet |
| IETF | Internet Engineering Task Force | Standards body; defines RFC for layer-3 and up |
| UDP | User Datagram Protocol | IP transport used by PTP; port 319 (event) and 320 (general) |
| EUI-64 | Extended Unique Identifier (64-bit) | IEEE identifier format used as `clockIdentity` in PTP |
| EtherType | Ethernet frame type field | `0x88F7` identifies PTP over layer-2 Ethernet |
| BC | Boundary Clock | Terminates and re-originates PTP on each port |
| BTCA | Best TimeTransmitter Clock Algorithm | Elects the GM; replaces BMCA from IEEE 1588-2008 |
| CMLDS | Common Mean Link Delay Service | IEEE 1588-2019 §16.6; shared delay service for multiple instances |
| DS | Data Set | Named attribute collection in IEEE 1588 (default-ds, port-ds, …) |
| E2E | End-to-End | Delay mechanism: measures path from GM to time-receiver |
| GM | Grandmaster | PTP network-wide time source, elected by BTCA |
| gPTP | generalized Precision Time Protocol | IEEE 802.1AS profile; used in TSN and AVB |
| NTP | Network Time Protocol | Millisecond-accuracy time protocol for wide-area use |
| OC | Ordinary Clock | Single-port PTP clock; time-transmitter or time-receiver |
| P2P | Peer-to-Peer | Delay mechanism: measures delay to immediate neighbour |
| PHC | PTP Hardware Clock | Hardware clock in the NIC used for PTP timestamping |
| PTP | Precision Time Protocol | IEEE 1588 sub-microsecond clock synchronisation protocol |
| SDO | Standards Development Organization | Body that defines a PTP profile; encoded in `sdo-id` |
| TC | Transparent Clock | Forwards PTP messages, correcting for residence-time delay |
| TSN | Time-Sensitive Networking | IEEE 802.1 standard set for deterministic Ethernet |
+61 -61
View File
@@ -39,20 +39,20 @@ Starting out, we assume a configuration where all ports are network
interfaces (possibly with IPv6 enabled).
```
admin@example:/> show interfaces
lo ethernet UP 00:00:00:00:00:00
admin@example:/> show interface
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
e1 ethernet LOWER-DOWN 00:53:00:06:11:01
e2 ethernet LOWER-DOWN 00:53:00:06:11:02
e3 ethernet LOWER-DOWN 00:53:00:06:11:03
e4 ethernet LOWER-DOWN 00:53:00:06:11:04
e5 ethernet LOWER-DOWN 00:53:00:06:11:05
e6 ethernet LOWER-DOWN 00:53:00:06:11:06
e7 ethernet LOWER-DOWN 00:53:00:06:11:07
e8 ethernet LOWER-DOWN 00:53:00:06:11:08
e9 ethernet LOWER-DOWN 00:53:00:06:11:09
e10 ethernet UP 00:53:00:06:11:0a
e1 ethernet LOWER-DOWN 00:53:00:06:11:01
e2 ethernet LOWER-DOWN 00:53:00:06:11:02
e3 ethernet LOWER-DOWN 00:53:00:06:11:03
e4 ethernet LOWER-DOWN 00:53:00:06:11:04
e5 ethernet LOWER-DOWN 00:53:00:06:11:05
e6 ethernet LOWER-DOWN 00:53:00:06:11:06
e7 ethernet LOWER-DOWN 00:53:00:06:11:07
e8 ethernet LOWER-DOWN 00:53:00:06:11:08
e9 ethernet LOWER-DOWN 00:53:00:06:11:09
e10 ethernet UP 00:53:00:06:11:0a
ipv6 fe80::0053:00ff:fe06:110a/64 (link-layer)
admin@example:/>
```
@@ -80,7 +80,7 @@ admin@example:/config/> set interface e10 bridge-port bridge br0
admin@example:/config/>
```
The interface status can be viewed using `show interfaces` after leaving
The interface status can be viewed using `show interface` after leaving
configuration context. When configuring via SSH, first assign an IP
address to `br0` *before leaving* configuration context, e.g.
@@ -95,10 +95,10 @@ setup, including [setting IP address](#set-ip-address).
```
admin@example:/config/> leave
admin@example:/>
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
admin@example:/> show interface
INTERFACE PROTOCOL STATE DATA
br0 bridge
│ ethernet UP 00:53:00:06:11:01
│ ethernet UP 00:53:00:06:11:01
├ e1 bridge LOWER-DOWN
├ e2 bridge LOWER-DOWN
├ e3 bridge LOWER-DOWN
@@ -109,7 +109,7 @@ br0 bridge
├ e8 bridge LOWER-DOWN
├ e9 bridge LOWER-DOWN
└ e10 bridge FORWARDING
lo ethernet UP 00:00:00:00:00:00
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
admin@example:/>
@@ -154,21 +154,21 @@ admin@example:/>
Interface status would now should something like the following
```
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
admin@example:/> show interface
INTERFACE PROTOCOL STATE DATA
br0 bridge
│ ethernet UP 00:53:00:06:11:01
├ e1 bridge LOWER-DOWN vlan:10u pvid:10
├ e2 bridge LOWER-DOWN vlan:10u pvid:10
├ e3 bridge LOWER-DOWN vlan:20u pvid:20
├ e4 bridge LOWER-DOWN vlan:20u pvid:20
├ e5 bridge LOWER-DOWN vlan:30u pvid:30
├ e6 bridge LOWER-DOWN vlan:30u pvid:30
├ e7 bridge LOWER-DOWN vlan:40u pvid:40
├ e8 bridge LOWER-DOWN vlan:40u pvid:40
├ e9 bridge LOWER-DOWN vlan:50u pvid:50
└ e10 bridge FORWARDING vlan:50u pvid:50
lo ethernet UP 00:00:00:00:00:00
│ ethernet UP 00:53:00:06:11:01
├ e1 bridge LOWER-DOWN vlan:10u pvid: 10
├ e2 bridge LOWER-DOWN vlan:10u pvid: 10
├ e3 bridge LOWER-DOWN vlan:20u pvid: 20
├ e4 bridge LOWER-DOWN vlan:20u pvid: 20
├ e5 bridge LOWER-DOWN vlan:30u pvid: 30
├ e6 bridge LOWER-DOWN vlan:30u pvid: 30
├ e7 bridge LOWER-DOWN vlan:40u pvid: 40
├ e8 bridge LOWER-DOWN vlan:40u pvid: 40
├ e9 bridge LOWER-DOWN vlan:50u pvid: 50
└ e10 bridge FORWARDING vlan:50u pvid: 50
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
admin@example:/>
@@ -181,21 +181,21 @@ patched according to [above](#vlan-snake). We should see link up and
*FORWARDING* on all ports in the bridge.
```
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
admin@example:/> show interface
INTERFACE PROTOCOL STATE DATA
br0 bridge
│ ethernet UP 00:53:00:06:11:01
├ e1 bridge FORWARDING vlan:10u pvid:10
├ e2 bridge FORWARDING vlan:10u pvid:10
├ e3 bridge FORWARDING vlan:20u pvid:20
├ e4 bridge FORWARDING vlan:20u pvid:20
├ e5 bridge FORWARDING vlan:30u pvid:30
├ e6 bridge FORWARDING vlan:30u pvid:30
├ e7 bridge FORWARDING vlan:40u pvid:40
├ e8 bridge FORWARDING vlan:40u pvid:40
├ e9 bridge FORWARDING vlan:50u pvid:50
└ e10 bridge FORWARDING vlan:50u pvid:50
lo ethernet UP 00:00:00:00:00:00
│ ethernet UP 00:53:00:06:11:01
├ e1 bridge FORWARDING vlan:10u pvid: 10
├ e2 bridge FORWARDING vlan:10u pvid: 10
├ e3 bridge FORWARDING vlan:20u pvid: 20
├ e4 bridge FORWARDING vlan:20u pvid: 20
├ e5 bridge FORWARDING vlan:30u pvid: 30
├ e6 bridge FORWARDING vlan:30u pvid: 30
├ e7 bridge FORWARDING vlan:40u pvid: 40
├ e8 bridge FORWARDING vlan:40u pvid: 40
├ e9 bridge FORWARDING vlan:50u pvid: 50
└ e10 bridge FORWARDING vlan:50u pvid: 50
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
admin@example:/>
@@ -284,26 +284,26 @@ admin@example:/>
Interface *vlan10* with an auto-configured IPv6 address should appear.
```
admin@example:/> show interfaces
INTERFACE PROTOCOL STATE DATA
admin@example:/> show interface
INTERFACE PROTOCOL STATE DATA
br0 bridge vlan:10t
│ ethernet UP 00:53:00:06:11:01
├ e1 bridge FORWARDING vlan:10u pvid:10
├ e2 bridge FORWARDING vlan:10u pvid:10
├ e3 bridge FORWARDING vlan:20u pvid:20
├ e4 bridge FORWARDING vlan:20u pvid:20
├ e5 bridge FORWARDING vlan:30u pvid:30
├ e6 bridge FORWARDING vlan:30u pvid:30
├ e7 bridge FORWARDING vlan:40u pvid:40
├ e8 bridge FORWARDING vlan:40u pvid:40
├ e9 bridge FORWARDING vlan:50u pvid:50
└ e10 bridge FORWARDING vlan:50u pvid:50
lo ethernet UP 00:00:00:00:00:00
│ ethernet UP 00:53:00:06:11:01
├ e1 bridge FORWARDING vlan:10u pvid: 10
├ e2 bridge FORWARDING vlan:10u pvid: 10
├ e3 bridge FORWARDING vlan:20u pvid: 20
├ e4 bridge FORWARDING vlan:20u pvid: 20
├ e5 bridge FORWARDING vlan:30u pvid: 30
├ e6 bridge FORWARDING vlan:30u pvid: 30
├ e7 bridge FORWARDING vlan:40u pvid: 40
├ e8 bridge FORWARDING vlan:40u pvid: 40
├ e9 bridge FORWARDING vlan:50u pvid: 50
└ e10 bridge FORWARDING vlan:50u pvid: 50
lo ethernet UP 00:00:00:00:00:00
ipv4 127.0.0.1/8 (static)
ipv6 ::1/128 (static)
vlan10 ethernet UP 00:53:00:06:11:01
vlan10 ethernet UP 00:53:00:06:11:01
│ ipv6 fe80::0053:00ff:fe06:1101/64 (link-layer)
└ br0 ethernet UP 00:53:00:06:11:01
└ br0 ethernet UP 00:53:00:06:11:01
admin@example:/>
```
+2 -2
View File
@@ -108,7 +108,7 @@ DHCP server, and the other two as DHCP clients - with all three having
a management connection to the host PC running the test. In other
words, the test requires a _logical_ topology like the one below.
<img align="right" src="img/testing-log.dot.svg" alt="Example Logical Topology">
![Example Logical Topology](img/testing-log.svg){ align=right width="360" }
```dot
graph "dhcp-client-server" {
@@ -155,7 +155,7 @@ degrees), we can deploy well-known algorithms to find such subgraphs.
Continuing our example, let's say we want to run our DHCP test on the
_physical_ topology below.
<img align="right" src="img/testing-phy.dot.svg" alt="Example Physical Topology">
![Example Physical Topology](img/testing-phy.svg){ align=right width="360" }
```dot
graph "quad-ring" {
+47
View File
@@ -359,6 +359,53 @@ $ make test-spec
...
```
### Node and Link Capabilities
Logical topology files (`topology.dot`) declare what each node and link
*requires*; physical topology files declare what each node and link
*provides*. When mapping a logical topology to physical hardware, infamy
only assigns a physical node to a logical node when the physical node's
`provides` set is a superset of the logical node's `requires` set. Tests
are skipped if no matching physical topology can be found.
#### Declaring requirements (logical topology)
```dot
dut [
requires="infix",
];
host:data -- dut:data [requires="ptp-hwts"]
```
#### Declaring capabilities (physical topology)
```dot
switch1 [
provides="infix",
];
switch1:eth0 -- switch2:eth0 [provides="ptp-hwts"]
```
#### Node capabilities
| Capability | Meaning |
|-------------------|-------------------------------------------------------------------------|
| `controller` | Reserved for the host/controller node; never assigned to a DUT |
| `infix` | Node runs Infix OS — required by virtually all DUT nodes |
| `gps` | Node has a GPS receiver available as a time reference |
| `watchdog` | Node has a hardware watchdog device |
#### Link capabilities
| Capability | Meaning |
|-------------------|-------------------------------------------------------------------------|
| `mgmt` | Link is a management path (typically coloured grey in diagrams) |
| `ieee-mc` | Link carries IEEE multicast traffic (required by LAG and some L2 tests) |
| `link-ctrl copper`| Link supports copper speed/duplex control |
| `ptp-hwts` | Both ends of this link support PTP hardware timestamping (PHC); required for sub-microsecond accuracy |
### Test Development
For adding a new test to the automated regression test suite, it's best
+89
View File
@@ -0,0 +1,89 @@
# VLAN Interfaces
A VLAN interface is an interface stacked on top of another Linux interface
that filters traffic for a single 802.1Q VID. `tcpdump` on a VLAN interface
shows only frames matching that VID, compared to *all* VIDs when listening
on the lower-layer interface.
![VLAN interface on top of Ethernet or Bridge interfaces](img/interface-vlan-variants.svg)
This page covers VLAN interfaces stacked on Ethernet, on a VLAN-filtering
bridge, and on other VLAN interfaces. For VLAN handling *inside* a bridge
(port VIDs, tagged/untagged membership, pvid), see [VLAN Filtering
Bridge](bridging.md#vlan-filtering-bridge).
## On Top of an Ethernet Interface
A VLAN interface for VID 20 on top of an Ethernet interface `eth0` is by
convention named `eth0.20`.
<pre class="cli"><code>admin@example:/> <b>configure</b>
admin@example:/config/> <b>edit interface eth0.20</b>
admin@example:/config/interface/eth0.20/> <b>show</b>
type vlan;
vlan {
tag-type c-vlan;
id 20;
lower-layer-if eth0;
}
admin@example:/config/interface/eth0.20/> <b>leave</b>
</code></pre>
The `tag-type` defaults to `c-vlan` (802.1Q customer VLAN, EtherType 0x8100).
Set to `s-vlan` (802.1ad service VLAN, EtherType 0x88A8) to terminate an outer
S-Tag.
> [!TIP]
> If you name your VLAN interface `foo0.N` or `vlanN`, where `N` is a
> number, the CLI infers the interface type automatically. Otherwise
> the type must be set explicitly.
## On Top of a Bridge
When the lower-layer interface is a VLAN-filtering bridge, the VLAN interface
gives the CPU an IP-addressable endpoint inside the bridged broadcast domain
for that VID. This pattern is named `vlanN` by convention.
<pre class="cli"><code>admin@example:/> <b>configure</b>
admin@example:/config/> <b>edit interface vlan10</b>
admin@example:/config/interface/vlan10/> <b>set vlan id 10</b>
admin@example:/config/interface/vlan10/> <b>set vlan lower-layer-if br0</b>
admin@example:/config/interface/vlan10/> <b>leave</b>
</code></pre>
The bridge `br0` must have VLAN 10 configured with the bridge itself as a
tagged member. See [VLAN Filtering Bridge](bridging.md#vlan-filtering-bridge)
for the bridge-side configuration.
## Stacked (Q-in-Q)
VLAN interfaces can be stacked. A VLAN interface whose lower-layer is itself
a VLAN interface terminates the inner tag, leaving the outer tag for the
parent to handle.
<pre class="cli"><code>admin@example:/> <b>configure</b>
admin@example:/config/> <b>edit interface eth0.10</b>
admin@example:/config/interface/eth0.10/> <b>set vlan tag-type s-vlan</b>
admin@example:/config/interface/eth0.10/> <b>leave</b>
admin@example:/config/> <b>edit interface eth0.10.20</b>
admin@example:/config/interface/eth0.10.20/> <b>show</b>
type vlan;
vlan {
tag-type c-vlan;
id 20;
lower-layer-if eth0.10;
}
admin@example:/config/interface/eth0.10.20/> <b>leave</b>
</code></pre>
The summary view shows each VLAN row pointing at its immediate parent:
<pre class="cli"><code>admin@example:/> <b>show interface</b>
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
eth0.10 vlan UP vid: 10
│ ipv4 10.0.10.1/24 (static)
└ eth0
eth0.10.20 vlan UP vid: 20
│ ipv4 10.0.10.20/28 (static)
└ eth0.10
</code></pre>
+7 -7
View File
@@ -345,17 +345,17 @@ tunnel endpoints use IPv4 or IPv6.
Check WireGuard interface status and peer connections:
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
<pre class="cli"><code>admin@example:/> <b>show interface</b>
wg0 wireguard UP 2 peers (1 up)
ipv4 10.0.0.1/24 (static)
ipv6 fd00::1/64 (static)
admin@example:/> <b>show interfaces wg0</b>
name : wg0
type : wireguard
index : 12
operational status : up
peers : 2
admin@example:/> <b>show interface wg0</b>
name : wg0
type : wireguard
index : 12
operational status : up
peers : 2
Peer 1:
status : UP
+39 -29
View File
@@ -137,6 +137,7 @@ admin@example:/config/> <b>edit hardware component radio0 wifi-radio</b>
admin@example:/config/hardware/component/radio0/wifi-radio/> <b>set country-code DE</b>
admin@example:/config/hardware/component/radio0/wifi-radio/> <b>set band 5GHz</b>
admin@example:/config/hardware/component/radio0/wifi-radio/> <b>set channel 36</b>
admin@example:/config/hardware/component/radio0/wifi-radio/> <b>set channel-width 80MHz</b>
admin@example:/config/hardware/component/radio0/wifi-radio/> <b>leave</b>
</code></pre>
@@ -150,22 +151,26 @@ admin@example:/config/hardware/component/radio0/wifi-radio/> <b>leave</b>
- 2.4GHz: 802.11n/ax
- 5GHz: 802.11n/ac/ax
- 6GHz: 802.11ax
- `channel`: Channel number (1-196) or "auto". When set to "auto", defaults to
channel 6 for 2.4GHz, channel 36 for 5GHz, or channel 109 for 6GHz
- `channel`: Channel number (1-233) or "auto". When set to "auto", defaults to
channel 6 for 2.4GHz, channel 36 for 5GHz, or channel 37 for 6GHz
- `channel-width`: AP channel bandwidth. Supported values are `auto`, `20MHz`,
`40MHz`, `80MHz`, and `160MHz`. Wider channels require matching hardware,
regulatory approval, and are only available on 5GHz/6GHz where supported.
- `probe-timeout`: Seconds to wait for PHY detection at boot (default: 0). Set
to a non-zero value (e.g., 30) for USB WiFi dongles that are slow to
initialize due to firmware loading
> [!NOTE]
> TX power and channel width are automatically determined by the driver
> based on regulatory constraints, PHY mode, and hardware capabilities.
> TX power is still determined by the driver based on regulatory
> constraints and hardware capabilities. Channel width can now be set
> explicitly for AP mode, or left at `auto` to let the driver choose.
### WiFi 6 Support
WiFi 6 (802.11ax) is always enabled in AP mode on all bands, providing improved
performance through features like OFDMA, BSS Coloring, and beamforming.
**WiFi 6 Features (always enabled):**
**WiFi 6 Features (always enabled in AP mode on supported radios):**
- **OFDMA**: Better multi-user efficiency in dense environments
- **BSS Coloring**: Reduced interference from neighboring networks
@@ -177,6 +182,11 @@ performance through features like OFDMA, BSS Coloring, and beamforming.
- Client devices must support WiFi 6 for full benefits
- Older WiFi 5/4 clients can still connect but won't use WiFi 6 features
> [!IMPORTANT]
> 6 GHz AP operation requires WPA3-Personal (SAE) with mandatory
> management frame protection. Open networks and WPA2-only AP
> configurations are not valid on 6 GHz.
## Discovering Available Networks
Before connecting to a WiFi network, you need to discover which networks
@@ -213,22 +223,22 @@ access-point).
Use `show interface` to see discovered networks and their signal strength:
<pre class="cli"><code>admin@example:/> <b>show interface wifi0</b>
name : wifi0
type : wifi
index : 3
mtu : 1500
operational status : up
ip forwarding : enabled
physical address : f0:09:0d:36:5f:86
ipv4 addresses : 192.168.1.100/24 (dhcp)
ipv6 addresses :
in-octets : 148388
out-octets : 24555
mode : station
ssid : MyNetwork
signal : -45 dBm (good)
rx bitrate : 72.2 Mbps
tx bitrate : 86.6 Mbps
name : wifi0
type : wifi
index : 3
mtu : 1500
operational status : up
ip forwarding : enabled
physical address : f0:09:0d:36:5f:86
ipv4 addresses : 192.168.1.100/24 (dhcp)
ipv6 addresses :
in-octets : 148388
out-octets : 24555
mode : station
ssid : MyNetwork
signal : -45 dBm (good)
rx bitrate : 72.2 Mbps
tx bitrate : 86.6 Mbps
──────────────────────────────────────────────────────────────────────
<span class="title">Available Networks</span>
<span class="header">SSID BSSID SECURITY SIGNAL CHANNEL</span>
@@ -294,13 +304,13 @@ admin@example:/config/interface/wifi0/> <b>leave</b>
The connection attempt will start immediately. You can verify the connection status:
<pre class="cli"><code>admin@example:/> <b>show interface wifi0</b>
name : wifi0
type : wifi
operational status : up
physical address : f0:09:0d:36:5f:86
mode : station
ssid : MyHomeNetwork
signal : -52 dBm (good)
name : wifi0
type : wifi
operational status : up
physical address : f0:09:0d:36:5f:86
mode : station
ssid : MyHomeNetwork
signal : -52 dBm (good)
</code></pre>
**Station configuration parameters:**
@@ -345,7 +355,6 @@ admin@example:/config/keystore/…/my-wifi-secret/> <b>end</b>
<pre class="cli"><code>admin@example:/config/> <b>edit interface wifi0</b>
admin@example:/config/interface/wifi0/> <b>set wifi radio radio0</b>
admin@example:/config/interface/wifi0/> <b>set wifi access-point ssid MyNetwork</b>
admin@example:/config/interface/wifi0/> <b>set wifi access-point security mode wpa2-personal</b>
admin@example:/config/interface/wifi0/> <b>set wifi access-point security secret my-wifi-secret</b>
admin@example:/config/interface/wifi0/> <b>leave</b>
</code></pre>
@@ -365,6 +374,7 @@ admin@example:/config/interface/wifi0/> <b>leave</b>
**Security modes:**
- `open`: No encryption (not recommended)
- `auto`: WPA2/WPA3 transitional mode on 2.4/5 GHz, WPA3-only on 6 GHz
- `wpa2-personal`: WPA2-PSK (most compatible)
- `wpa3-personal`: WPA3-SAE (more secure, requires WPA3-capable clients)
- `wpa2-wpa3-personal`: Mixed mode (maximum compatibility)
+7 -1
View File
@@ -3,7 +3,7 @@ site_description: Infix Documentation
site_url: https://kernelkit.github.io/infix/
repo_url: https://github.com/kernelkit/infix/
repo_name: kernelkit/infix
copyright: Copyright &copy; 2022-2025 The KernelKit Team
copyright: Copyright &copy; 2022-2026 The KernelKit Team
docs_dir: doc/
edit_uri: edit/master/doc/
extra_css:
@@ -33,6 +33,7 @@ nav:
- Bridging: bridging.md
- Link Aggregation: lag.md
- Ethernet Interfaces: ethernet.md
- VLAN Interfaces: vlan.md
- IP Addressing: ip.md
- Routing: routing.md
- Firewall Configuration: firewall.md
@@ -47,6 +48,7 @@ nav:
- Device Discovery: discovery.md
- DHCP Server: dhcp.md
- NTP Server: ntp.md
- PTP (IEEE 1588/802.1AS): ptp.md
- System:
- Boot Procedure: boot.md
- Configuration: system.md
@@ -77,6 +79,10 @@ nav:
theme:
logo: logo-plain.png
name: material
# Fonts are loaded by doc/extra.css (Lato headings + Source Sans body +
# system monospace, matching the Chirpy blog) instead of Material's
# auto-loaded Roboto. Keep this false so Material does not also fetch Roboto.
font: false
features:
- toc.follow
# - toc.integrate
+10
View File
@@ -12,6 +12,7 @@ define FEATURE_WIFI_LINUX_CONFIG_FIXUPS
$(call KCONFIG_ENABLE_OPT,CONFIG_RFKILL)
$(call KCONFIG_SET_OPT,CONFIG_MAC80211,m)
$(call KCONFIG_SET_OPT,CONFIG_CFG80211,m)
$(call KCONFIG_ENABLE_OPT,CONFIG_MAC80211_MESH)
$(if $(filter y,$(BR2_PACKAGE_FEATURE_WIFI_MEDIATEK)),
$(call KCONFIG_ENABLE_OPT,CONFIG_MT7601U)
@@ -67,4 +68,13 @@ define FEATURE_WIFI_LINUX_CONFIG_FIXUPS
)
endef
define FEATURE_WIFI_INSTALL_IN_ROMFS
mkdir -p $(TARGET_DIR)/etc/modprobe.d $(TARGET_DIR)/etc/udev/rules.d
cp $(FEATURE_WIFI_PKGDIR)/mt7915e.conf $(TARGET_DIR)/etc/modprobe.d/mt7915e.conf
cp $(FEATURE_WIFI_PKGDIR)/60-rename-wifi-phy.rules $(TARGET_DIR)/etc/udev/rules.d/60-rename-wifi-phy.rules
cp $(FEATURE_WIFI_PKGDIR)/70-remove-virtual-wifi-interfaces.rules $(TARGET_DIR)/etc/udev/rules.d/70-remove-virtual-wifi-interfaces.rules
endef
FEATURE_WIFI_POST_INSTALL_TARGET_HOOKS += FEATURE_WIFI_INSTALL_IN_ROMFS
$(eval $(generic-package))
+1
View File
@@ -0,0 +1 @@
options mt7915e enable_6ghz=1
@@ -1,54 +0,0 @@
From 184c079c08387d1b0f74de25b63c56304d2156d0 Mon Sep 17 00:00:00 2001
From: bazub <github@zubko.cc>
Date: Tue, 3 Mar 2026 20:31:33 +0000
Subject: [PATCH 1/3] Remove redundant global path var and fix memory
corruption
Organization: Wires
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/conf.c | 13 ++-----------
1 file changed, 2 insertions(+), 11 deletions(-)
diff --git a/src/conf.c b/src/conf.c
index d0abb61d..6e8ec834 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -121,9 +121,6 @@ static uev_t etcw;
static TAILQ_HEAD(, conf_change) conf_change_list = TAILQ_HEAD_INITIALIZER(conf_change_list);
-static char *path;
-static char *shell;
-
static int parse_conf(char *file, int is_rcsd);
static void drop_changes(void);
@@ -377,8 +374,6 @@ void conf_parse_cmdline(int argc, char *argv[])
fstab = strdup(ptr);
finit_conf = strdup(FINIT_CONF);
finit_rcsd = strdup(FINIT_RCSD);
- path = getenv("PATH");
- shell = getenv("SHELL");
for (int i = 1; i < argc; i++)
parse_arg(argv[i]);
@@ -404,13 +399,9 @@ void conf_reset_env(void)
free(node);
}
- if (path)
- setenv("PATH", path, 1);
- else
+ if (!getenv("PATH"))
setenv("PATH", _PATH_STDPATH, 1);
- if (shell)
- setenv("SHELL", shell, 1);
- else
+ if (!getenv("SHELL"))
setenv("SHELL", _PATH_BSHELL, 1);
setenv("LOGNAME", "root", 1);
setenv("USER", "root", 1);
--
2.43.0
@@ -0,0 +1,86 @@
From 4a53f610cd05c2aba3da770384460f7e66488ff5 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 11 May 2026 13:55:11 +0200
Subject: [PATCH 1/2] service: clean stale pidfile after unclean daemon exit
Organization: Wires
With `pid:!/path` Finit does not manage the file -- the daemon
creates it on start and removes it on graceful exit. If the daemon
dies before cleanup (SIGKILL, OOM, segfault, exit during startup)
the file lingers and can block the next instance from starting,
e.g. dbus-daemon refuses with EEXIST and the restart loop fails.
Remove the file when it still names the just-reaped PID and that
PID is no longer alive (the liveness check guards against reuse).
Called from service_cleanup(), and from service_monitor()'s
forking+starting branch where cleanup was previously skipped.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/service.c | 36 +++++++++++++++++++++++++++++++++++-
1 file changed, 35 insertions(+), 1 deletion(-)
diff --git a/src/service.c b/src/service.c
index 7ed4fceb..e930c4fd 100644
--- a/src/service.c
+++ b/src/service.c
@@ -1120,6 +1120,35 @@ static void service_notify_stop(svc_t *svc)
}
}
+/*
+ * Drop a daemon-owned (pid:!) pidfile if it still names the just-reaped
+ * PID and that PID is gone. The liveness check guards against reuse.
+ */
+static void service_clean_pidfile(svc_t *svc, pid_t reaped)
+{
+ pid_t pid;
+ char *fn;
+
+ if (reaped <= 1)
+ return;
+
+ fn = pid_file(svc);
+ if (!fn)
+ return;
+
+ pid = pid_file_read(fn);
+ if (pid != reaped || pid_alive(pid))
+ return;
+
+ if (remove(fn) && errno != ENOENT) {
+ logit(LOG_CRIT, "Failed removing stale service %s pidfile %s",
+ svc_ident(svc, NULL, 0), fn);
+ return;
+ }
+
+ dbg("Removed stale service %s pidfile %s", svc_ident(svc, NULL, 0), fn);
+}
+
/*
* Clean up any lingering state from dead/killed services
*/
@@ -1137,6 +1166,8 @@ static void service_cleanup(svc_t *svc)
if (remove(fn) && errno != ENOENT)
logit(LOG_CRIT, "Failed removing service %s pidfile %s",
svc_ident(svc, NULL, 0), fn);
+ } else if (svc->pidfile[0] == '!') {
+ service_clean_pidfile(svc, svc->pid);
}
/*
@@ -2405,7 +2436,10 @@ void service_monitor(pid_t lost, int status)
if (svc_is_forking(svc)) {
/* Likely start script exiting */
if (svc_is_starting(svc)) {
- svc->pid = 0; /* Expect no more activity from this one */
+ /* Daemon died before clearing 'starting'; drop any stale pidfile. */
+ service_clean_pidfile(svc, lost);
+ svc->oldpid = lost; /* So service_retry() logs the real PID */
+ svc->pid = 0; /* Expect no more activity from this one */
goto cont;
}
--
2.43.0
@@ -1,318 +0,0 @@
From 662293e194811213b9b387163dfe8499e3300ccf Mon Sep 17 00:00:00 2001
From: bazub <github@zubko.cc>
Date: Fri, 6 Mar 2026 20:36:23 +0000
Subject: [PATCH 2/3] Use explicit plugin names to prevent subtle macro
processing bugs
Organization: Wires
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
plugins/alsa-utils.c | 6 +++---
plugins/bootmisc.c | 2 +-
plugins/dbus.c | 4 ++--
plugins/hook-scripts.c | 2 +-
plugins/modprobe.c | 2 +-
plugins/modules-load.c | 2 +-
plugins/netlink.c | 2 +-
plugins/pidfile.c | 2 +-
plugins/procps.c | 4 ++--
plugins/resolvconf.c | 2 +-
plugins/rtc.c | 6 +++---
plugins/sys.c | 2 +-
plugins/tty.c | 1 +
plugins/urandom.c | 6 +++---
plugins/usr.c | 2 +-
plugins/x11-common.c | 4 ++--
16 files changed, 25 insertions(+), 24 deletions(-)
diff --git a/plugins/alsa-utils.c b/plugins/alsa-utils.c
index 6b2c3603..a8a967b0 100644
--- a/plugins/alsa-utils.c
+++ b/plugins/alsa-utils.c
@@ -38,7 +38,7 @@
static void save(void *arg)
{
if (rescue) {
- dbg("Skipping %s plugin in rescue mode.", __FILE__);
+ dbg("Skipping %s plugin in rescue mode.", "alsa-utils");
return;
}
@@ -51,7 +51,7 @@ static void save(void *arg)
static void restore(void *arg)
{
if (rescue) {
- dbg("Skipping %s plugin in rescue mode.", __FILE__);
+ dbg("Skipping %s plugin in rescue mode.", "alsa-utils");
return;
}
@@ -62,7 +62,7 @@ static void restore(void *arg)
}
static plugin_t plugin = {
- .name = __FILE__,
+ .name = "alsa-utils",
.hook[HOOK_BASEFS_UP] = { .cb = restore },
.hook[HOOK_SHUTDOWN] = { .cb = save }
};
diff --git a/plugins/bootmisc.c b/plugins/bootmisc.c
index 701f73f0..a8ba3808 100644
--- a/plugins/bootmisc.c
+++ b/plugins/bootmisc.c
@@ -172,7 +172,7 @@ static void setup(void *arg)
}
static plugin_t plugin = {
- .name = __FILE__,
+ .name = "bootmisc",
.hook[HOOK_MOUNT_POST] = { .cb = clean },
.hook[HOOK_BASEFS_UP] = { .cb = setup },
.depends = { "pidfile" },
diff --git a/plugins/dbus.c b/plugins/dbus.c
index bbf55bc2..a8a155a1 100644
--- a/plugins/dbus.c
+++ b/plugins/dbus.c
@@ -106,7 +106,7 @@ static void setup(void *arg)
char *cmd;
if (rescue) {
- dbg("Skipping %s plugin in rescue mode.", __FILE__);
+ dbg("Skipping %s plugin in rescue mode.", "dbus");
return;
}
@@ -164,7 +164,7 @@ static void setup(void *arg)
}
static plugin_t plugin = {
- .name = __FILE__,
+ .name = "dbus",
.hook[HOOK_SVC_PLUGIN] = { .cb = setup },
};
diff --git a/plugins/hook-scripts.c b/plugins/hook-scripts.c
index 9aa78173..e75808c5 100644
--- a/plugins/hook-scripts.c
+++ b/plugins/hook-scripts.c
@@ -79,7 +79,7 @@ static void hscript_shutdown(void *arg)
}
static plugin_t plugin = {
- .name = __FILE__,
+ .name = "hook-scripts",
.hook[HOOK_BANNER] = { .cb = hscript_banner },
.hook[HOOK_ROOTFS_UP] = { .cb = hscript_rootfs_up },
.hook[HOOK_MOUNT_ERROR] = { .cb = hscript_mount_error },
diff --git a/plugins/modprobe.c b/plugins/modprobe.c
index b6b7e7bb..e52bf228 100644
--- a/plugins/modprobe.c
+++ b/plugins/modprobe.c
@@ -228,7 +228,7 @@ static void coldplug(void *arg)
}
static plugin_t plugin = {
- .name = __FILE__,
+ .name = "modprobe",
.hook[HOOK_BASEFS_UP] = { .cb = coldplug },
.depends = { "bootmisc", }
};
diff --git a/plugins/modules-load.c b/plugins/modules-load.c
index 53aef82f..e2e45c72 100644
--- a/plugins/modules-load.c
+++ b/plugins/modules-load.c
@@ -213,7 +213,7 @@ static void load(void *arg)
}
static plugin_t plugin = {
- .name = __FILE__,
+ .name = "modules-load",
.hook[HOOK_SVC_PLUGIN] = { .cb = load },
};
diff --git a/plugins/netlink.c b/plugins/netlink.c
index a70b01e8..625cbd1b 100644
--- a/plugins/netlink.c
+++ b/plugins/netlink.c
@@ -426,7 +426,7 @@ static void nl_enumerate(void *arg)
}
static plugin_t plugin = {
- .name = __FILE__,
+ .name = "netlink",
.hook[HOOK_SVC_RECONF] = { .cb = nl_reconf },
.hook[HOOK_SVC_PLUGIN] = { .cb = nl_enumerate },
.io = {
diff --git a/plugins/pidfile.c b/plugins/pidfile.c
index ae0fdeea..f1232ab6 100644
--- a/plugins/pidfile.c
+++ b/plugins/pidfile.c
@@ -335,7 +335,7 @@ static void pidfile_init(void *arg)
* SIGSTP:ed (in state PAUSED) waiting for <net/iface/lo>.
*/
static plugin_t plugin = {
- .name = __FILE__,
+ .name = "pidfile",
.hook[HOOK_BASEFS_UP] = { .cb = pidfile_init },
.hook[HOOK_SVC_RECONF] = { .cb = pidfile_reconf },
.depends = { "netlink" }, /* bootmisc depends on us */
diff --git a/plugins/procps.c b/plugins/procps.c
index 826e38ad..5a178d75 100644
--- a/plugins/procps.c
+++ b/plugins/procps.c
@@ -43,7 +43,7 @@ static void setup(void *arg)
glob_t gl;
if (rescue) {
- dbg("Skipping %s plugin in rescue mode.", __FILE__);
+ dbg("Skipping %s plugin in rescue mode.", "procps");
return;
}
@@ -69,7 +69,7 @@ static void setup(void *arg)
}
static plugin_t plugin = {
- .name = __FILE__,
+ .name = "procps",
.hook[HOOK_BASEFS_UP] = {
.cb = setup
},
diff --git a/plugins/resolvconf.c b/plugins/resolvconf.c
index 1ac29dae..b98e9214 100644
--- a/plugins/resolvconf.c
+++ b/plugins/resolvconf.c
@@ -51,7 +51,7 @@ static void setup(void *arg)
}
static plugin_t plugin = {
- .name = __FILE__,
+ .name = "resolvconf",
.hook[HOOK_BASEFS_UP] = {
.cb = setup
},
diff --git a/plugins/rtc.c b/plugins/rtc.c
index faf69415..cf734763 100644
--- a/plugins/rtc.c
+++ b/plugins/rtc.c
@@ -236,7 +236,7 @@ static void rtc_save(void *arg)
int fd, rc = 0;
if (rescue) {
- dbg("Skipping %s plugin in rescue mode.", __FILE__);
+ dbg("Skipping %s plugin in rescue mode.", "rtc");
return;
}
@@ -266,7 +266,7 @@ static void rtc_restore(void *arg)
int fd, rc = 0;
if (rescue) {
- dbg("Skipping %s plugin in rescue mode.", __FILE__);
+ dbg("Skipping %s plugin in rescue mode.", "rtc");
return;
}
@@ -321,7 +321,7 @@ static void update(uev_t *w, void *arg, int events)
static plugin_t plugin = {
- .name = __FILE__,
+ .name = "rtc",
.hook[HOOK_BASEFS_UP] = {
.cb = rtc_restore
},
diff --git a/plugins/sys.c b/plugins/sys.c
index 438fdfd5..484adc05 100644
--- a/plugins/sys.c
+++ b/plugins/sys.c
@@ -180,7 +180,7 @@ static void sys_init(void *arg)
}
static plugin_t plugin = {
- .name = __FILE__,
+ .name = "sys",
.hook[HOOK_BASEFS_UP] = { .cb = sys_init },
.depends = { "bootmisc", },
};
diff --git a/plugins/tty.c b/plugins/tty.c
index b3255f9f..c6a750b0 100644
--- a/plugins/tty.c
+++ b/plugins/tty.c
@@ -43,6 +43,7 @@
static void tty_watcher(void *arg, int fd, int events);
static plugin_t plugin = {
+ .name = "tty",
.io = {
.cb = tty_watcher,
.flags = PLUGIN_IO_READ,
diff --git a/plugins/urandom.c b/plugins/urandom.c
index 410d0660..9bb6252b 100644
--- a/plugins/urandom.c
+++ b/plugins/urandom.c
@@ -87,7 +87,7 @@ static void setup(void *arg)
int fd, err;
if (rescue) {
- dbg("Skipping %s plugin in rescue mode.", __FILE__);
+ dbg("Skipping %s plugin in rescue mode.", "urandom");
return;
}
@@ -188,7 +188,7 @@ static void save(void *arg)
mode_t prev;
if (rescue) {
- dbg("Skipping %s plugin in rescue mode.", __FILE__);
+ dbg("Skipping %s plugin in rescue mode.", "urandom");
return;
}
@@ -202,7 +202,7 @@ static void save(void *arg)
}
static plugin_t plugin = {
- .name = __FILE__,
+ .name = "urandom",
.hook[HOOK_BASEFS_UP] = { .cb = setup },
.hook[HOOK_SHUTDOWN] = { .cb = save },
.depends = { "bootmisc", }
diff --git a/plugins/usr.c b/plugins/usr.c
index d30d9440..496facc2 100644
--- a/plugins/usr.c
+++ b/plugins/usr.c
@@ -104,7 +104,7 @@ static void usr_init(void *arg)
}
static plugin_t plugin = {
- .name = __FILE__,
+ .name = "usr",
.hook[HOOK_BASEFS_UP] = { .cb = usr_init },
.depends = { "bootmisc", },
};
diff --git a/plugins/x11-common.c b/plugins/x11-common.c
index f65331a0..75825a36 100644
--- a/plugins/x11-common.c
+++ b/plugins/x11-common.c
@@ -39,7 +39,7 @@
static void setup(void *arg)
{
if (rescue) {
- dbg("Skipping %s plugin in rescue mode.", __FILE__);
+ dbg("Skipping %s plugin in rescue mode.", "x11-common");
return;
}
@@ -48,7 +48,7 @@ static void setup(void *arg)
}
static plugin_t plugin = {
- .name = __FILE__,
+ .name = "x11-common",
.hook[HOOK_SVC_PLUGIN] = { .cb = setup },
};
--
2.43.0
@@ -0,0 +1,50 @@
From 30f2ca3b2e64bce7db1e2d9dcb37a06d53e0b6bf Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 11 May 2026 17:08:25 +0200
Subject: [PATCH 2/2] service: log signal name and core dumps in death message
Organization: Wires
Replace the bare signal number ("by signal: 9") with the symbolic
name ("killed by SIGKILL") and annotate when the kernel wrote a
core:("killed by SIGSEGV, core dumped"). Makes the restart line
self-explanatory and gives operators a strong breadcrumb when a
daemon dies unexpectedly.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/service.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/src/service.c b/src/service.c
index e930c4fd..127e0099 100644
--- a/src/service.c
+++ b/src/service.c
@@ -2828,13 +2828,18 @@ static void service_retry(svc_t *svc)
timeout = ((*restart_cnt) <= (svc->restart_max / 2)) ? 2000 : 5000;
/* If a longer timeout was specified in the conf, use that instead. */
svc->restart_tmo = max(svc->restart_tmo, timeout);
- logit(LOG_CONSOLE|LOG_WARNING, "Service %s[%d] died (%s%d), restarting (retry in %d msec) (attempt: %d/%d)",
- svc_ident(svc, NULL, 0), svc->oldpid,
- WIFEXITED(svc->status) ? "with exit status: " : "by signal: ",
- WIFEXITED(svc->status) ? WEXITSTATUS(svc->status) : WTERMSIG(svc->status),
- svc->restart_tmo,
- *restart_cnt,
- svc->restart_max);
+ if (WIFEXITED(svc->status))
+ logit(LOG_CONSOLE|LOG_WARNING,
+ "Service %s[%d] died (exit status: %d), restarting (retry in %d msec) (attempt: %d/%d)",
+ svc_ident(svc, NULL, 0), svc->oldpid, WEXITSTATUS(svc->status),
+ svc->restart_tmo, *restart_cnt, svc->restart_max);
+ else
+ logit(LOG_CONSOLE|LOG_WARNING,
+ "Service %s[%d] died (killed by %s%s), restarting (retry in %d msec) (attempt: %d/%d)",
+ svc_ident(svc, NULL, 0), svc->oldpid,
+ sig_name(WTERMSIG(svc->status)),
+ WCOREDUMP(svc->status) ? ", core dumped" : "",
+ svc->restart_tmo, *restart_cnt, svc->restart_max);
svc_unblock(svc);
service_step(svc);
--
2.43.0
@@ -1,66 +0,0 @@
From c01faef99b7e4ff9c39f29ad5648db61a4742539 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Thu, 19 Mar 2026 06:37:50 +0100
Subject: [PATCH 3/3] service: clear condition before stopping rdeps on reload
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Wires
When a service without SIGHUP reload support (noreload) is touched and
'initctl reload' is called, service_update_rdeps() correctly identifies
its reverse dependencies but only marks them dirty. It does not clear
the service's condition, so when service_step_all() runs:
- rdeps supporting SIGHUP hit the sm_in_reload() guard and break early,
left running while their dependency is being killed.
- rdeps without SIGHUP support may receive SIGTERM too late, after the
dependency has already died and broken their connection, causing them
to exit from RUNNING state and have their restart counter incremented.
Fix by calling cond_clear() on the service's condition immediately in
service_update_rdeps(), before service_step_all() runs. cond_clear()
calls cond_update() which calls service_step() inline on all affected
services, which see COND_OFF and transition to STOPPING_STATE — all
before SIGTERM is ever sent to the dependency itself.
This mirrors the pattern already used in api.c:do_reload() for direct
'initctl reload <svc>' calls.
Fixes: avahi/mdns stop causing mdns-alias restart counter increment
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/service.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/src/service.c b/src/service.c
index b2c6c15b..016b5d2f 100644
--- a/src/service.c
+++ b/src/service.c
@@ -2418,7 +2418,21 @@ void service_update_rdeps(void)
if (!svc_is_noreload(svc))
continue; /* Yup, no need to stop start rdeps */
- svc_mark_affected(mkcond(svc, cond, sizeof(cond)));
+ /*
+ * Clear the condition immediately, before service_step_all()
+ * runs. cond_clear() calls cond_update() which calls
+ * service_step() on all affected services right now. Those
+ * services see COND_OFF and get service_stop() called,
+ * transitioning to STOPPING_STATE before we ever send SIGTERM
+ * to this service. Without this, the condition is only cleared
+ * after the service dies, by which time reverse-dependencies
+ * may have already crashed due to the lost connection.
+ * See also: api.c do_reload() which does the same for direct
+ * 'initctl reload <svc>' calls.
+ */
+ mkcond(svc, cond, sizeof(cond));
+ cond_clear(cond);
+ svc_mark_affected(cond);
}
}
--
2.43.0
+1 -1
View File
@@ -1,5 +1,5 @@
# From https://github.com/troglobit/finit/releases/
sha256 f0894cd8b79ce030fdc656600208ddb0b994364f86ebad066de2e005e5e18a35 finit-4.16.tar.gz
sha256 ca8b489a0ed99c17c0288e9e65e325a8f14af3734dfecf58f516c0a6f884e903 finit-4.17.tar.gz
# Locally calculated
sha256 868cb6c5414933a48db11186042cfe65c87480d326734bc6cf0e4b19b4a2e52a LICENSE
+1 -1
View File
@@ -4,7 +4,7 @@
#
################################################################################
FINIT_VERSION = 4.16
FINIT_VERSION = 4.17
FINIT_SITE = https://github.com/troglobit/finit/releases/download/$(FINIT_VERSION)
FINIT_LICENSE = MIT
FINIT_LICENSE_FILES = LICENSE
+1 -1
View File
@@ -1,2 +1,2 @@
sha256 dcd639c77689c432e84e63267202c00958fb1032e066ae355e3cbc68d9fcd063 mcd-2.3.tar.gz
sha256 896c455c1a013a153cbf3186b5f87b7a3344b8939603c0f09e534de714a32e65 mcd-2.4.tar.gz
sha256 99a0480db163445c5a1a5bf7f85bc37cbb5be8c40e9e441291ad78e8d4252d0b LICENSE
+1 -1
View File
@@ -4,7 +4,7 @@
#
################################################################################
MCD_VERSION = 2.3
MCD_VERSION = 2.4
MCD_SITE = https://github.com/kernelkit/mcd/releases/download/v$(MCD_VERSION)
MCD_LICENSE = BSD-3-Clause
MCD_LICENSE_FILES = LICENSE
@@ -0,0 +1,309 @@
From ccd5fe71878cc3eeea2a3137c7b8d5715e3f4253 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Thu, 9 Apr 2026 11:09:51 +0200
Subject: [PATCH] ethtool: Add --json support for -T (show-time-stamping)
Organization: Wires
Wire up JSON output for `ethtool -T`:
- Mark the -T command with .json = true in the command table
- Wrap tsinfo_reply_cb output in open/close_json_object, use
print_string for the header, and handle the PHC index/none
case with proper JSON primitives
- Convert tsinfo_dump_list to open a JSON array (keyed by the
new json_key parameter) and close it on return; update callers
in tsinfo.c and tsconfig.c with appropriate keys
- Convert tsinfo_dump_cb to use print_string(PRINT_ANY) so
each set bit is emitted as a JSON array element in JSON mode
and as an indented text line in plain mode
- Wrap the netlink request in nl_tsinfo with new_json_obj /
delete_json_obj
Example output on a Marvell 88e6341 (Topaz) switch (lan0):
$ ethtool --json -T lan0 | jq
[
{
"ifname": "lan0",
"capabilities": [
"hardware-transmit",
"hardware-receive",
"software-receive",
"software-system-clock",
"hardware-raw-clock"
],
"hwtstamp-provider-index": 0,
"hwtstamp-provider-qualifier": "Precise (IEEE 1588 quality)",
"tx-types": [
"off",
"on"
],
"rx-filters": [
"none",
"ptpv2-l4-event",
"ptpv2-l4-sync",
"ptpv2-l4-delay-req",
"ptpv2-l2-event",
"ptpv2-l2-sync",
"ptpv2-l2-delay-req",
"ptpv2-event",
"ptpv2-sync",
"ptpv2-delay-req"
]
}
]
Example output on a Qemu VM with e1000 NIC (e1):
$ ethtool --json -T e1 | jq
[
{
"ifname": "e1",
"capabilities": [
"software-transmit",
"software-receive",
"software-system-clock"
],
"phc-index": -1,
"tx-types": [],
"rx-filters": []
}
]
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
ethtool.c | 1 +
netlink/ts.h | 2 +-
netlink/tsconfig.c | 6 +--
netlink/tsinfo.c | 106 ++++++++++++++++++++++++++++++---------------
4 files changed, 75 insertions(+), 40 deletions(-)
diff --git a/ethtool.c b/ethtool.c
index 9c8a542..f845dae 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -5985,6 +5985,7 @@ static const struct option args[] = {
},
{
.opts = "-T|--show-time-stamping",
+ .json = true,
.func = do_tsinfo,
.nlfunc = nl_tsinfo,
.help = "Show time stamping capabilities",
diff --git a/netlink/ts.h b/netlink/ts.h
index 9442b44..07f140a 100644
--- a/netlink/ts.h
+++ b/netlink/ts.h
@@ -17,6 +17,6 @@ int tsinfo_qualifier_parser(struct nl_context *nlctx,
void *dest);
int tsinfo_dump_list(struct nl_context *nlctx, const struct nlattr *attr,
const char *label, const char *if_empty,
- unsigned int stringset_id);
+ unsigned int stringset_id, const char *json_key);
#endif /* ETHTOOL_NETLINK_TS_H__ */
diff --git a/netlink/tsconfig.c b/netlink/tsconfig.c
index d427c7b..aab9859 100644
--- a/netlink/tsconfig.c
+++ b/netlink/tsconfig.c
@@ -52,19 +52,19 @@ int tsconfig_reply_cb(const struct nlmsghdr *nlhdr, void *data)
ret = tsinfo_dump_list(nlctx, tb[ETHTOOL_A_TSCONFIG_TX_TYPES],
"Hardware Transmit Timestamp Mode", " none",
- ETH_SS_TS_TX_TYPES);
+ ETH_SS_TS_TX_TYPES, "tx-types");
if (ret < 0)
return err_ret;
ret = tsinfo_dump_list(nlctx, tb[ETHTOOL_A_TSCONFIG_RX_FILTERS],
"Hardware Receive Filter Mode", " none",
- ETH_SS_TS_RX_FILTERS);
+ ETH_SS_TS_RX_FILTERS, "rx-filters");
if (ret < 0)
return err_ret;
ret = tsinfo_dump_list(nlctx, tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS],
"Hardware Flags", " none",
- ETH_SS_TS_FLAGS);
+ ETH_SS_TS_FLAGS, "hwtstamp-flags");
if (ret < 0)
return err_ret;
diff --git a/netlink/tsinfo.c b/netlink/tsinfo.c
index 187c3ad..da64b50 100644
--- a/netlink/tsinfo.c
+++ b/netlink/tsinfo.c
@@ -52,6 +52,7 @@ int tsinfo_show_hwprov(const struct nlattr *nest)
return 0;
}
+
static int tsinfo_show_stats(const struct nlattr *nest)
{
const struct nlattr *tb[ETHTOOL_A_TS_STAT_MAX + 1] = {};
@@ -109,39 +110,57 @@ err_close_stats:
static void tsinfo_dump_cb(unsigned int idx, const char *name, bool val,
void *data __maybe_unused)
{
+ char buf[16];
+
if (!val)
return;
- if (name)
- printf("\t%s\n", name);
- else
- printf("\tbit%u\n", idx);
+ if (!name) {
+ snprintf(buf, sizeof(buf), "bit%u", idx);
+ name = buf;
+ }
+ print_string(PRINT_ANY, NULL, "\t%s\n", name);
}
int tsinfo_dump_list(struct nl_context *nlctx, const struct nlattr *attr,
const char *label, const char *if_empty,
- unsigned int stringset_id)
+ unsigned int stringset_id, const char *json_key)
{
const struct stringset *strings = NULL;
- int ret;
+ bool empty;
+ int ret = 0;
- printf("%s:", label);
- ret = 0;
- if (!attr || bitset_is_empty(attr, false, &ret)) {
- printf("%s\n", if_empty);
- return ret;
- }
- putchar('\n');
- if (ret < 0)
- return ret;
+ empty = !attr || bitset_is_empty(attr, false, &ret);
- if (bitset_is_compact(attr)) {
- ret = netlink_init_ethnl2_socket(nlctx);
+ if (!is_json_context()) {
+ printf("%s:", label);
+ if (empty) {
+ printf("%s\n", if_empty);
+ return ret;
+ }
+ putchar('\n');
+ if (ret < 0)
+ return ret;
+ } else {
if (ret < 0)
return ret;
- strings = global_stringset(stringset_id, nlctx->ethnl2_socket);
+ open_json_array(json_key, "");
+ }
+
+ if (!empty) {
+ if (bitset_is_compact(attr)) {
+ ret = netlink_init_ethnl2_socket(nlctx);
+ if (ret < 0)
+ goto out_close;
+ strings = global_stringset(stringset_id, nlctx->ethnl2_socket);
+ }
+ ret = walk_bitset(attr, strings, tsinfo_dump_cb, NULL);
}
- return walk_bitset(attr, strings, tsinfo_dump_cb, NULL);
+
+out_close:
+ if (is_json_context())
+ close_json_array("");
+ return ret;
}
int tsinfo_reply_cb(const struct nlmsghdr *nlhdr, void *data)
@@ -163,47 +182,59 @@ int tsinfo_reply_cb(const struct nlmsghdr *nlhdr, void *data)
return err_ret;
if (silent)
- putchar('\n');
- printf("Time stamping parameters for %s:\n", nlctx->devname);
+ print_nl();
+
+ open_json_object(NULL);
+ print_string(PRINT_ANY, "ifname",
+ "Time stamping parameters for %s:\n", nlctx->devname);
ret = tsinfo_dump_list(nlctx, tb[ETHTOOL_A_TSINFO_TIMESTAMPING],
- "Capabilities", "", ETH_SS_SOF_TIMESTAMPING);
+ "Capabilities", "", ETH_SS_SOF_TIMESTAMPING,
+ "capabilities");
if (ret < 0)
- return err_ret;
+ goto err_close_dev;
if (tb[ETHTOOL_A_TSINFO_HWTSTAMP_PROVIDER]) {
ret = tsinfo_show_hwprov(tb[ETHTOOL_A_TSINFO_HWTSTAMP_PROVIDER]);
if (ret < 0)
- return err_ret;
-
+ goto err_close_dev;
} else if (tb[ETHTOOL_A_TSINFO_PHC_INDEX]) {
- printf("PTP Hardware Clock: ");
- printf("%d\n",
- mnl_attr_get_u32(tb[ETHTOOL_A_TSINFO_PHC_INDEX]));
+ print_uint(PRINT_ANY, "phc-index",
+ "PTP Hardware Clock: %d\n",
+ mnl_attr_get_u32(tb[ETHTOOL_A_TSINFO_PHC_INDEX]));
} else {
- printf("PTP Hardware Clock: ");
- printf("none\n");
+ if (is_json_context())
+ print_int(PRINT_JSON, "phc-index", NULL, -1);
+ else
+ printf("PTP Hardware Clock: none\n");
}
ret = tsinfo_dump_list(nlctx, tb[ETHTOOL_A_TSINFO_TX_TYPES],
"Hardware Transmit Timestamp Modes", " none",
- ETH_SS_TS_TX_TYPES);
+ ETH_SS_TS_TX_TYPES, "tx-types");
if (ret < 0)
- return err_ret;
+ goto err_close_dev;
ret = tsinfo_dump_list(nlctx, tb[ETHTOOL_A_TSINFO_RX_FILTERS],
"Hardware Receive Filter Modes", " none",
- ETH_SS_TS_RX_FILTERS);
+ ETH_SS_TS_RX_FILTERS, "rx-filters");
if (ret < 0)
- return err_ret;
+ goto err_close_dev;
if (tb[ETHTOOL_A_TSINFO_STATS]) {
ret = tsinfo_show_stats(tb[ETHTOOL_A_TSINFO_STATS]);
if (ret < 0)
- return err_ret;
+ goto err_close_dev;
}
+ if (!silent)
+ print_nl();
+ close_json_object();
return MNL_CB_OK;
+
+err_close_dev:
+ close_json_object();
+ return err_ret;
}
int tsinfo_qualifier_parser(struct nl_context *nlctx,
@@ -271,5 +302,8 @@ int nl_tsinfo(struct cmd_context *ctx)
if (ret < 0)
return ret;
- return nlsock_send_get_request(nlsk, tsinfo_reply_cb);
+ new_json_obj(ctx->json);
+ ret = nlsock_send_get_request(nlsk, tsinfo_reply_cb);
+ delete_json_obj();
+ return ret;
}
--
2.43.0
@@ -1,4 +1,4 @@
From 39ebf709e91a89f59e14ac1d1179df170448d09a Mon Sep 17 00:00:00 2001
From 72ad44e1e215cded7c8bf3209203b5d1b32e179d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= <lazzer@gmail.com>
Date: Tue, 27 Jan 2026 22:54:59 +0100
Subject: [PATCH 1/3] Libyang4 compat
@@ -1,4 +1,4 @@
From 6f7ff746c4016ea6e6d81c7abad088f5a86f8fbf Mon Sep 17 00:00:00 2001
From 80634c421c695b191c54d94feda6fb6c32c17eb4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= <lazzer@gmail.com>
Date: Fri, 30 Jan 2026 13:00:12 +0100
Subject: [PATCH 2/3] Failed without c++ 23, this adds compatibility layer
@@ -67,10 +67,10 @@ index 97c7460079..8fe8b10c05 100644
#define zassert assert
diff --git a/lib/zlog.c b/lib/zlog.c
index 157f3323cb..7e7b6f0c25 100644
index eb9b1c236b..b1d23a08d9 100644
--- a/lib/zlog.c
+++ b/lib/zlog.c
@@ -789,6 +789,51 @@ void _zlog_assert_failed(const struct xref_assert *xref, const char *extra, ...)
@@ -792,6 +792,51 @@ void _zlog_assert_failed(const struct xref_assert *xref, const char *extra, ...)
abort();
}
@@ -1,4 +1,4 @@
From 868d13c0982a0633e4144d03776358837d92cd8b Mon Sep 17 00:00:00 2001
From 939a6bd1c38f8fe37236696a862c659b8fa96b07 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Sun, 22 Feb 2026 10:22:06 +0100
Subject: [PATCH 3/3] zebra: don't resolve nexthop via inactive connected route
+5 -23
View File
@@ -1,23 +1,8 @@
From 9ba3bc688c45a0c9e761c6c8bd0be83d6570c9dc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= <lazzer@gmail.com>
Date: Fri, 27 Feb 2026 16:58:12 +0100
Subject: [PATCH] Always log to syslog
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Wires
Signed-off-by: Mattias Walström <lazzer@gmail.com>
---
gpsd/libgpsd_core.c | 13 ++-----------
1 file changed, 2 insertions(+), 11 deletions(-)
diff --git a/gpsd/libgpsd_core.c b/gpsd/libgpsd_core.c
index 982f822b8..c53c64838 100644
--- a/gpsd/libgpsd_core.c
+++ b/gpsd/libgpsd_core.c
@@ -180,17 +180,8 @@ static void gpsd_vlog(const int errlevel,
// this was crazy expensive, just fix the bad log calls
diff -urN gpsd-3.25.orig/gpsd/libgpsd_core.c gpsd-3.25/gpsd/libgpsd_core.c
--- gpsd-3.25.orig/gpsd/libgpsd_core.c 2023-01-10 23:38:26.000000000 +0100
+++ gpsd-3.25/gpsd/libgpsd_core.c 2026-04-22 14:06:09.498017456 +0200
@@ -180,17 +180,8 @@
// this was carzy expensive, just fix the bad log calls
// gps_visibilize(outbuf, outlen, buf, strlen(buf));
- if (getpid() == getsid(getpid())) {
@@ -36,6 +21,3 @@ index 982f822b8..c53c64838 100644
gpsd_release_reporting_lock();
#endif // !SQUELCH_ENABLE
}
--
2.43.0

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