Updating from 5.3.2 — nothing to re-import
No action was added or renamed, so no rescan: replace the module directory,
chown, reload php-fpm. Reload the page once with a cache bypass — the bundle
changed, and this release changes what the map draws. No template changed.
Layouts, manual links, pins, notes and presets stay where they are.
What will look different immediately: a device pair connected by several
cables is now several lines. On a meshed core that is a visible change, and
View → All parallel links: off puts it back to one line per pair, marked
×N. Nothing is hidden either way — the count is on the line.
Expect one burst of change notifications, once. The baseline the topology
diff compares against knows one key per device pair; from this release on
it knows one per cable. On the first refresh after the upgrade the old entry
is carried over to one member of each bundle, and the remaining members are
formally new — a 4×10G LAG therefore announces another cable … — 4 parallel
now three times. Once, per user, then it is quiet. Nothing is wrong, and
nothing was rediscovered: the map simply counts cables now where it used to
count pairs.
Thanks
@christos-diamantis reported
#20 and then
built it: #21 is
his, including the tests that pin the matching rules. His default — fan out
when zoomed in, bundle in the overview — replaced the one the roadmap had
sketched, and it is the better answer.
A reporter who wrote by email sent the screenshots behind four of the
fixes below: the 4.3 Gb/s that is a counter ceiling, red links on a switch
whose ports are merely unused, a port named on one side only, and a map where
30 hosts and 127 unmonitored neighbours piled up on each other.
Added
-
Parallel links (LAG, bonding, several cables) are drawn as what they are.
Until now every pair of devices had exactly one edge: a second LLDP/CDP
report for the same pair was merged into the first, first-wins. A 2×10G LAG
showed one member's port and one member's counters, and a failed member was
invisible. Now every cable is its own edge, with its own ports, traffic,
utilisation and state.- Fanned out (zoomed in): one curve per member, side by side, each in its
own weathermap colour; port labels at both ends stack into a small list.
A member that stops being reported while its siblings still are is drawn
red and dashed among the live ones. - Bundled (zoomed out): one line marked
×N(only slightly thicker —
the label carries the count), total traffic against total capacity of
the live members, amber glow while a member is down. - View → All parallel links: on / off. On (default) fans out from 60 %
zoom upwards and bundles below. Off always draws one line per device
pair with×N— for meshed cores with six or seven cables between
every pair, where a fan turns into a thicket at any zoom. - Clicking a bundle lists its members in the edge panel; a row opens that
member. Path highlighting marks the whole bundle. - The topology diff reports a lost or added member on its own, instead of a
false "port moved". A link that gains a second cable is not reported as
removed and re-added.
- Fanned out (zoomed in): one curve per member, side by side, each in its
-
The dashboard widget keeps one line per device pair — the tile is too small
for a fan — but it counts the cables:×4on the line,×4 (1 down)
when a member is dead, red when all of them are. Without the count the tile
claimed the same thing for a 4×10G bundle as for a single cable, and a
failed member was invisible there — which is the very thing this release
set out to fix. -
"Connected to" — the port a device hangs on, as a column. The hosts table
carries device and port of the far end, and sorts and filters by them. That
turns it into a patch list: which access point sits on which switch port,
printable, and out through the new CSV button. Infrastructure sorts first,
an ageing link is marked with a clock (for a device that is already gone,
the port it hung on last is exactly the question), several cables stay one
line with "+2 more". The table search knowsport:Gi1/0/8as a field. -
CSV export for the hosts table. It existed only in Items mode. Exports
what is on screen — filtered, sorted, visible rows — with device and port in
two separate columns, because a spreadsheet wants to group by switch, and
"Last seen here" as a value one can filter on. -
The port in the connection list of the host panel. One click on the
device, and the list sayseth0 → Gi1/0/8per connection. It survives the
device going away, because edges age instead of vanishing. -
A change notification says which cable. A lost bundle member used to be
announced as "link A ↔ B disappeared", which is false while the other
members carry it. Now: cable core Gi1/0/1 ↔ acc Te1/1/1 gone — 3 of 4 still
up, and when the last one dies, the link is down. A single line keeps the
shorter wording. -
The legend knows the bundle: the
×Nline and the amber glow of a
bundle with a dead cable, drawn with the same symbols the map uses.
How members are matched
Both ends of one cable report it, often with labels that do not compare
("10101" on one side, "GigabitEthernet1/0/1" on the other), and LLDP and CDP
can number the same port differently. A report therefore only opens a new
member when the same device already reported every existing member
over the same protocol on other ports. The number of lines is exact; what
can be wrong with incomparable labels is which far-end port is paired with
which near-end port — never how many cables are drawn.
Changed
-
The ghost filter step is called what it does. "Network gear only" became
"without endpoints", and when nothing can be dropped — because not one
neighbour reports its capabilities, which is normal for CDP — the map says
so once per session instead of leaving a step that looks broken. -
The cluster toggle dims itself when the map has fewer than two host
groups, instead of silently doing nothing. -
The upper limit for LLDP/CDP edges is 6000 instead of 8000. It exists to
prevent a PHP fatal — a white page mid-render — not clutter, and a member
edge costs more than the merged one did: measured 5.9 KB against 4.6 KB,
46 MB against 36 MB at 8000 edges. 6000 restores the headroom the number was
chosen for. It is still far past any readable map, and when it does bite,
the map says so.
Fixed
-
ifSpeed 4294967295is not a link speed. It is 2³²−1, the ceiling of a
32-bit counter: a 10G port reports it and puts the truth inifHighSpeed.
The panel said "0.0 % of 4.3 Gb/s", and every utilisation percentage on such
a link was wrong with it. The value is discarded; withoutifHighSpeedthe
speed stays unknown rather than invented. -
A red link meant the host, not the link. The colour came from the ratio
of down interfaces across both endpoints, so a switch with 17 of 31 ports
unused but administratively up painted every one of its links red — next to
a panel showing 0.00 errors for the actual port. The operational state of
the port the edge hangs on now decides where it is known; the host-wide
ratio survives only as the fallback for edges without a port mapping. -
A port named on one side only. One end showed
29, the otherPort 9—
the reporter's raw ifIndex against the text the neighbour announces. A
resolved neighbour port now takes that interface's ownifName, and a
host's own label wins over what the far side claims about it. -
Layout "auto" stopped reusing an arrangement that covers a third of the
map. With 30 hosts and 127 unmonitored neighbours, the saved positions
covered 30 of 157 drawn nodes and the rest landed in rings around their
reporting switch. Where ghosts outnumber hosts more than two to one, auto
computes a fresh layout and says once why. -
A ghost node is no longer treated as a host in the tooltip, the detail
panel and on its edges: no severity pill, no history request for an id that
belongs to no host. -
A replugged bundle member is reported as moved, not as one cable gone
and another arrived — and no ghost line is left next to the cable it is. -
nt:uplinkfinds its member by port, not by spelling:Gi1/0/2in the
tag matchesGigabitEthernet1/0/2on the edge. -
A bundle counts a cable whose port is down, not only one that stopped
being reported — on the line, in the member list, and in the trunk's colour.
The two counts used to disagree.
Widgets
Their versions move independently of the module: NT Topology 3.2.0 (the
cable count above), NT Health 2.1.2, NT Table 2.1.2, NT KPI 1.0.2
(the generated data access below). NT Items 1.0.0 is unchanged.
And they are not 7.4-only any more. The note that said so came from a
test on 7.0.28 in July, where they registered but stayed on "Loading…".
Re-tested on 7.0.30 with all five on one dashboard: topology, KPI, health,
table and items render, no console errors. What changed in between is not
established — so if they do hang on a 7.0 of yours, that is worth a report
rather than a shrug.
For contributors
-
tools/devnet/— a compose stack with Zabbix 7.0, Postgres and
snmpsim: simulated SNMP devices, one.snmprecfile per device, all
values invented. Everything interesting in this module hangs off SNMP
values, and a bug report can be translated into a file and reproduced in
minutes.npm run ci:snmprecchecks the format, because snmpsim answers a
file it does not understand with "No Such Instance" and no error at all. -
The shared data access in the widgets is generated, not maintained.
window.NtWidgetDatasat byte-identical in four widget files, because the
jsLoader knows no ES modules and a widget cannot import the main module.
ci:parityguarded the copies against each other — but a change was still
a change in four places, and four identically wrong copies would have
passed. The source istools/widget-shared.jsnow,npm run buildwrites
it into the four files, and the gate compares them against it. -
npm run ci:frontend— a gate that reads what the interface says,
without a browser: detail panel, tooltip, ghost filter, layout decision,
bundle label, notification text, legend, and the CSV export. Three bug
reports in September 2026 lived exactly there, and no existing test went red
for any of them, because none had ever looked at the output.