mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-09-02 15:02:51 +08:00
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.
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user