From 426485610985884822246ef3cfdefb18dfd219e2 Mon Sep 17 00:00:00 2001 From: d00f Date: Fri, 14 Aug 2026 15:27:41 +0200 Subject: [PATCH] stp: stop treating a port as an edge once it hears a BPDU 802.1D has a port leave the edge state when a BPDU arrives on it. Here the flag was only ever cleared by the loop latch, root guard, a link coming back, "stp on", "stp off" and the edge command itself, so a port that auto-edged during the three seconds of silence after link-up kept the flag for as long as it stayed up, whatever the neighbour sent. Two things read that flag. The status page prints it, so a port talking to a bridge reported edge 1 and there was no way to tell from the output whether a BPDU had ever arrived. More quietly, stp_topology_change() returns early for an edge port, which is right for a real one and wrong for this: a topology change on such a port was neither counted nor propagated, and port_l2_forget_port() never ran, so what was learned behind it stayed in the table. Only the flag is cleared. The port is not pushed back through the listen period, which would take a working link out of forwarding for a forward delay the first time a neighbour speaks. --- rtl837x_stp.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/rtl837x_stp.c b/rtl837x_stp.c index 04afaa6..7a9c894 100644 --- a/rtl837x_stp.c +++ b/rtl837x_stp.c @@ -451,6 +451,16 @@ void stp_in(void) __banked stp_bpdu_age[port] = 0; + /* A port that hears a BPDU is not an edge port, whatever it decided + * during the silence after the link came up. Only the flag is dropped: + * the port keeps whatever forwarding state the rules below give it, + * rather than being pushed back through the listen period, which would + * black-hole a working link for a forward delay on the first BPDU. The + * flag matters beyond the status page, since stp_topology_change() + * exempts edge ports and so would go on skipping the counter and the + * L2 flush for a port that has a bridge behind it. */ + stp_pflags[port] &= ~STP_PF_OPEREDGE; + if (STP_I->bpdu_type == 0x80) { /* TCN: a downstream bridge reports a topology change. Acknowledge it * on this port so the sender stops repeating; the change itself is