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