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