stp: accept BPDUs with a protocol version above 2

We only recognised RST BPDUs when the Protocol Version Identifier was
exactly 2, which silently drops every MST BPDU: 802.1s uses version 3
with type 2 and a prefix deliberately laid out to be identical to an RST
BPDU, precisely so that an RSTP bridge can parse it.

802.1D-2004 14.4 spells the rule out - a bridge shall accept a version
identifier of 2 or greater and treat the BPDU as RST, ignoring anything
beyond what it understands. Compare with >= instead of ==. The receive
path already length-checks before touching the body and only reads the
fields common to both formats, so a longer MST body needs no other care.

The two fields are deliberately asymmetric: the Protocol Identifier must
be exactly zero (it is a sanity check), while the version is an extension
point that has to tolerate the future.
This commit is contained in:
d00f
2026-08-18 23:28:35 +02:00
committed by d00f
parent f3c1b7f3ac
commit be520d6716
+7 -2
View File
@@ -337,8 +337,13 @@ void stp_in(void) __banked
if (STP_I->proto) if (STP_I->proto)
return; return;
/* Accept RSTP BPDUs (v2 type 2), legacy Config BPDUs (v0 type 0) and /* Accept RSTP BPDUs (v2 type 2), legacy Config BPDUs (v0 type 0) and
* legacy TCN BPDUs (v0 type 0x80, 4-byte body) */ * legacy TCN BPDUs (v0 type 0x80, 4-byte body).
if (!((STP_I->version == 2 && STP_I->bpdu_type == 2) * Version 2 *or greater*: 802.1D-2004 14.4 requires an RSTP bridge to
* accept a higher Protocol Version and treat it as RST, ignoring what
* it does not understand. MSTP (802.1s) sends version 3 type 2 with a
* prefix deliberately identical to an RST BPDU for exactly this reason;
* insisting on == 2 makes us blind to every MST bridge on the segment. */
if (!((STP_I->version >= 2 && STP_I->bpdu_type == 2)
|| (STP_I->version == 0 || (STP_I->version == 0
&& (STP_I->bpdu_type == 0 || STP_I->bpdu_type == 0x80)))) && (STP_I->bpdu_type == 0 || STP_I->bpdu_type == 0x80))))
return; return;