xref: /titanic_51/usr/src/lib/librstp/common/rolesel.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 Selection state machine : 17.22 */
24*4eaa4710SRishi Srivatsavai 
25*4eaa4710SRishi Srivatsavai #include "base.h"
26*4eaa4710SRishi Srivatsavai #include "stpm.h"
27*4eaa4710SRishi Srivatsavai #include "stp_vectors.h"
28*4eaa4710SRishi Srivatsavai 
29*4eaa4710SRishi Srivatsavai #define STATES { \
30*4eaa4710SRishi Srivatsavai   CHOOSE(INIT_BRIDGE),      \
31*4eaa4710SRishi Srivatsavai   CHOOSE(ROLE_SELECTION)   \
32*4eaa4710SRishi Srivatsavai }
33*4eaa4710SRishi Srivatsavai 
34*4eaa4710SRishi Srivatsavai #define GET_STATE_NAME STP_rolesel_get_state_name
35*4eaa4710SRishi Srivatsavai #include "choose.h"
36*4eaa4710SRishi Srivatsavai 
37*4eaa4710SRishi Srivatsavai #if 0
38*4eaa4710SRishi Srivatsavai void stp_dbg_break_point (PORT_T * port, STPM_T* stpm)
39*4eaa4710SRishi Srivatsavai {
40*4eaa4710SRishi Srivatsavai }
41*4eaa4710SRishi Srivatsavai #endif
42*4eaa4710SRishi Srivatsavai 
43*4eaa4710SRishi Srivatsavai static Bool
44*4eaa4710SRishi Srivatsavai _is_backup_port (PORT_T* port, STPM_T* this)
45*4eaa4710SRishi Srivatsavai {
46*4eaa4710SRishi Srivatsavai   if (!STP_VECT_compare_bridge_id
47*4eaa4710SRishi Srivatsavai       (&port->portPrio.design_bridge, &this->BrId)) {
48*4eaa4710SRishi Srivatsavai #if 0 /* def STP_DBG */
49*4eaa4710SRishi Srivatsavai     if (port->info->debug) {
50*4eaa4710SRishi Srivatsavai       STP_VECT_br_id_print ("portPrio.design_bridge",
51*4eaa4710SRishi Srivatsavai                             &port->portPrio.design_bridge, True);
52*4eaa4710SRishi Srivatsavai       STP_VECT_br_id_print ("            this->BrId",
53*4eaa4710SRishi Srivatsavai                             &this->BrId, True);
54*4eaa4710SRishi Srivatsavai     }
55*4eaa4710SRishi Srivatsavai     stp_dbg_break_point (port, this);
56*4eaa4710SRishi Srivatsavai #endif
57*4eaa4710SRishi Srivatsavai     return True;
58*4eaa4710SRishi Srivatsavai   } else {
59*4eaa4710SRishi Srivatsavai     return False;
60*4eaa4710SRishi Srivatsavai   }
61*4eaa4710SRishi Srivatsavai }
62*4eaa4710SRishi Srivatsavai 
63*4eaa4710SRishi Srivatsavai /* ARGSUSED */
64*4eaa4710SRishi Srivatsavai static void
65*4eaa4710SRishi Srivatsavai setRoleSelected (char* reason, STPM_T* stpm, PORT_T* port,
66*4eaa4710SRishi Srivatsavai                 PORT_ROLE_T newRole)
67*4eaa4710SRishi Srivatsavai {
68*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
69*4eaa4710SRishi Srivatsavai   char* new_role_name;
70*4eaa4710SRishi Srivatsavai #endif
71*4eaa4710SRishi Srivatsavai 
72*4eaa4710SRishi Srivatsavai   port->selectedRole = newRole;
73*4eaa4710SRishi Srivatsavai 
74*4eaa4710SRishi Srivatsavai   if (newRole == port->role)
75*4eaa4710SRishi Srivatsavai     return;
76*4eaa4710SRishi Srivatsavai 
77*4eaa4710SRishi Srivatsavai   switch (newRole) {
78*4eaa4710SRishi Srivatsavai     case DisabledPort:
79*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
80*4eaa4710SRishi Srivatsavai       new_role_name = "Disabled";
81*4eaa4710SRishi Srivatsavai #endif
82*4eaa4710SRishi Srivatsavai       break;
83*4eaa4710SRishi Srivatsavai     case AlternatePort:
84*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
85*4eaa4710SRishi Srivatsavai       new_role_name = "Alternate";
86*4eaa4710SRishi Srivatsavai #endif
87*4eaa4710SRishi Srivatsavai       break;
88*4eaa4710SRishi Srivatsavai     case BackupPort:
89*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
90*4eaa4710SRishi Srivatsavai       new_role_name = "Backup";
91*4eaa4710SRishi Srivatsavai #endif
92*4eaa4710SRishi Srivatsavai       break;
93*4eaa4710SRishi Srivatsavai     case RootPort:
94*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
95*4eaa4710SRishi Srivatsavai       new_role_name = "Root";
96*4eaa4710SRishi Srivatsavai #endif
97*4eaa4710SRishi Srivatsavai       break;
98*4eaa4710SRishi Srivatsavai     case DesignatedPort:
99*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
100*4eaa4710SRishi Srivatsavai       new_role_name = "Designated";
101*4eaa4710SRishi Srivatsavai #endif
102*4eaa4710SRishi Srivatsavai       break;
103*4eaa4710SRishi Srivatsavai     case NonStpPort:
104*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
105*4eaa4710SRishi Srivatsavai       new_role_name = "NonStp";
106*4eaa4710SRishi Srivatsavai #endif
107*4eaa4710SRishi Srivatsavai       port->role = newRole;
108*4eaa4710SRishi Srivatsavai       break;
109*4eaa4710SRishi Srivatsavai     default:
110*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
111*4eaa4710SRishi Srivatsavai       stp_trace ("%s-%s:port %s => Unknown (%d ?)",
112*4eaa4710SRishi Srivatsavai                  reason, stpm->name, port->port_name, (int) newRole);
113*4eaa4710SRishi Srivatsavai #else
114*4eaa4710SRishi Srivatsavai       abort();
115*4eaa4710SRishi Srivatsavai #endif
116*4eaa4710SRishi Srivatsavai       return;
117*4eaa4710SRishi Srivatsavai   }
118*4eaa4710SRishi Srivatsavai 
119*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
120*4eaa4710SRishi Srivatsavai   if (port->roletrns->debug)
121*4eaa4710SRishi Srivatsavai     stp_trace ("%s(%s-%s) => %s",
122*4eaa4710SRishi Srivatsavai                reason, stpm->name, port->port_name, new_role_name);
123*4eaa4710SRishi Srivatsavai #endif
124*4eaa4710SRishi Srivatsavai }
125*4eaa4710SRishi Srivatsavai 
126*4eaa4710SRishi Srivatsavai static void
127*4eaa4710SRishi Srivatsavai updtRoleDisableBridge (STPM_T* this)
128*4eaa4710SRishi Srivatsavai {               /* 17.10.20 */
129*4eaa4710SRishi Srivatsavai   register PORT_T *port;
130*4eaa4710SRishi Srivatsavai 
131*4eaa4710SRishi Srivatsavai   for (port = this->ports; port; port = port->next) {
132*4eaa4710SRishi Srivatsavai     port->selectedRole = DisabledPort;
133*4eaa4710SRishi Srivatsavai   }
134*4eaa4710SRishi Srivatsavai }
135*4eaa4710SRishi Srivatsavai 
136*4eaa4710SRishi Srivatsavai static void
137*4eaa4710SRishi Srivatsavai clearReselectBridge (STPM_T* this)
138*4eaa4710SRishi Srivatsavai {               /* 17.19.1 */
139*4eaa4710SRishi Srivatsavai   register PORT_T *port;
140*4eaa4710SRishi Srivatsavai 
141*4eaa4710SRishi Srivatsavai   for (port = this->ports; port; port = port->next) {
142*4eaa4710SRishi Srivatsavai     port->reselect = False;
143*4eaa4710SRishi Srivatsavai   }
144*4eaa4710SRishi Srivatsavai }
145*4eaa4710SRishi Srivatsavai 
146*4eaa4710SRishi Srivatsavai static void
147*4eaa4710SRishi Srivatsavai updtRootPrio (STATE_MACH_T* this)
148*4eaa4710SRishi Srivatsavai {
149*4eaa4710SRishi Srivatsavai   PRIO_VECTOR_T rootPathPrio;   /* 17.4.2.2 */
150*4eaa4710SRishi Srivatsavai   register PORT_T *port;
151*4eaa4710SRishi Srivatsavai   register STPM_T *stpm;
152*4eaa4710SRishi Srivatsavai   register unsigned int dm;
153*4eaa4710SRishi Srivatsavai 
154*4eaa4710SRishi Srivatsavai   stpm = this->owner.stpm;
155*4eaa4710SRishi Srivatsavai 
156*4eaa4710SRishi Srivatsavai   for (port = stpm->ports; port; port = port->next) {
157*4eaa4710SRishi Srivatsavai     if (port->admin_non_stp) {
158*4eaa4710SRishi Srivatsavai       continue;
159*4eaa4710SRishi Srivatsavai     }
160*4eaa4710SRishi Srivatsavai 
161*4eaa4710SRishi Srivatsavai     if (Disabled == port->infoIs)
162*4eaa4710SRishi Srivatsavai       continue;
163*4eaa4710SRishi Srivatsavai     if (Aged == port->infoIs)
164*4eaa4710SRishi Srivatsavai       continue;
165*4eaa4710SRishi Srivatsavai     if (Mine == port->infoIs) {
166*4eaa4710SRishi Srivatsavai #if 0 /* def STP_DBG */
167*4eaa4710SRishi Srivatsavai       stp_dbg_break_point (port); /* for debugger break point */
168*4eaa4710SRishi Srivatsavai #endif
169*4eaa4710SRishi Srivatsavai       continue;
170*4eaa4710SRishi Srivatsavai     }
171*4eaa4710SRishi Srivatsavai 
172*4eaa4710SRishi Srivatsavai     STP_VECT_copy (&rootPathPrio, &port->portPrio);
173*4eaa4710SRishi Srivatsavai     rootPathPrio.root_path_cost += port->operPCost;
174*4eaa4710SRishi Srivatsavai 
175*4eaa4710SRishi Srivatsavai     if (STP_VECT_compare_vector (&rootPathPrio, &stpm->rootPrio) < 0) {
176*4eaa4710SRishi Srivatsavai       STP_VECT_copy (&stpm->rootPrio, &rootPathPrio);
177*4eaa4710SRishi Srivatsavai       STP_copy_times (&stpm->rootTimes, &port->portTimes);
178*4eaa4710SRishi Srivatsavai       dm = (8 +  stpm->rootTimes.MaxAge) / 16;
179*4eaa4710SRishi Srivatsavai       if (!dm)
180*4eaa4710SRishi Srivatsavai         dm = 1;
181*4eaa4710SRishi Srivatsavai       stpm->rootTimes.MessageAge += dm;
182*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
183*4eaa4710SRishi Srivatsavai       if (port->roletrns->debug)
184*4eaa4710SRishi Srivatsavai           stp_trace ("updtRootPrio: dm=%d rootTimes.MessageAge=%d on port %s",
185*4eaa4710SRishi Srivatsavai                  (int) dm, (int) stpm->rootTimes.MessageAge,
186*4eaa4710SRishi Srivatsavai                  port->port_name);
187*4eaa4710SRishi Srivatsavai #endif
188*4eaa4710SRishi Srivatsavai     }
189*4eaa4710SRishi Srivatsavai   }
190*4eaa4710SRishi Srivatsavai }
191*4eaa4710SRishi Srivatsavai 
192*4eaa4710SRishi Srivatsavai static void
193*4eaa4710SRishi Srivatsavai updtRolesBridge (STATE_MACH_T* this)
194*4eaa4710SRishi Srivatsavai {               /* 17.19.21 */
195*4eaa4710SRishi Srivatsavai   register PORT_T* port;
196*4eaa4710SRishi Srivatsavai   register STPM_T* stpm;
197*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
198*4eaa4710SRishi Srivatsavai   PORT_ID old_root_port; /* for tracing of root port changing */
199*4eaa4710SRishi Srivatsavai #endif
200*4eaa4710SRishi Srivatsavai 
201*4eaa4710SRishi Srivatsavai   stpm = this->owner.stpm;
202*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
203*4eaa4710SRishi Srivatsavai   old_root_port = stpm->rootPortId;
204*4eaa4710SRishi Srivatsavai #endif
205*4eaa4710SRishi Srivatsavai 
206*4eaa4710SRishi Srivatsavai   STP_VECT_create (&stpm->rootPrio, &stpm->BrId, 0, &stpm->BrId, 0, 0);
207*4eaa4710SRishi Srivatsavai   STP_copy_times (&stpm->rootTimes, &stpm->BrTimes);
208*4eaa4710SRishi Srivatsavai   stpm->rootPortId = 0;
209*4eaa4710SRishi Srivatsavai 
210*4eaa4710SRishi Srivatsavai   updtRootPrio (this);
211*4eaa4710SRishi Srivatsavai 
212*4eaa4710SRishi Srivatsavai   for (port = stpm->ports; port; port = port->next) {
213*4eaa4710SRishi Srivatsavai     if (port->admin_non_stp) {
214*4eaa4710SRishi Srivatsavai       continue;
215*4eaa4710SRishi Srivatsavai     }
216*4eaa4710SRishi Srivatsavai     STP_VECT_create (&port->designPrio,
217*4eaa4710SRishi Srivatsavai              &stpm->rootPrio.root_bridge,
218*4eaa4710SRishi Srivatsavai              stpm->rootPrio.root_path_cost,
219*4eaa4710SRishi Srivatsavai              &stpm->BrId, port->port_id, port->port_id);
220*4eaa4710SRishi Srivatsavai     STP_copy_times (&port->designTimes, &stpm->rootTimes);
221*4eaa4710SRishi Srivatsavai 
222*4eaa4710SRishi Srivatsavai #if 0
223*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
224*4eaa4710SRishi Srivatsavai     if (port->roletrns->debug) {
225*4eaa4710SRishi Srivatsavai       STP_VECT_br_id_print ("ch:designPrio.design_bridge",
226*4eaa4710SRishi Srivatsavai                             &port->designPrio.design_bridge, True);
227*4eaa4710SRishi Srivatsavai     }
228*4eaa4710SRishi Srivatsavai #endif
229*4eaa4710SRishi Srivatsavai #endif
230*4eaa4710SRishi Srivatsavai   }
231*4eaa4710SRishi Srivatsavai 
232*4eaa4710SRishi Srivatsavai   stpm->rootPortId = stpm->rootPrio.bridge_port;
233*4eaa4710SRishi Srivatsavai 
234*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
235*4eaa4710SRishi Srivatsavai   if (old_root_port != stpm->rootPortId) {
236*4eaa4710SRishi Srivatsavai     if (! stpm->rootPortId) {
237*4eaa4710SRishi Srivatsavai       stp_trace ("bridge %s became root", stpm->name);
238*4eaa4710SRishi Srivatsavai     } else {
239*4eaa4710SRishi Srivatsavai       stp_trace ("bridge %s new root port: %s",
240*4eaa4710SRishi Srivatsavai         stpm->name,
241*4eaa4710SRishi Srivatsavai         STP_stpm_get_port_name_by_id (stpm, stpm->rootPortId));
242*4eaa4710SRishi Srivatsavai     }
243*4eaa4710SRishi Srivatsavai   }
244*4eaa4710SRishi Srivatsavai #endif
245*4eaa4710SRishi Srivatsavai 
246*4eaa4710SRishi Srivatsavai   for (port = stpm->ports; port; port = port->next) {
247*4eaa4710SRishi Srivatsavai     if (port->admin_non_stp) {
248*4eaa4710SRishi Srivatsavai       setRoleSelected ("Non", stpm, port, NonStpPort);
249*4eaa4710SRishi Srivatsavai       port->forward = port->learn = True;
250*4eaa4710SRishi Srivatsavai       continue;
251*4eaa4710SRishi Srivatsavai     }
252*4eaa4710SRishi Srivatsavai 
253*4eaa4710SRishi Srivatsavai     switch (port->infoIs) {
254*4eaa4710SRishi Srivatsavai       case Disabled:
255*4eaa4710SRishi Srivatsavai         setRoleSelected ("Dis", stpm, port, DisabledPort);
256*4eaa4710SRishi Srivatsavai         break;
257*4eaa4710SRishi Srivatsavai       case Aged:
258*4eaa4710SRishi Srivatsavai         setRoleSelected ("Age", stpm, port, DesignatedPort);
259*4eaa4710SRishi Srivatsavai         port->updtInfo = True;
260*4eaa4710SRishi Srivatsavai         break;
261*4eaa4710SRishi Srivatsavai       case Mine:
262*4eaa4710SRishi Srivatsavai         setRoleSelected ("Mine", stpm, port, DesignatedPort);
263*4eaa4710SRishi Srivatsavai         if (0 != STP_VECT_compare_vector (&port->portPrio,
264*4eaa4710SRishi Srivatsavai                       &port->designPrio) ||
265*4eaa4710SRishi Srivatsavai             0 != STP_compare_times (&port->portTimes,
266*4eaa4710SRishi Srivatsavai                   &port->designTimes)) {
267*4eaa4710SRishi Srivatsavai             port->updtInfo = True;
268*4eaa4710SRishi Srivatsavai         }
269*4eaa4710SRishi Srivatsavai         break;
270*4eaa4710SRishi Srivatsavai       case Received:
271*4eaa4710SRishi Srivatsavai         if (stpm->rootPortId == port->port_id) {
272*4eaa4710SRishi Srivatsavai           setRoleSelected ("Rec", stpm, port, RootPort);
273*4eaa4710SRishi Srivatsavai         } else if (STP_VECT_compare_vector (&port->designPrio, &port->portPrio) < 0) {
274*4eaa4710SRishi Srivatsavai           /* Note: this important piece has been inserted after
275*4eaa4710SRishi Srivatsavai            * discussion with Mick Sieman and reading 802.1y Z1 */
276*4eaa4710SRishi Srivatsavai           setRoleSelected ("Rec", stpm, port, DesignatedPort);
277*4eaa4710SRishi Srivatsavai           port->updtInfo = True;
278*4eaa4710SRishi Srivatsavai           break;
279*4eaa4710SRishi Srivatsavai         } else {
280*4eaa4710SRishi Srivatsavai           if (_is_backup_port (port, stpm)) {
281*4eaa4710SRishi Srivatsavai             setRoleSelected ("rec", stpm, port, BackupPort);
282*4eaa4710SRishi Srivatsavai           } else {
283*4eaa4710SRishi Srivatsavai             setRoleSelected ("rec", stpm, port, AlternatePort);
284*4eaa4710SRishi Srivatsavai           }
285*4eaa4710SRishi Srivatsavai         }
286*4eaa4710SRishi Srivatsavai         port->updtInfo = False;
287*4eaa4710SRishi Srivatsavai         break;
288*4eaa4710SRishi Srivatsavai       default:
289*4eaa4710SRishi Srivatsavai         stp_trace ("undef infoIs=%d", (int) port->infoIs);
290*4eaa4710SRishi Srivatsavai         break;
291*4eaa4710SRishi Srivatsavai     }
292*4eaa4710SRishi Srivatsavai   }
293*4eaa4710SRishi Srivatsavai 
294*4eaa4710SRishi Srivatsavai }
295*4eaa4710SRishi Srivatsavai 
296*4eaa4710SRishi Srivatsavai 
297*4eaa4710SRishi Srivatsavai static Bool
298*4eaa4710SRishi Srivatsavai setSelectedBridge (STPM_T* this)
299*4eaa4710SRishi Srivatsavai {
300*4eaa4710SRishi Srivatsavai   register PORT_T* port;
301*4eaa4710SRishi Srivatsavai 
302*4eaa4710SRishi Srivatsavai   for (port = this->ports; port; port = port->next) {
303*4eaa4710SRishi Srivatsavai     if (port->reselect) {
304*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
305*4eaa4710SRishi Srivatsavai       stp_trace ("setSelectedBridge: TRUE=reselect on port %s", port->port_name);
306*4eaa4710SRishi Srivatsavai #endif
307*4eaa4710SRishi Srivatsavai       return False;
308*4eaa4710SRishi Srivatsavai     }
309*4eaa4710SRishi Srivatsavai   }
310*4eaa4710SRishi Srivatsavai 
311*4eaa4710SRishi Srivatsavai   for (port = this->ports; port; port = port->next) {
312*4eaa4710SRishi Srivatsavai     port->selected = True;
313*4eaa4710SRishi Srivatsavai   }
314*4eaa4710SRishi Srivatsavai 
315*4eaa4710SRishi Srivatsavai   return True;
316*4eaa4710SRishi Srivatsavai }
317*4eaa4710SRishi Srivatsavai 
318*4eaa4710SRishi Srivatsavai void
319*4eaa4710SRishi Srivatsavai STP_rolesel_enter_state (STATE_MACH_T* this)
320*4eaa4710SRishi Srivatsavai {
321*4eaa4710SRishi Srivatsavai   STPM_T* stpm;
322*4eaa4710SRishi Srivatsavai 
323*4eaa4710SRishi Srivatsavai   stpm = this->owner.stpm;
324*4eaa4710SRishi Srivatsavai 
325*4eaa4710SRishi Srivatsavai   switch (this->State) {
326*4eaa4710SRishi Srivatsavai     case BEGIN:
327*4eaa4710SRishi Srivatsavai     case INIT_BRIDGE:
328*4eaa4710SRishi Srivatsavai       updtRoleDisableBridge (stpm);
329*4eaa4710SRishi Srivatsavai       break;
330*4eaa4710SRishi Srivatsavai     case ROLE_SELECTION:
331*4eaa4710SRishi Srivatsavai       clearReselectBridge (stpm);
332*4eaa4710SRishi Srivatsavai       updtRolesBridge (this);
333*4eaa4710SRishi Srivatsavai       (void) setSelectedBridge (stpm);
334*4eaa4710SRishi Srivatsavai       break;
335*4eaa4710SRishi Srivatsavai   }
336*4eaa4710SRishi Srivatsavai }
337*4eaa4710SRishi Srivatsavai 
338*4eaa4710SRishi Srivatsavai Bool
339*4eaa4710SRishi Srivatsavai STP_rolesel_check_conditions (STATE_MACH_T* s)
340*4eaa4710SRishi Srivatsavai {
341*4eaa4710SRishi Srivatsavai   STPM_T* stpm;
342*4eaa4710SRishi Srivatsavai   register PORT_T* port;
343*4eaa4710SRishi Srivatsavai 
344*4eaa4710SRishi Srivatsavai   /*
345*4eaa4710SRishi Srivatsavai    * This doesn't look right.  Why should we hop state twice in a single check
346*4eaa4710SRishi Srivatsavai    * condition call?  It means we can never perform the enter-state action for
347*4eaa4710SRishi Srivatsavai    * INIT_BRIDGE.
348*4eaa4710SRishi Srivatsavai    */
349*4eaa4710SRishi Srivatsavai #ifdef carlsonj_removed
350*4eaa4710SRishi Srivatsavai   if (BEGIN == s->State) {
351*4eaa4710SRishi Srivatsavai     (void) STP_hop_2_state (s, INIT_BRIDGE);
352*4eaa4710SRishi Srivatsavai   }
353*4eaa4710SRishi Srivatsavai #endif
354*4eaa4710SRishi Srivatsavai 
355*4eaa4710SRishi Srivatsavai   switch (s->State) {
356*4eaa4710SRishi Srivatsavai     case BEGIN:
357*4eaa4710SRishi Srivatsavai       return STP_hop_2_state (s, INIT_BRIDGE);
358*4eaa4710SRishi Srivatsavai     case INIT_BRIDGE:
359*4eaa4710SRishi Srivatsavai       return STP_hop_2_state (s, ROLE_SELECTION);
360*4eaa4710SRishi Srivatsavai     case ROLE_SELECTION:
361*4eaa4710SRishi Srivatsavai       stpm = s->owner.stpm;
362*4eaa4710SRishi Srivatsavai       for (port = stpm->ports; port; port = port->next) {
363*4eaa4710SRishi Srivatsavai         if (port->reselect) {
364*4eaa4710SRishi Srivatsavai           /* stp_trace ("reselect on port %s", port->port_name); */
365*4eaa4710SRishi Srivatsavai           return STP_hop_2_state (s, ROLE_SELECTION);
366*4eaa4710SRishi Srivatsavai         }
367*4eaa4710SRishi Srivatsavai       }
368*4eaa4710SRishi Srivatsavai       break;
369*4eaa4710SRishi Srivatsavai   }
370*4eaa4710SRishi Srivatsavai 
371*4eaa4710SRishi Srivatsavai   return False;
372*4eaa4710SRishi Srivatsavai }
373*4eaa4710SRishi Srivatsavai 
374*4eaa4710SRishi Srivatsavai void
375*4eaa4710SRishi Srivatsavai STP_rolesel_update_stpm (STPM_T* this)
376*4eaa4710SRishi Srivatsavai {
377*4eaa4710SRishi Srivatsavai   register PORT_T* port;
378*4eaa4710SRishi Srivatsavai   PRIO_VECTOR_T rootPathPrio;   /* 17.4.2.2 */
379*4eaa4710SRishi Srivatsavai 
380*4eaa4710SRishi Srivatsavai   stp_trace ("%s", "??? STP_rolesel_update_stpm ???");
381*4eaa4710SRishi Srivatsavai   STP_VECT_create (&rootPathPrio, &this->BrId, 0, &this->BrId, 0, 0);
382*4eaa4710SRishi Srivatsavai 
383*4eaa4710SRishi Srivatsavai   if (!this->rootPortId ||
384*4eaa4710SRishi Srivatsavai       STP_VECT_compare_vector (&rootPathPrio, &this->rootPrio) < 0) {
385*4eaa4710SRishi Srivatsavai     STP_VECT_copy (&this->rootPrio, &rootPathPrio);
386*4eaa4710SRishi Srivatsavai   }
387*4eaa4710SRishi Srivatsavai 
388*4eaa4710SRishi Srivatsavai   for (port = this->ports; port; port = port->next) {
389*4eaa4710SRishi Srivatsavai     STP_VECT_create (&port->designPrio,
390*4eaa4710SRishi Srivatsavai              &this->rootPrio.root_bridge,
391*4eaa4710SRishi Srivatsavai              this->rootPrio.root_path_cost,
392*4eaa4710SRishi Srivatsavai              &this->BrId, port->port_id, port->port_id);
393*4eaa4710SRishi Srivatsavai     if (Received != port->infoIs || this->rootPortId == port->port_id) {
394*4eaa4710SRishi Srivatsavai       STP_VECT_copy (&port->portPrio, &port->designPrio);
395*4eaa4710SRishi Srivatsavai     }
396*4eaa4710SRishi Srivatsavai     port->reselect = True;
397*4eaa4710SRishi Srivatsavai     port->selected = False;
398*4eaa4710SRishi Srivatsavai   }
399*4eaa4710SRishi Srivatsavai }
400*4eaa4710SRishi Srivatsavai 
401