xref: /onnv-gate/usr/src/lib/librstp/common/roletrns.c (revision 10491:8893b747ecdf)
1*10491SRishi.Srivatsavai@Sun.COM /************************************************************************
2*10491SRishi.Srivatsavai@Sun.COM  * RSTP library - Rapid Spanning Tree (802.1t, 802.1w)
3*10491SRishi.Srivatsavai@Sun.COM  * Copyright (C) 2001-2003 Optical Access
4*10491SRishi.Srivatsavai@Sun.COM  * Author: Alex Rozin
5*10491SRishi.Srivatsavai@Sun.COM  *
6*10491SRishi.Srivatsavai@Sun.COM  * This file is part of RSTP library.
7*10491SRishi.Srivatsavai@Sun.COM  *
8*10491SRishi.Srivatsavai@Sun.COM  * RSTP library is free software; you can redistribute it and/or modify it
9*10491SRishi.Srivatsavai@Sun.COM  * under the terms of the GNU Lesser General Public License as published by the
10*10491SRishi.Srivatsavai@Sun.COM  * Free Software Foundation; version 2.1
11*10491SRishi.Srivatsavai@Sun.COM  *
12*10491SRishi.Srivatsavai@Sun.COM  * RSTP library is distributed in the hope that it will be useful, but
13*10491SRishi.Srivatsavai@Sun.COM  * WITHOUT ANY WARRANTY; without even the implied warranty of
14*10491SRishi.Srivatsavai@Sun.COM  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
15*10491SRishi.Srivatsavai@Sun.COM  * General Public License for more details.
16*10491SRishi.Srivatsavai@Sun.COM  *
17*10491SRishi.Srivatsavai@Sun.COM  * You should have received a copy of the GNU Lesser General Public License
18*10491SRishi.Srivatsavai@Sun.COM  * along with RSTP library; see the file COPYING.  If not, write to the Free
19*10491SRishi.Srivatsavai@Sun.COM  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20*10491SRishi.Srivatsavai@Sun.COM  * 02111-1307, USA.
21*10491SRishi.Srivatsavai@Sun.COM  **********************************************************************/
22*10491SRishi.Srivatsavai@Sun.COM 
23*10491SRishi.Srivatsavai@Sun.COM /* Port Role Transitions state machine : 17.24 */
24*10491SRishi.Srivatsavai@Sun.COM 
25*10491SRishi.Srivatsavai@Sun.COM #include "base.h"
26*10491SRishi.Srivatsavai@Sun.COM 
27*10491SRishi.Srivatsavai@Sun.COM #include "stpm.h"
28*10491SRishi.Srivatsavai@Sun.COM 
29*10491SRishi.Srivatsavai@Sun.COM #define STATES { \
30*10491SRishi.Srivatsavai@Sun.COM    CHOOSE(INIT_PORT),       \
31*10491SRishi.Srivatsavai@Sun.COM    CHOOSE(BLOCK_PORT),      \
32*10491SRishi.Srivatsavai@Sun.COM    CHOOSE(BLOCKED_PORT),    \
33*10491SRishi.Srivatsavai@Sun.COM    CHOOSE(BACKUP_PORT),     \
34*10491SRishi.Srivatsavai@Sun.COM    CHOOSE(ROOT_PROPOSED),   \
35*10491SRishi.Srivatsavai@Sun.COM    CHOOSE(ROOT_AGREED),     \
36*10491SRishi.Srivatsavai@Sun.COM    CHOOSE(REROOT),      \
37*10491SRishi.Srivatsavai@Sun.COM    CHOOSE(ROOT_PORT),       \
38*10491SRishi.Srivatsavai@Sun.COM    CHOOSE(REROOTED),        \
39*10491SRishi.Srivatsavai@Sun.COM    CHOOSE(ROOT_LEARN),      \
40*10491SRishi.Srivatsavai@Sun.COM    CHOOSE(ROOT_FORWARD),    \
41*10491SRishi.Srivatsavai@Sun.COM    CHOOSE(DESIGNATED_PROPOSE),  \
42*10491SRishi.Srivatsavai@Sun.COM    CHOOSE(DESIGNATED_SYNCED),   \
43*10491SRishi.Srivatsavai@Sun.COM    CHOOSE(DESIGNATED_RETIRED),  \
44*10491SRishi.Srivatsavai@Sun.COM    CHOOSE(DESIGNATED_PORT), \
45*10491SRishi.Srivatsavai@Sun.COM    CHOOSE(DESIGNATED_LISTEN),   \
46*10491SRishi.Srivatsavai@Sun.COM    CHOOSE(DESIGNATED_LEARN),    \
47*10491SRishi.Srivatsavai@Sun.COM    CHOOSE(DESIGNATED_FORWARD)  \
48*10491SRishi.Srivatsavai@Sun.COM }
49*10491SRishi.Srivatsavai@Sun.COM 
50*10491SRishi.Srivatsavai@Sun.COM #define GET_STATE_NAME STP_roletrns_get_state_name
51*10491SRishi.Srivatsavai@Sun.COM #include "choose.h"
52*10491SRishi.Srivatsavai@Sun.COM 
53*10491SRishi.Srivatsavai@Sun.COM static void
setSyncBridge(STATE_MACH_T * this)54*10491SRishi.Srivatsavai@Sun.COM setSyncBridge (STATE_MACH_T *this)
55*10491SRishi.Srivatsavai@Sun.COM {
56*10491SRishi.Srivatsavai@Sun.COM   register PORT_T* port;
57*10491SRishi.Srivatsavai@Sun.COM 
58*10491SRishi.Srivatsavai@Sun.COM   for (port = this->owner.port->owner->ports; port; port = port->next) {
59*10491SRishi.Srivatsavai@Sun.COM     port->sync = True; /* in ROOT_PROPOSED (setSyncBridge) */
60*10491SRishi.Srivatsavai@Sun.COM   }
61*10491SRishi.Srivatsavai@Sun.COM }
62*10491SRishi.Srivatsavai@Sun.COM 
63*10491SRishi.Srivatsavai@Sun.COM static void
setReRootBridge(STATE_MACH_T * this)64*10491SRishi.Srivatsavai@Sun.COM setReRootBridge (STATE_MACH_T *this)
65*10491SRishi.Srivatsavai@Sun.COM {
66*10491SRishi.Srivatsavai@Sun.COM   register PORT_T* port;
67*10491SRishi.Srivatsavai@Sun.COM 
68*10491SRishi.Srivatsavai@Sun.COM   for (port = this->owner.port->owner->ports; port; port = port->next) {
69*10491SRishi.Srivatsavai@Sun.COM     port->reRoot = True; /* In setReRootBridge */
70*10491SRishi.Srivatsavai@Sun.COM   }
71*10491SRishi.Srivatsavai@Sun.COM }
72*10491SRishi.Srivatsavai@Sun.COM 
73*10491SRishi.Srivatsavai@Sun.COM static Bool
compute_all_synced(PORT_T * this)74*10491SRishi.Srivatsavai@Sun.COM compute_all_synced (PORT_T* this)
75*10491SRishi.Srivatsavai@Sun.COM {
76*10491SRishi.Srivatsavai@Sun.COM   register PORT_T* port;
77*10491SRishi.Srivatsavai@Sun.COM 
78*10491SRishi.Srivatsavai@Sun.COM   for (port = this->owner->ports; port; port = port->next) {
79*10491SRishi.Srivatsavai@Sun.COM     if (port->port_index == this->port_index) continue;
80*10491SRishi.Srivatsavai@Sun.COM     if (! port->synced) {
81*10491SRishi.Srivatsavai@Sun.COM         return False;
82*10491SRishi.Srivatsavai@Sun.COM     }
83*10491SRishi.Srivatsavai@Sun.COM   }
84*10491SRishi.Srivatsavai@Sun.COM 
85*10491SRishi.Srivatsavai@Sun.COM   return True;
86*10491SRishi.Srivatsavai@Sun.COM }
87*10491SRishi.Srivatsavai@Sun.COM 
88*10491SRishi.Srivatsavai@Sun.COM static Bool
compute_re_rooted(PORT_T * this)89*10491SRishi.Srivatsavai@Sun.COM compute_re_rooted (PORT_T* this)
90*10491SRishi.Srivatsavai@Sun.COM {
91*10491SRishi.Srivatsavai@Sun.COM   register PORT_T* port;
92*10491SRishi.Srivatsavai@Sun.COM 
93*10491SRishi.Srivatsavai@Sun.COM   for (port = this->owner->ports; port; port = port->next) {
94*10491SRishi.Srivatsavai@Sun.COM     if (port->port_index == this->port_index) continue;
95*10491SRishi.Srivatsavai@Sun.COM     if (port->rrWhile) {
96*10491SRishi.Srivatsavai@Sun.COM       return False;
97*10491SRishi.Srivatsavai@Sun.COM     }
98*10491SRishi.Srivatsavai@Sun.COM   }
99*10491SRishi.Srivatsavai@Sun.COM   return True;
100*10491SRishi.Srivatsavai@Sun.COM }
101*10491SRishi.Srivatsavai@Sun.COM 
102*10491SRishi.Srivatsavai@Sun.COM void
STP_roletrns_enter_state(STATE_MACH_T * this)103*10491SRishi.Srivatsavai@Sun.COM STP_roletrns_enter_state (STATE_MACH_T* this)
104*10491SRishi.Srivatsavai@Sun.COM {
105*10491SRishi.Srivatsavai@Sun.COM   register PORT_T*           port = this->owner.port;
106*10491SRishi.Srivatsavai@Sun.COM   register STPM_T*           stpm;
107*10491SRishi.Srivatsavai@Sun.COM 
108*10491SRishi.Srivatsavai@Sun.COM   stpm = port->owner;
109*10491SRishi.Srivatsavai@Sun.COM 
110*10491SRishi.Srivatsavai@Sun.COM   switch (this->State) {
111*10491SRishi.Srivatsavai@Sun.COM     case BEGIN:
112*10491SRishi.Srivatsavai@Sun.COM     case INIT_PORT:
113*10491SRishi.Srivatsavai@Sun.COM #if 0 /* due 802.1y Z.4 */
114*10491SRishi.Srivatsavai@Sun.COM       port->role = DisabledPort;
115*10491SRishi.Srivatsavai@Sun.COM #else
116*10491SRishi.Srivatsavai@Sun.COM       port->role = port->selectedRole = DisabledPort;
117*10491SRishi.Srivatsavai@Sun.COM       port->reselect = True;
118*10491SRishi.Srivatsavai@Sun.COM #endif
119*10491SRishi.Srivatsavai@Sun.COM       port->synced = False; /* in INIT */
120*10491SRishi.Srivatsavai@Sun.COM       port->sync = True; /* in INIT */
121*10491SRishi.Srivatsavai@Sun.COM       port->reRoot = True; /* in INIT_PORT */
122*10491SRishi.Srivatsavai@Sun.COM       port->rrWhile = stpm->rootTimes.ForwardDelay;
123*10491SRishi.Srivatsavai@Sun.COM       port->fdWhile = stpm->rootTimes.ForwardDelay;
124*10491SRishi.Srivatsavai@Sun.COM       port->rbWhile = 0;
125*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
126*10491SRishi.Srivatsavai@Sun.COM       if (this->debug)
127*10491SRishi.Srivatsavai@Sun.COM         STP_port_trace_flags ("after init", port);
128*10491SRishi.Srivatsavai@Sun.COM #endif
129*10491SRishi.Srivatsavai@Sun.COM       break;
130*10491SRishi.Srivatsavai@Sun.COM     case BLOCK_PORT:
131*10491SRishi.Srivatsavai@Sun.COM       port->role = port->selectedRole;
132*10491SRishi.Srivatsavai@Sun.COM       port->learn =
133*10491SRishi.Srivatsavai@Sun.COM       port->forward = False;
134*10491SRishi.Srivatsavai@Sun.COM       break;
135*10491SRishi.Srivatsavai@Sun.COM     case BLOCKED_PORT:
136*10491SRishi.Srivatsavai@Sun.COM       port->fdWhile = stpm->rootTimes.ForwardDelay;
137*10491SRishi.Srivatsavai@Sun.COM       port->synced = True; /* In BLOCKED_PORT */
138*10491SRishi.Srivatsavai@Sun.COM       port->rrWhile = 0;
139*10491SRishi.Srivatsavai@Sun.COM       port->sync = port->reRoot = False; /* BLOCKED_PORT */
140*10491SRishi.Srivatsavai@Sun.COM       break;
141*10491SRishi.Srivatsavai@Sun.COM     case BACKUP_PORT:
142*10491SRishi.Srivatsavai@Sun.COM       port->rbWhile = 2 * stpm->rootTimes.HelloTime;
143*10491SRishi.Srivatsavai@Sun.COM       break;
144*10491SRishi.Srivatsavai@Sun.COM 
145*10491SRishi.Srivatsavai@Sun.COM     /* 17.23.2 */
146*10491SRishi.Srivatsavai@Sun.COM     case ROOT_PROPOSED:
147*10491SRishi.Srivatsavai@Sun.COM       setSyncBridge (this);
148*10491SRishi.Srivatsavai@Sun.COM       port->proposed = False;
149*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
150*10491SRishi.Srivatsavai@Sun.COM       if (this->debug)
151*10491SRishi.Srivatsavai@Sun.COM         STP_port_trace_flags ("ROOT_PROPOSED", port);
152*10491SRishi.Srivatsavai@Sun.COM #endif
153*10491SRishi.Srivatsavai@Sun.COM       break;
154*10491SRishi.Srivatsavai@Sun.COM     case ROOT_AGREED:
155*10491SRishi.Srivatsavai@Sun.COM       port->proposed = port->sync = False; /* in ROOT_AGREED */
156*10491SRishi.Srivatsavai@Sun.COM       port->synced = True; /* In ROOT_AGREED */
157*10491SRishi.Srivatsavai@Sun.COM       port->newInfo = True;
158*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
159*10491SRishi.Srivatsavai@Sun.COM       if (this->debug)
160*10491SRishi.Srivatsavai@Sun.COM         STP_port_trace_flags ("ROOT_AGREED", port);
161*10491SRishi.Srivatsavai@Sun.COM #endif
162*10491SRishi.Srivatsavai@Sun.COM       break;
163*10491SRishi.Srivatsavai@Sun.COM     case REROOT:
164*10491SRishi.Srivatsavai@Sun.COM       setReRootBridge (this);
165*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
166*10491SRishi.Srivatsavai@Sun.COM       if (this->debug)
167*10491SRishi.Srivatsavai@Sun.COM         STP_port_trace_flags ("REROOT", port);
168*10491SRishi.Srivatsavai@Sun.COM #endif
169*10491SRishi.Srivatsavai@Sun.COM       break;
170*10491SRishi.Srivatsavai@Sun.COM     case ROOT_PORT:
171*10491SRishi.Srivatsavai@Sun.COM       port->role = RootPort;
172*10491SRishi.Srivatsavai@Sun.COM       port->rrWhile = stpm->rootTimes.ForwardDelay;
173*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
174*10491SRishi.Srivatsavai@Sun.COM       if (this->debug)
175*10491SRishi.Srivatsavai@Sun.COM         STP_port_trace_flags ("ROOT_PORT", port);
176*10491SRishi.Srivatsavai@Sun.COM #endif
177*10491SRishi.Srivatsavai@Sun.COM       break;
178*10491SRishi.Srivatsavai@Sun.COM     case REROOTED:
179*10491SRishi.Srivatsavai@Sun.COM       port->reRoot = False; /* In REROOTED */
180*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
181*10491SRishi.Srivatsavai@Sun.COM       if (this->debug)
182*10491SRishi.Srivatsavai@Sun.COM         STP_port_trace_flags ("REROOTED", port);
183*10491SRishi.Srivatsavai@Sun.COM #endif
184*10491SRishi.Srivatsavai@Sun.COM       break;
185*10491SRishi.Srivatsavai@Sun.COM     case ROOT_LEARN:
186*10491SRishi.Srivatsavai@Sun.COM       port->fdWhile = stpm->rootTimes.ForwardDelay;
187*10491SRishi.Srivatsavai@Sun.COM       port->learn = True;
188*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
189*10491SRishi.Srivatsavai@Sun.COM       if (this->debug)
190*10491SRishi.Srivatsavai@Sun.COM         STP_port_trace_flags ("ROOT_LEARN", port);
191*10491SRishi.Srivatsavai@Sun.COM #endif
192*10491SRishi.Srivatsavai@Sun.COM       break;
193*10491SRishi.Srivatsavai@Sun.COM     case ROOT_FORWARD:
194*10491SRishi.Srivatsavai@Sun.COM       port->fdWhile = 0;
195*10491SRishi.Srivatsavai@Sun.COM       port->forward = True;
196*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
197*10491SRishi.Srivatsavai@Sun.COM       if (this->debug)
198*10491SRishi.Srivatsavai@Sun.COM         STP_port_trace_flags ("ROOT_FORWARD", port);
199*10491SRishi.Srivatsavai@Sun.COM #endif
200*10491SRishi.Srivatsavai@Sun.COM       break;
201*10491SRishi.Srivatsavai@Sun.COM 
202*10491SRishi.Srivatsavai@Sun.COM     /* 17.23.3 */
203*10491SRishi.Srivatsavai@Sun.COM     case DESIGNATED_PROPOSE:
204*10491SRishi.Srivatsavai@Sun.COM       port->proposing = True; /* in DESIGNATED_PROPOSE */
205*10491SRishi.Srivatsavai@Sun.COM       port->newInfo = True;
206*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
207*10491SRishi.Srivatsavai@Sun.COM       if (this->debug)
208*10491SRishi.Srivatsavai@Sun.COM         STP_port_trace_flags ("DESIGNATED_PROPOSE", port);
209*10491SRishi.Srivatsavai@Sun.COM #endif
210*10491SRishi.Srivatsavai@Sun.COM       break;
211*10491SRishi.Srivatsavai@Sun.COM     case DESIGNATED_SYNCED:
212*10491SRishi.Srivatsavai@Sun.COM       port->rrWhile = 0;
213*10491SRishi.Srivatsavai@Sun.COM       port->synced = True; /* DESIGNATED_SYNCED */
214*10491SRishi.Srivatsavai@Sun.COM       port->sync = False; /* DESIGNATED_SYNCED */
215*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
216*10491SRishi.Srivatsavai@Sun.COM       if (this->debug)
217*10491SRishi.Srivatsavai@Sun.COM         STP_port_trace_flags ("DESIGNATED_SYNCED", port);
218*10491SRishi.Srivatsavai@Sun.COM #endif
219*10491SRishi.Srivatsavai@Sun.COM       break;
220*10491SRishi.Srivatsavai@Sun.COM     case DESIGNATED_RETIRED:
221*10491SRishi.Srivatsavai@Sun.COM       port->reRoot = False; /* DESIGNATED_RETIRED */
222*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
223*10491SRishi.Srivatsavai@Sun.COM       if (this->debug)
224*10491SRishi.Srivatsavai@Sun.COM         STP_port_trace_flags ("DESIGNATED_RETIRED", port);
225*10491SRishi.Srivatsavai@Sun.COM #endif
226*10491SRishi.Srivatsavai@Sun.COM       break;
227*10491SRishi.Srivatsavai@Sun.COM     case DESIGNATED_PORT:
228*10491SRishi.Srivatsavai@Sun.COM       port->role = DesignatedPort;
229*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
230*10491SRishi.Srivatsavai@Sun.COM       if (this->debug)
231*10491SRishi.Srivatsavai@Sun.COM         STP_port_trace_flags ("DESIGNATED_PORT", port);
232*10491SRishi.Srivatsavai@Sun.COM #endif
233*10491SRishi.Srivatsavai@Sun.COM       break;
234*10491SRishi.Srivatsavai@Sun.COM     case DESIGNATED_LISTEN:
235*10491SRishi.Srivatsavai@Sun.COM       port->learn = port->forward = False;
236*10491SRishi.Srivatsavai@Sun.COM       port->fdWhile = stpm->rootTimes.ForwardDelay;
237*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
238*10491SRishi.Srivatsavai@Sun.COM       if (this->debug)
239*10491SRishi.Srivatsavai@Sun.COM         STP_port_trace_flags ("DESIGNATED_LISTEN", port);
240*10491SRishi.Srivatsavai@Sun.COM #endif
241*10491SRishi.Srivatsavai@Sun.COM       break;
242*10491SRishi.Srivatsavai@Sun.COM     case DESIGNATED_LEARN:
243*10491SRishi.Srivatsavai@Sun.COM       port->learn = True;
244*10491SRishi.Srivatsavai@Sun.COM       port->fdWhile = stpm->rootTimes.ForwardDelay;
245*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
246*10491SRishi.Srivatsavai@Sun.COM       if (this->debug)
247*10491SRishi.Srivatsavai@Sun.COM         STP_port_trace_flags ("DESIGNATED_LEARN", port);
248*10491SRishi.Srivatsavai@Sun.COM #endif
249*10491SRishi.Srivatsavai@Sun.COM       break;
250*10491SRishi.Srivatsavai@Sun.COM     case DESIGNATED_FORWARD:
251*10491SRishi.Srivatsavai@Sun.COM       port->forward = True;
252*10491SRishi.Srivatsavai@Sun.COM       port->fdWhile = 0;
253*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
254*10491SRishi.Srivatsavai@Sun.COM       if (this->debug)
255*10491SRishi.Srivatsavai@Sun.COM         STP_port_trace_flags ("DESIGNATED_FORWARD", port);
256*10491SRishi.Srivatsavai@Sun.COM #endif
257*10491SRishi.Srivatsavai@Sun.COM       break;
258*10491SRishi.Srivatsavai@Sun.COM   };
259*10491SRishi.Srivatsavai@Sun.COM }
260*10491SRishi.Srivatsavai@Sun.COM 
261*10491SRishi.Srivatsavai@Sun.COM Bool
STP_roletrns_check_conditions(STATE_MACH_T * this)262*10491SRishi.Srivatsavai@Sun.COM STP_roletrns_check_conditions (STATE_MACH_T* this)
263*10491SRishi.Srivatsavai@Sun.COM {
264*10491SRishi.Srivatsavai@Sun.COM   register PORT_T           *port = this->owner.port;
265*10491SRishi.Srivatsavai@Sun.COM   register STPM_T           *stpm;
266*10491SRishi.Srivatsavai@Sun.COM   Bool                      allSynced;
267*10491SRishi.Srivatsavai@Sun.COM   Bool                      allReRooted;
268*10491SRishi.Srivatsavai@Sun.COM 
269*10491SRishi.Srivatsavai@Sun.COM   stpm = port->owner;
270*10491SRishi.Srivatsavai@Sun.COM 
271*10491SRishi.Srivatsavai@Sun.COM   if (BEGIN == this->State) {
272*10491SRishi.Srivatsavai@Sun.COM     return STP_hop_2_state (this, INIT_PORT);
273*10491SRishi.Srivatsavai@Sun.COM   }
274*10491SRishi.Srivatsavai@Sun.COM 
275*10491SRishi.Srivatsavai@Sun.COM   if (port->role != port->selectedRole &&
276*10491SRishi.Srivatsavai@Sun.COM       port->selected &&
277*10491SRishi.Srivatsavai@Sun.COM       ! port->updtInfo) {
278*10491SRishi.Srivatsavai@Sun.COM     switch (port->selectedRole) {
279*10491SRishi.Srivatsavai@Sun.COM       case DisabledPort:
280*10491SRishi.Srivatsavai@Sun.COM       case AlternatePort:
281*10491SRishi.Srivatsavai@Sun.COM       case BackupPort:
282*10491SRishi.Srivatsavai@Sun.COM #if 0 /* def STP_DBG */
283*10491SRishi.Srivatsavai@Sun.COM         if (this->debug) {
284*10491SRishi.Srivatsavai@Sun.COM           stp_trace ("hop to BLOCK_PORT role=%d selectedRole=%d",
285*10491SRishi.Srivatsavai@Sun.COM                                 (int) port->role, (int) port->selectedRole);
286*10491SRishi.Srivatsavai@Sun.COM         }
287*10491SRishi.Srivatsavai@Sun.COM #endif
288*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, BLOCK_PORT);
289*10491SRishi.Srivatsavai@Sun.COM       case RootPort:
290*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, ROOT_PORT);
291*10491SRishi.Srivatsavai@Sun.COM       case DesignatedPort:
292*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, DESIGNATED_PORT);
293*10491SRishi.Srivatsavai@Sun.COM       default:
294*10491SRishi.Srivatsavai@Sun.COM         return False;
295*10491SRishi.Srivatsavai@Sun.COM     }
296*10491SRishi.Srivatsavai@Sun.COM   }
297*10491SRishi.Srivatsavai@Sun.COM 
298*10491SRishi.Srivatsavai@Sun.COM   switch (this->State) {
299*10491SRishi.Srivatsavai@Sun.COM     /* 17.23.1 */
300*10491SRishi.Srivatsavai@Sun.COM     case INIT_PORT:
301*10491SRishi.Srivatsavai@Sun.COM       return STP_hop_2_state (this, BLOCK_PORT);
302*10491SRishi.Srivatsavai@Sun.COM     case BLOCK_PORT:
303*10491SRishi.Srivatsavai@Sun.COM       if (!port->selected || port->updtInfo) break;
304*10491SRishi.Srivatsavai@Sun.COM       if (!port->learning && !port->forwarding) {
305*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, BLOCKED_PORT);
306*10491SRishi.Srivatsavai@Sun.COM       }
307*10491SRishi.Srivatsavai@Sun.COM       break;
308*10491SRishi.Srivatsavai@Sun.COM     case BLOCKED_PORT:
309*10491SRishi.Srivatsavai@Sun.COM       if (!port->selected || port->updtInfo) break;
310*10491SRishi.Srivatsavai@Sun.COM       if (port->fdWhile != stpm->rootTimes.ForwardDelay ||
311*10491SRishi.Srivatsavai@Sun.COM           port->sync                ||
312*10491SRishi.Srivatsavai@Sun.COM           port->reRoot              ||
313*10491SRishi.Srivatsavai@Sun.COM           !port->synced) {
314*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, BLOCKED_PORT);
315*10491SRishi.Srivatsavai@Sun.COM       }
316*10491SRishi.Srivatsavai@Sun.COM       if (port->rbWhile != 2 * stpm->rootTimes.HelloTime &&
317*10491SRishi.Srivatsavai@Sun.COM           port->role == BackupPort) {
318*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, BACKUP_PORT);
319*10491SRishi.Srivatsavai@Sun.COM       }
320*10491SRishi.Srivatsavai@Sun.COM       break;
321*10491SRishi.Srivatsavai@Sun.COM     case BACKUP_PORT:
322*10491SRishi.Srivatsavai@Sun.COM       return STP_hop_2_state (this, BLOCKED_PORT);
323*10491SRishi.Srivatsavai@Sun.COM 
324*10491SRishi.Srivatsavai@Sun.COM     /* 17.23.2 */
325*10491SRishi.Srivatsavai@Sun.COM     case ROOT_PROPOSED:
326*10491SRishi.Srivatsavai@Sun.COM       return STP_hop_2_state (this, ROOT_PORT);
327*10491SRishi.Srivatsavai@Sun.COM     case ROOT_AGREED:
328*10491SRishi.Srivatsavai@Sun.COM       return STP_hop_2_state (this, ROOT_PORT);
329*10491SRishi.Srivatsavai@Sun.COM     case REROOT:
330*10491SRishi.Srivatsavai@Sun.COM       return STP_hop_2_state (this, ROOT_PORT);
331*10491SRishi.Srivatsavai@Sun.COM     case ROOT_PORT:
332*10491SRishi.Srivatsavai@Sun.COM       if (!port->selected || port->updtInfo) break;
333*10491SRishi.Srivatsavai@Sun.COM       if (!port->forward && !port->reRoot) {
334*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, REROOT);
335*10491SRishi.Srivatsavai@Sun.COM       }
336*10491SRishi.Srivatsavai@Sun.COM       allSynced = compute_all_synced (port);
337*10491SRishi.Srivatsavai@Sun.COM       if ((port->proposed && allSynced) ||
338*10491SRishi.Srivatsavai@Sun.COM           (!port->synced && allSynced)) {
339*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, ROOT_AGREED);
340*10491SRishi.Srivatsavai@Sun.COM       }
341*10491SRishi.Srivatsavai@Sun.COM       if (port->proposed && !port->synced) {
342*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, ROOT_PROPOSED);
343*10491SRishi.Srivatsavai@Sun.COM       }
344*10491SRishi.Srivatsavai@Sun.COM 
345*10491SRishi.Srivatsavai@Sun.COM       allReRooted = compute_re_rooted (port);
346*10491SRishi.Srivatsavai@Sun.COM       if ((!port->fdWhile ||
347*10491SRishi.Srivatsavai@Sun.COM            ((allReRooted && !port->rbWhile) && stpm->ForceVersion >=2)) &&
348*10491SRishi.Srivatsavai@Sun.COM           port->learn && !port->forward) {
349*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, ROOT_FORWARD);
350*10491SRishi.Srivatsavai@Sun.COM       }
351*10491SRishi.Srivatsavai@Sun.COM       if ((!port->fdWhile ||
352*10491SRishi.Srivatsavai@Sun.COM            ((allReRooted && !port->rbWhile) && stpm->ForceVersion >=2)) &&
353*10491SRishi.Srivatsavai@Sun.COM           !port->learn) {
354*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, ROOT_LEARN);
355*10491SRishi.Srivatsavai@Sun.COM       }
356*10491SRishi.Srivatsavai@Sun.COM 
357*10491SRishi.Srivatsavai@Sun.COM       if (port->reRoot && port->forward) {
358*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, REROOTED);
359*10491SRishi.Srivatsavai@Sun.COM       }
360*10491SRishi.Srivatsavai@Sun.COM       if (port->rrWhile != stpm->rootTimes.ForwardDelay) {
361*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, ROOT_PORT);
362*10491SRishi.Srivatsavai@Sun.COM       }
363*10491SRishi.Srivatsavai@Sun.COM       break;
364*10491SRishi.Srivatsavai@Sun.COM     case REROOTED:
365*10491SRishi.Srivatsavai@Sun.COM       return STP_hop_2_state (this, ROOT_PORT);
366*10491SRishi.Srivatsavai@Sun.COM     case ROOT_LEARN:
367*10491SRishi.Srivatsavai@Sun.COM       return STP_hop_2_state (this, ROOT_PORT);
368*10491SRishi.Srivatsavai@Sun.COM     case ROOT_FORWARD:
369*10491SRishi.Srivatsavai@Sun.COM       return STP_hop_2_state (this, ROOT_PORT);
370*10491SRishi.Srivatsavai@Sun.COM 
371*10491SRishi.Srivatsavai@Sun.COM     /* 17.23.3 */
372*10491SRishi.Srivatsavai@Sun.COM     case DESIGNATED_PROPOSE:
373*10491SRishi.Srivatsavai@Sun.COM       return STP_hop_2_state (this, DESIGNATED_PORT);
374*10491SRishi.Srivatsavai@Sun.COM     case DESIGNATED_SYNCED:
375*10491SRishi.Srivatsavai@Sun.COM       return STP_hop_2_state (this, DESIGNATED_PORT);
376*10491SRishi.Srivatsavai@Sun.COM     case DESIGNATED_RETIRED:
377*10491SRishi.Srivatsavai@Sun.COM       return STP_hop_2_state (this, DESIGNATED_PORT);
378*10491SRishi.Srivatsavai@Sun.COM     case DESIGNATED_PORT:
379*10491SRishi.Srivatsavai@Sun.COM       if (!port->selected || port->updtInfo) break;
380*10491SRishi.Srivatsavai@Sun.COM 
381*10491SRishi.Srivatsavai@Sun.COM       if (!port->forward && !port->agreed && !port->proposing && !port->operEdge) {
382*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, DESIGNATED_PROPOSE);
383*10491SRishi.Srivatsavai@Sun.COM       }
384*10491SRishi.Srivatsavai@Sun.COM 
385*10491SRishi.Srivatsavai@Sun.COM       if (!port->rrWhile && port->reRoot) {
386*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, DESIGNATED_RETIRED);
387*10491SRishi.Srivatsavai@Sun.COM       }
388*10491SRishi.Srivatsavai@Sun.COM 
389*10491SRishi.Srivatsavai@Sun.COM       if (!port->learning && !port->forwarding && !port->synced) {
390*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, DESIGNATED_SYNCED);
391*10491SRishi.Srivatsavai@Sun.COM       }
392*10491SRishi.Srivatsavai@Sun.COM 
393*10491SRishi.Srivatsavai@Sun.COM       if (port->agreed && !port->synced) {
394*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, DESIGNATED_SYNCED);
395*10491SRishi.Srivatsavai@Sun.COM       }
396*10491SRishi.Srivatsavai@Sun.COM       if (port->operEdge && !port->synced) {
397*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, DESIGNATED_SYNCED);
398*10491SRishi.Srivatsavai@Sun.COM       }
399*10491SRishi.Srivatsavai@Sun.COM       if (port->sync && port->synced) {
400*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, DESIGNATED_SYNCED);
401*10491SRishi.Srivatsavai@Sun.COM       }
402*10491SRishi.Srivatsavai@Sun.COM 
403*10491SRishi.Srivatsavai@Sun.COM       if ((!port->fdWhile || port->agreed || port->operEdge) &&
404*10491SRishi.Srivatsavai@Sun.COM           (!port->rrWhile  || !port->reRoot) &&
405*10491SRishi.Srivatsavai@Sun.COM           !port->sync &&
406*10491SRishi.Srivatsavai@Sun.COM           (port->learn && !port->forward)) {
407*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, DESIGNATED_FORWARD);
408*10491SRishi.Srivatsavai@Sun.COM       }
409*10491SRishi.Srivatsavai@Sun.COM       if ((!port->fdWhile || port->agreed || port->operEdge) &&
410*10491SRishi.Srivatsavai@Sun.COM           (!port->rrWhile  || !port->reRoot) &&
411*10491SRishi.Srivatsavai@Sun.COM           !port->sync && !port->learn) {
412*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, DESIGNATED_LEARN);
413*10491SRishi.Srivatsavai@Sun.COM       }
414*10491SRishi.Srivatsavai@Sun.COM       if (((port->sync && !port->synced) ||
415*10491SRishi.Srivatsavai@Sun.COM            (port->reRoot && port->rrWhile)) &&
416*10491SRishi.Srivatsavai@Sun.COM           !port->operEdge && (port->learn || port->forward)) {
417*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, DESIGNATED_LISTEN);
418*10491SRishi.Srivatsavai@Sun.COM       }
419*10491SRishi.Srivatsavai@Sun.COM       break;
420*10491SRishi.Srivatsavai@Sun.COM     case DESIGNATED_LISTEN:
421*10491SRishi.Srivatsavai@Sun.COM       return STP_hop_2_state (this, DESIGNATED_PORT);
422*10491SRishi.Srivatsavai@Sun.COM     case DESIGNATED_LEARN:
423*10491SRishi.Srivatsavai@Sun.COM       return STP_hop_2_state (this, DESIGNATED_PORT);
424*10491SRishi.Srivatsavai@Sun.COM     case DESIGNATED_FORWARD:
425*10491SRishi.Srivatsavai@Sun.COM       return STP_hop_2_state (this, DESIGNATED_PORT);
426*10491SRishi.Srivatsavai@Sun.COM   };
427*10491SRishi.Srivatsavai@Sun.COM 
428*10491SRishi.Srivatsavai@Sun.COM   return False;
429*10491SRishi.Srivatsavai@Sun.COM }
430*10491SRishi.Srivatsavai@Sun.COM 
431*10491SRishi.Srivatsavai@Sun.COM 
432