stp: treat a link aggregation group as one entity

Spanning tree so far saw only physical ports. Two ports aggregated towards
the same neighbour look to the protocol like two parallel paths, so it
blocks one of them and cuts the group in half.

Give each of the four groups an STP entity of its own, numbered above the
physical ports. A member port answers to its group: BPDUs arriving on it
are accounted to the entity, the entity's state is written to every member
together, and its BPDUs carry the state of a live member. Ports outside
any group keep behaving exactly as before.

Membership comes from the aggregation tables once a second; when it
changed, the entity's state is reapplied to the new set of members. The
CLI takes lag <1-4> wherever it takes port <n>, the web UI shows a group
as one row, and the saved config keeps the lag form of the commands.
This commit is contained in:
d00f committed 2026-09-09 20:58:35 +02:00
1 parent d3f1069285
commit 02c816647c
4 files changed
+319 -59

No files matched your search

+22
View File
@@ -58,6 +58,28 @@ port set to admit tagged frames only (`ingress <port>t`) never delivers one
to the CPU. `stp_setup()` prints a warning for every STP-enabled port in that
state.
## Link aggregation
A LAG is a port to the protocol, the way the vendor firmware presents it as
Trk1 to Trk4. The four groups are entities alongside the nine physical ports:
they carry their own path cost, priority, edge and guard settings, they hold
their own timers, and they appear as their own rows on the Spanning Tree page.
```
stp lag 1 cost 10000 # the group decides, not its members
stp lag 1 edge off
```
Membership comes from the aggregation registers the `lag` command writes, re-read
once a second, so a group changing under LACP is picked up without any
coordination between the two. A member port is not an STP port of its own:
`stp port <n>` on a member says which group to configure instead. State
changes are written to every member in one register write, since the hardware
has no per-group state, and BPDUs are transmitted through the lowest
member while carrying the group's own port id. Losing one member of a live
LAG is not a topology change; the logical port only goes down with its last
link.
Port states live in `RTL837X_MSTP_STATES (0x5310)`, two bits per port:
`00` disabled, `01` blocking, `10` learning, `11` forwarding. A port in
blocking forwards nothing between ports, but it still sends what the CPU