1 /************************************************************************ 2 * RSTP library - Rapid Spanning Tree (802.1t, 802.1w) 3 * Copyright (C) 2001-2003 Optical Access 4 * Author: Alex Rozin 5 * 6 * This file is part of RSTP library. 7 * 8 * RSTP library is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU Lesser General Public License as published by the 10 * Free Software Foundation; version 2.1 11 * 12 * RSTP library is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public License 18 * along with RSTP library; see the file COPYING. If not, write to the Free 19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 * 02111-1307, USA. 21 **********************************************************************/ 22 23 /* Note: this state mashine distinkts from described in P802.1t Clause 18. */ 24 /* I am ready to discuss it */ 25 26 #include "base.h" 27 #include "stpm.h" 28 #include "stp_vectors.h" 29 30 #define STATES { \ 31 CHOOSE(DISABLED), \ 32 CHOOSE(DETECTED), \ 33 CHOOSE(DELAYED), \ 34 CHOOSE(RESOLVED) \ 35 } 36 37 #define GET_STATE_NAME STP_edge_get_state_name 38 #include "choose.h" 39 40 #define DEFAULT_LINK_DELAY 3 41 42 void 43 STP_edge_enter_state (STATE_MACH_T *s) 44 { 45 register PORT_T *port = s->owner.port; 46 47 switch (s->State) { 48 case BEGIN: 49 break; 50 case DISABLED: 51 port->operEdge = port->adminEdge; 52 port->wasInitBpdu = False; 53 port->lnkWhile = 0; 54 port->portEnabled = False; 55 break; 56 case DETECTED: 57 port->portEnabled = True; 58 port->lnkWhile = port->LinkDelay; 59 port->operEdge = False; 60 break; 61 case DELAYED: 62 break; 63 case RESOLVED: 64 if (! port->wasInitBpdu) { 65 port->operEdge = port->adminEdge; 66 } 67 break; 68 } 69 } 70 71 Bool 72 STP_edge_check_conditions (STATE_MACH_T *s) 73 { 74 register PORT_T *port = s->owner.port; 75 76 /* If we're disabled, then stay that way. */ 77 if (!port->adminEnable) { 78 if (s->State == DISABLED) 79 return False; 80 else 81 return STP_hop_2_state (s, DISABLED); 82 } 83 84 switch (s->State) { 85 case BEGIN: 86 return STP_hop_2_state (s, DISABLED); 87 case DISABLED: 88 if (port->adminEnable) { 89 return STP_hop_2_state (s, DETECTED); 90 } 91 break; 92 case DETECTED: 93 return STP_hop_2_state (s, DELAYED); 94 case DELAYED: 95 if (port->wasInitBpdu) { 96 #ifdef STP_DBG 97 if (s->debug) 98 stp_trace ("port %s 'edge' resolved by BPDU", port->port_name); 99 #endif 100 return STP_hop_2_state (s, RESOLVED); 101 } 102 103 if (! port->lnkWhile) { 104 #ifdef STP_DBG 105 if (s->debug) 106 stp_trace ("port %s 'edge' resolved by timer", port->port_name); 107 #endif 108 return STP_hop_2_state (s, RESOLVED); 109 } 110 break; 111 case RESOLVED: 112 break; 113 } 114 return False; 115 } 116