Skip to content

v0.23.35-beta

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 07 Sep 15:58
· 1 commit to main since this release

fix(topology): read the spanning-tree root instead of guessing it (v0.23.35-beta)

Closes #131.

Reported as the wrong device being marked root: an RB4011 at priority 4096 says
"root bridge: yes", two APs at 8192 say they are not and name the RB4011's MAC,
and the map crowned an AP anyway — consistently, always the same one.

The detection had never worked at all. It looked for a device with no port whose
STP role was 'root', but RouterOS reports the role as 'root-port'. Nothing ever
matched, so the set of devices-with-a-root-port was permanently empty and the
lookup returned the first device in the list. It was not choosing badly; it was
not choosing.

The same mismatch broke link state. Blocking was derived from a role of
'alternate' or 'backup' against values that arrive as 'alternate-port' and
'backup-port', so blocked links were drawn as forwarding — which is the "traffic
connection path" half of the report, since a blocked link shown as live yields a
path that does not exist.

Roles are now normalised on write so both ends of the system share one
vocabulary, and the root is no longer inferred. RouterOS answers it directly:
/interface/bridge/monitor reports whether a bridge is the root and names the root
it sees, which is exactly what the reporter's own screenshots show the device
knowing. That is collected into device_bridges and resolved in
utils/stpRoot.ts with 13 tests.

Two properties of real networks shaped the resolution, both observed on the
development fleet rather than reasoned about:

  • A root belongs to a spanning tree, not to a fleet. Two of four devices
    here legitimately report root at once, being separate bridge domains, so
    roots are resolved per connected component.
  • The root may not be ours. One switch points at priority 8192 on a MAC
    belonging to no device in the inventory. Naming a local device in that case
    is precisely the original bug, so the crown is withheld and the foreign
    bridge id reported instead.

Verified against that fleet: the managed root resolves to the device that claims
it, a self-rooted bridge keeps its own crown, and the switch with an external
root now reports "not ours" where the old logic confidently crowned it — the
reported symptom, reproduced and fixed.

Also adds collectStp to the full sync. It previously ran only on the five-minute
slow poll, so pressing Sync after rewiring did not refresh the map.

Co-Authored-By: Claude Opus 5 noreply@anthropic.com


Container image: ghcr.io/2gt-media-group-llc/mikrotik-manager:0.23.35-beta

Documentation: https://2gt-media-group-llc.github.io/mikrotik-manager/