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