Commit Graph
10 Commits
Author SHA1 Message Date
DrDoof bdca888ecd stp: use the front panel number as the port ID
The port ID in the BPDUs was the chip port plus one, so on most boards
it did not match the port label, neither on the Spanning Tree page nor
on the neighbour. Send the front panel number instead, and 101 and up
for the LAGs, the same numbers the page already uses for the Port
column. A returned BPDU of our own is mapped back to the port by that
number.

Scenario 66 gives one port a front panel number that differs from its
chip port.
2026-10-28 16:05:12 +01:00
João Silva 970e98f4c5 test/stp: pack host structs like SDCC and cover the edge recovery
Build the harness with -fpack-struct=1 and assert the frame struct sizes,
so the host reads wire bytes the way the firmware lays them out. Add
scenarios for a port that regains edge after a hold, one that heard a BPDU
and stays non-edge, auto-edge switched off, and a captured RouterOS BPDU
fed in on every port, tagged and untagged.
2026-10-27 22:11:24 +01:00
d00f eb51128ec7 stp: a port without carrier does not become the root port
stp_reselect() took every port with fresh information as a candidate, so a
BPDU credited to a port whose carrier the once-a-second link poll had not
seen yet made that port the root port before the port was set up for it.
A candidate now needs its link bit as well; the poll that sees the carrier
a moment later runs the selection again. Scenario 54.
2026-10-27 22:11:24 +01:00
d00f b86fd37eaa stp: pass a topology change on only from a forwarding port
stp_in() propagated the TC flag of any BPDU that did not arrive on an
alternate port, and acknowledged and propagated a TCN from any port, so a
port still in its listen period or held discarding in a dispute could flush
the addresses of every other port and move the topology change counter.
802.1D-2004 17.31 keeps the Topology Change machine in LEARNING until the
port forwards and drops rcvdTc and rcvdTcn there. Both paths now ask for
the forwarding state first; an alternate port is discarding, so the old
check is covered by the new one.

Scenario 53 plays a TC flag and a TCN into a port that is still discarding,
and then into the same port once it forwards. Scenario 51 used a TCN on a
port one tick short of its edge transition as the trigger for the clock it
tests; it now waits for the transition.
2026-10-27 22:11:24 +01:00
d00f b92a773cad test/stp: tag the frames the simulator feeds in
The frame the simulator builds carries a vlan_tag between the RTL tag and the BPDU, but left its TPID zero. stp_in() now takes the body offset from TRAP_RX_BODY(), which reads those two bytes, so it took the untagged branch and parsed the body four bytes early. Writing 0x8100 makes the frame what its layout says it is.
2026-10-27 22:11:24 +01:00
d00f 068e7467af test/stp: stub the RMA action the trap now sets
Reception moved to the RMA trap in main, so rtl837x_stp.c calls trap_rma_set() from stp_setup() and stp_off(). The simulator defines neither, so it does not link. Linking rtl837x_trap.c instead would pull trap_init() and the register primitives it needs, which the simulator does not mock.
2026-10-27 22:11:24 +01:00
DrDoof da4f5058a7 test/stp: declarations first, one statement per line
stp_sim.c declared variables in the middle of the scenarios and put
whole loops and conditions on one line. Each block now starts with its
declarations; an initializer that depends on what happens before it
stays where it was as an assignment. Bodies of if and for are on lines
of their own, functions are separated by an empty line, and lines stay
within 120 columns. The output of stp_sim -v is unchanged.
2026-10-27 22:11:24 +01:00
DrDoof fee4f17bff test/stp: print each scenario heading once
Scenarios 4 and 7 start from the state scenario 3 leaves behind, and 38
from the one 37 leaves, and they called those scenarios for it, so the
headings of 3 and 37 showed up again in the middle of the run. The setup
of 3 and 37 now lives in functions of its own that the scenarios call.
2026-10-27 22:11:24 +01:00
DrDoof e19271fc44 test/stp: build the simulator against the firmware headers
test/stp/shim held hand-written copies of the headers the STP code
includes, and they had drifted: the uIP buffer was 600 bytes instead of
1556, struct machine had three fields, port_ingress_filter_get()
returned a plain uint8_t. The simulator now compiles rtl837x_stp.c and
rtl837x_stp_cli.c the way test/ compiles firmware sources, with the real
headers and sdcc_shim.h forced in, and with the same warnings, including
-Wno-pointer-sign for the string literals passed to cmd_compare(). It
stays on -std=c11: in gnu11 mode glibc defines LITTLE_ENDIAN, which
uip-conf.h names as the byte order, and HTONS() stops swapping. Its own
print_string() and cmd_compare() take the firmware's argument types.
2026-10-27 22:11:24 +01:00
DrDoof aff6ac0923 stp: full RSTP and a reworked Spanning Tree page
* stp: select the root port by cost and block redundant links
* stp: move the protocol to BANK4 and keep the command line in BANK2
* stp: implement the RSTP state machines of 802.1D-2004 clause 17
* stp: counters, more settings and a fuller Spanning Tree page
* stp: make a link aggregation group one port of the RSTP tree
* web: serve the Spanning Tree JSON from BANK4 as well

Kept in BANK1, the larger Spanning Tree page would leave under 1 kB
there for the rest of the web server and every page still to come, so
send_stp() and send_stp_counters() move to httpd/page_stp.c in BANK4
with the protocol, as banked calls, with their own copies of the few output
helpers and of the JSON header, so nothing in BANK4 calls into BANK1
directly or hands it a pointer into its code space. BANK4 takes the
free flash between BANK3 and the web files.

KP_9000_6XHML_X2: BANK1 44336, BANK2 36969, BANK3 11942, BANK4 20965
bytes of 49152.
2026-10-27 22:11:24 +01:00