From f1f69e26fdd14885283cff9e02820269defde4f5 Mon Sep 17 00:00:00 2001 From: d00f Date: Tue, 4 Aug 2026 05:30:57 +0200 Subject: [PATCH] stp: do not carry a dropped BPDU's flags over to the next one The Topology Change Acknowledgment is staged in a one-shot variable and consumed when the BPDU is built - but stp_cnf_send() can return before that, when the port is filtered/tripped or its tx-hold budget for this second is spent. The flag then survived and was OR-ed into the next BPDU this switch sent, on whatever port that happened to be. Clear it with the frame it belonged to. --- rtl837x_stp.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/rtl837x_stp.c b/rtl837x_stp.c index bd16597..610dcc7 100644 --- a/rtl837x_stp.c +++ b/rtl837x_stp.c @@ -214,10 +214,16 @@ static void stp_claim_root(void) void stp_cnf_send(uint8_t port) __reentrant { - if (!(stp_pflags[port] & STP_PF_ENABLED) || (stp_pflags[port] & (STP_PF_FILTER | STP_PF_TRIPPED))) + /* A one-shot flag (TCA) belongs to the BPDU we were asked to send: drop + * it with the frame, or it would surface on an unrelated port later. */ + if (!(stp_pflags[port] & STP_PF_ENABLED) || (stp_pflags[port] & (STP_PF_FILTER | STP_PF_TRIPPED))) { + stp_tx_flags_extra = 0; return; - if (!stp_tx_budget[port]) /* tx hold count exhausted for this second */ + } + if (!stp_tx_budget[port]) { /* tx hold count exhausted for this second */ + stp_tx_flags_extra = 0; return; + } stp_tx_budget[port]--; STP_O->stp_addr[0] = 0x01; STP_O->stp_addr[1] = 0x80; STP_O->stp_addr[2] = 0xc2;