Other ports should stop forwarding and learning when a port receives a superior BPDU carrying a Proposal flag. Without this patch this does not happen and other ports keep executing the learning and forwarding processes. This patch contains some fixes reported in the 802.1q-2008 standard.
Signed-off-by: Daniele Venturino <daniele.ventur...@m3s.it> --- lib/rstp-state-machines.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/rstp-state-machines.c b/lib/rstp-state-machines.c index dc25b00..31909a5 100644 --- a/lib/rstp-state-machines.c +++ b/lib/rstp-state-machines.c @@ -754,8 +754,11 @@ record_dispute(struct rstp_port *p) OVS_REQUIRES(rstp_mutex) { if ((p->received_bpdu_buffer.flags & BPDU_FLAG_LEARNING) != 0) { - p->agreed = true; - p->proposing = false; + /* 802.1D-2004 says to set the agreed flag and to clear the proposing + * flag. 802.1q-2008 instead says to set the disputed variable and to + * clear the agreed variable. */ + p->disputed = true; + p->agreed = false; } } @@ -1133,6 +1136,7 @@ port_information_sm(struct rstp_port *p) { enum port_information_state_machine old_state; struct rstp *r; + struct rstp_port *p1; old_state = p->port_information_sm_state; r = p->rstp; @@ -1236,6 +1240,18 @@ port_information_sm(struct rstp_port *p) } switch (p->rcvd_info) { case SUPERIOR_DESIGNATED_INFO: + /* 802.1q-2008 has a checkBPDUConsistency() function, called on a + * BPDU reception. checkBPDUConsistency() clears the agreed + * variable if the received message priority vector is superior to + * the port priority vector, the BPDU is an ST BPDU or an RST BPDU, + * its port role is Designated and its Learning flag is set. */ + if ((p->received_bpdu_buffer.flags & BPDU_FLAG_LEARNING) != 0) { + HMAP_FOR_EACH (p1, node, &r->ports) { + if (p1->port_number != p->port_number) { + p1->agreed = false; + } + } + } p->port_information_sm_state = PORT_INFORMATION_SM_SUPERIOR_DESIGNATED_EXEC; break; @@ -1301,6 +1317,9 @@ port_information_sm(struct rstp_port *p) case PORT_INFORMATION_SM_REPEATED_DESIGNATED_EXEC: record_proposal(p); set_tc_flags(p); + /* This record_agreement() is missing in 802.1D-2004, but it's present + * in 802.1q-2008. */ + record_agreement(p); updt_rcvd_info_while(p); p->rcvd_msg = false; p->port_information_sm_state = PORT_INFORMATION_SM_REPEATED_DESIGNATED; @@ -1319,6 +1338,10 @@ port_information_sm(struct rstp_port *p) set_tc_flags(p); /* RECEIVED is not specified in Standard 802.1D-2004. */ p->agree = p->agree && better_or_same_info(p, RECEIVED); + /* This record_agreement() and the synced assignment are missing in + * 802.1D-2004, but they're present in 802.1q-2008. */ + record_agreement(p); + p->synced = p->synced && p->agreed; record_priority(p); record_times(p); updt_rcvd_info_while(p); -- 1.8.1.2 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev