4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai/************************************************************************
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * RSTP library - Rapid Spanning Tree (802.1t, 802.1w)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * Copyright (C) 2001-2003 Optical Access
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * Author: Alex Rozin
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * This file is part of RSTP library.
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * RSTP library is free software; you can redistribute it and/or modify it
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * under the terms of the GNU Lesser General Public License as published by the
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * Free Software Foundation; version 2.1
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * RSTP library is distributed in the hope that it will be useful, but
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * WITHOUT ANY WARRANTY; without even the implied warranty of
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * General Public License for more details.
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * You should have received a copy of the GNU Lesser General Public License
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * along with RSTP library; see the file COPYING. If not, write to the Free
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai * 02111-1307, USA.
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai **********************************************************************/
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai/* The Port Information State Machine : 17.21 */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#define GET_STATE_NAME STP_info_get_state_name
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#if 0 /* for debug */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai_stp_dump (char* title, unsigned char* buff, int len)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai register int iii;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (! (iii % 24)) stp_trace ("\n%6d:", iii);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai stp_trace ("%02lx", (unsigned long) buff[iii]);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (port->msgBpduType == BPDU_TOPO_CHANGE_TYPE) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai stp_trace ("%s", "rcvBpdu: OtherMsg:BPDU_TOPO_CHANGE_TYPE");
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->msgPortRole = (port->msgFlags & PORT_ROLE_MASK) >> PORT_ROLE_OFFS;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (RSTP_PORT_ROLE_DESGN == port->msgPortRole ||
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai bridcmp = STP_VECT_compare_vector (&port->msgPrio, &port->portPrio);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai (! STP_VECT_compare_bridge_id (&port->msgPrio.design_bridge,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->msgPrio.design_port == port->portPrio.design_port &&
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai STP_compare_times (&port->msgTimes, &port->portTimes))) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai stp_trace ("rcvBpdu: SuperiorDesignateMsg:bridcmp=%d", (int) bridcmp);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (BPDU_CONFIG_TYPE == port->msgBpduType ||
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai RSTP_PORT_ROLE_DESGN == port->msgPortRole) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (! STP_VECT_compare_vector (&port->msgPrio,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai ! STP_compare_times (&port->msgTimes, &port->portTimes)) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai stp_trace ("%s", "rcvBpdu: RepeatedDesignateMsg");
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (RSTP_PORT_ROLE_ROOT == port->msgBpduType &&
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai ! STP_VECT_compare_bridge_id (&port->msgPrio.design_bridge,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai stp_trace ("%s", "rcvBpdu: ConfirmedRootMsg");
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (RSTP_PORT_ROLE_ROOT == port->msgBpduType) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai stp_trace("rcvBpdu: OtherMsg: not point-to-point MAC");
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai } else if (STP_VECT_compare_bridge_id (&port->msgPrio.design_bridge,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai STP_VECT_br_id_print("rcvBpdu: OtherMsg: msgPrio", &port->msgPrio.design_bridge, True);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai STP_VECT_br_id_print("rcvBpdu: portPrio", &port->portPrio.design_bridge, True);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai stp_trace("rcvBpdu: OtherMsg: agreement bit not set");
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai stp_trace ("rcvBpdu: OtherMsg: type %d", port->msgBpduType);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi SrivatsavairecordProposed (STATE_MACH_T* this, char* reason)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (RSTP_PORT_ROLE_DESGN == port->msgPortRole &&
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai{/* 17.19.13 */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (BPDU_TOPO_CHANGE_TYPE == port->msgBpduType) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai stp_trace ("port %s rx rcvdTcn", port->port_name);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (TOPOLOGY_CHANGE_BIT & port->msgFlags) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (TOPOLOGY_CHANGE_ACK_BIT & port->msgFlags) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai{/* 17.19.18 */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (BPDU_TOPO_CHANGE_TYPE == port->msgBpduType) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai /* port->port->owner->ForceVersion >= NORMAL_RSTP
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai we have checked in STP_info_rx_bpdu */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai{/* 17.19.19 */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai eff_age = ( + port->portTimes.MaxAge) / 16;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai stp_trace ("ma=%d eff_age=%d dm=%d dt=%d p=%s",
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai (int) port->portTimes.MessageAge,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai (int) eff_age, (int) dm, (int) dt, port->port_name);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai /*if (this->debug) */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai stp_trace ("port %s: MaxAge=%d MessageAge=%d HelloTime=%d rcvdInfoWhile=null !",
4eaa471005973e11a6110b69fe990530b3b95a38Rishi SrivatsavaiSTP_info_rx_bpdu (PORT_T* port, struct stp_bpdu_t* bpdu, size_t len)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai _stp_dump ("\nall BPDU", ((unsigned char*) bpdu) - 12, len + 12);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai _stp_dump ("ETH_HEADER", (unsigned char*) &bpdu->eth, 5);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai _stp_dump ("BPDU_HEADER", (unsigned char*) &bpdu->hdr, 4);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai stp_trace ("protocol=%02x%02x version=%02x bpdu_type=%02x\n",
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai bpdu->hdr.protocol[0], bpdu->hdr.protocol[1],
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai _stp_dump ("\nBPDU_BODY", (unsigned char*) &bpdu->body, sizeof (BPDU_BODY_T) + 2);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai stp_trace ("flags=%02x\n", bpdu->body.flags);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai _stp_dump ("root_id", bpdu->body.root_id, 8);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai _stp_dump ("root_path_cost", bpdu->body.root_path_cost, 4);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai _stp_dump ("bridge_id", bpdu->body.bridge_id, 8);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai _stp_dump ("port_id", bpdu->body.port_id, 2);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai _stp_dump ("message_age", bpdu->body.message_age, 2);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai _stp_dump ("max_age", bpdu->body.max_age, 2);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai _stp_dump ("hello_time", bpdu->body.hello_time, 2);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai _stp_dump ("forward_delay", bpdu->body.forward_delay, 2);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai _stp_dump ("ver_1_len", bpdu->ver_1_len, 2);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai /* check bpdu type */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai stp_trace ("CfgBpdu on port %s", port->port_name);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai stp_trace ("TcnBpdu on port %s", port->port_name);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai stp_trace ("RX undef bpdu type=%d", (int) bpdu->hdr.bpdu_type);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (port->owner->ForceVersion >= NORMAL_RSTP) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai stp_trace ("BPDU_RSTP on port %s", port->port_name);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai /* 17.18.11 */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai STP_VECT_get_vector (&bpdu->body, &port->msgPrio);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->msgPrio.bridge_port = port->port_id;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai /* 17.18.12 */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai STP_get_times (&bpdu->body, &port->msgTimes);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai /* 17.18.25, 17.18.26 : see setTcFlags() */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavaivoid STP_info_enter_state (STATE_MACH_T* this)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai /* clear port statistics */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai /* FALLTHRU */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->rcvdBpdu = port->rcvdRSTP = port->rcvdSTP = False;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->updtInfo = port->proposing = False; /* In DISABLED */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai case ENABLED: /* IEEE 802.1y, 17.21, Z.14 */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai STP_VECT_copy (&port->portPrio, &port->designPrio);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai STP_copy_times (&port->portTimes, &port->designTimes);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai STP_VECT_copy (&port->portPrio, &port->designPrio);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai STP_copy_times (&port->portTimes, &port->designTimes);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->agreed = port->synced = False; /* In UPDATE */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->proposed = port->proposing = False; /* in UPDATE */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai STP_VECT_br_id_print ("updated: portPrio.design_bridge",
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai STP_VECT_br_id_print ("updated: portPrio.root_bridge",
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai STP_VECT_copy (&port->portPrio, &port->msgPrio);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai STP_copy_times (&port->portTimes, &port->msgTimes);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->agreed = False; /* deleted due 802.y in SUPERIOR */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->synced = False; /* due 802.y deleted in SUPERIOR */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->proposing = False; /* in SUPERIOR */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->proposed = recordProposed (this, "SUPERIOR");
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai STP_VECT_br_id_print ("stored: portPrio.design_bridge",
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai STP_VECT_br_id_print ("stored: portPrio.root_bridge",
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->proposed = recordProposed (this, "REPEAT");
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai port->proposing = False; /* In AGREEMENT */
4eaa471005973e11a6110b69fe990530b3b95a38Rishi SrivatsavaiBool STP_info_check_conditions (STATE_MACH_T* this)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if ((! port->portEnabled && port->infoIs != Disabled) || BEGIN == this->State) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai if (port->portEnabled && port->selected) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai case ENABLED: /* IEEE 802.1y, 17.21, Z.14 */