diff --git a/doc/stp.md b/doc/stp.md index d3d2028..baf1496 100644 --- a/doc/stp.md +++ b/doc/stp.md @@ -64,6 +64,17 @@ by a static L2 multicast entry (`port_l2mc_set()`), one per VLAN in use: transparency an unmanaged switch is expected to have, so a surrounding spanning tree can span *through* this device. +Because delivery rides the forward action, a BPDU is an ordinary frame to the +ingress pipeline and is subject to the port's acceptable-frame-type setting. +BPDUs are untagged by definition, so a port configured to admit tagged frames +only (`ingress t`) will never deliver one: a port left on the default +auto edge turns edge after three seconds of silence, one with edge switched off +sits out the full forward delay instead, and either way the bridge elects +itself root no matter what the neighbour sends. `stp_setup()` prints a warning for every +STP-enabled port in that state. On a normal bridge this cannot happen, since +BPDUs are consumed before any VLAN classification; here it is a direct +consequence of the delivery path above. + Port states live in `RTL837X_MSTP_STATES (0x5310)`, two bits per port: `00` disabled, `01` blocking, `10` learning, `11` forwarding. Note that a port held in blocking also drops frames the CPU injects into it, so a blocked port diff --git a/rtl837x_port.h b/rtl837x_port.h index 73cc0bf..56397ee 100644 --- a/rtl837x_port.h +++ b/rtl837x_port.h @@ -75,6 +75,7 @@ void port_eee_status(uint8_t port) __banked; void print_port_ingress_filter_mode(vlan_ingress_mode_t mode) __banked; bool port_ingress_vlan_filter_set(__xdata uint8_t port, __xdata bool enabled) __banked; bool port_ingress_vlan_filter_get(__xdata uint8_t port) __banked; +vlan_ingress_mode_t port_ingress_filter_get(__xdata uint8_t port) __banked; void port_isolate(register uint8_t port, __xdata uint16_t pmask) __banked; uint16_t port_isolation_get(register uint8_t port) __banked; diff --git a/rtl837x_stp.c b/rtl837x_stp.c index 8999e3b..c333291 100644 --- a/rtl837x_stp.c +++ b/rtl837x_stp.c @@ -720,6 +720,16 @@ void stp_setup(void) __banked print_reg(RTL837X_MSTP_STATES); write_char('\n'); + for (stp_i = machine.min_port; stp_i <= machine.max_port; stp_i++) { + if (!(stp_pflags[stp_i] & STP_PF_ENABLED)) + continue; + if (port_ingress_filter_get(stp_i) != VLAN_TAGGED) + continue; + print_string("STP: port "); + write_char('0' + machine.log_to_phys_port[stp_i]); + print_string(" admits tagged frames only - BPDUs are untagged and will not arrive\n"); + } + /* Seed the carrier bitmap, so turning STP on does not report every * port that was already down as a fresh topology change. */ reg_read_m(RTL837X_REG_LINKS_STS);