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

+16 -8
View File
@@ -12,6 +12,10 @@ void stp_defaults(void) __banked;
/* Tick rate of stp_timers(), also used by the web UI. */
#define STP_HZ 50
#define STP_LAG_BASE 10
#define STP_LAG_COUNT 4
#define STP_ENTITIES (STP_LAG_BASE + STP_LAG_COUNT)
/* Bridge identifier as carried in a BPDU (priority, extension, MAC). */
struct bridge {
uint8_t prio;
@@ -36,15 +40,19 @@ extern __xdata uint8_t stp_txhold;
#define STP_PF_OPEREDGE 0x40 /* runtime: port went forwarding as an edge */
#define STP_PF_TRIPPED 0x80 /* runtime: disabled by BPDU guard */
extern __xdata uint8_t stp_pflags[10];
extern __xdata uint32_t stp_pcost[10];
extern __xdata uint8_t stp_pprio[10];
extern __xdata uint8_t stp_pp2p[10];
extern __xdata uint8_t stp_pflags[STP_ENTITIES];
extern __xdata uint32_t stp_pcost[STP_ENTITIES]; /* path cost; 0 = auto (20000) */
extern __xdata uint8_t stp_pprio[STP_ENTITIES];
extern __xdata uint8_t stp_pp2p[STP_ENTITIES];
extern __xdata uint8_t stp_ent_of[10]; /* the STP entity a port answers to: itself, or its lag */
extern __xdata uint16_t stp_lag_mask[STP_LAG_COUNT]; /* member ports of each lag; 0 = not part of STP */
extern __xdata struct bridge stp_dbridge[10];
extern __xdata uint16_t stp_dpid[10];
extern __xdata uint32_t stp_dcost[10];
extern __xdata uint16_t stp_bpdu_age[10];
/* Last-heard designated info per port (from received BPDUs); consult
* stp_bpdu_age to decide whether it is still current. */
extern __xdata struct bridge stp_dbridge[STP_ENTITIES];
extern __xdata uint16_t stp_dpid[STP_ENTITIES];
extern __xdata uint32_t stp_dcost[STP_ENTITIES];
extern __xdata uint16_t stp_bpdu_age[STP_ENTITIES]; /* ticks since a BPDU was heard */
extern __xdata struct bridge root_bridge;
extern __xdata uint32_t root_bridge_cost;