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 /* STP PORT instance : 17.18, 17.15 */ 24*10491SRishi.Srivatsavai@Sun.COM 25*10491SRishi.Srivatsavai@Sun.COM #include "base.h" 26*10491SRishi.Srivatsavai@Sun.COM #include "stpm.h" 27*10491SRishi.Srivatsavai@Sun.COM #include "stp_in.h" 28*10491SRishi.Srivatsavai@Sun.COM 29*10491SRishi.Srivatsavai@Sun.COM /* #include "rolesel.h" */ 30*10491SRishi.Srivatsavai@Sun.COM #include "portinfo.h" 31*10491SRishi.Srivatsavai@Sun.COM #include "roletrns.h" 32*10491SRishi.Srivatsavai@Sun.COM #include "sttrans.h" 33*10491SRishi.Srivatsavai@Sun.COM #include "topoch.h" 34*10491SRishi.Srivatsavai@Sun.COM #include "migrate.h" 35*10491SRishi.Srivatsavai@Sun.COM #include "transmit.h" 36*10491SRishi.Srivatsavai@Sun.COM #include "p2p.h" 37*10491SRishi.Srivatsavai@Sun.COM #include "pcost.h" 38*10491SRishi.Srivatsavai@Sun.COM #include "edge.h" 39*10491SRishi.Srivatsavai@Sun.COM 40*10491SRishi.Srivatsavai@Sun.COM #include "stp_to.h" /* for STP_OUT_get_port_name & STP_OUT_get_port_link_status */ 41*10491SRishi.Srivatsavai@Sun.COM 42*10491SRishi.Srivatsavai@Sun.COM int port_trace_flags; 43*10491SRishi.Srivatsavai@Sun.COM 44*10491SRishi.Srivatsavai@Sun.COM PORT_T * 45*10491SRishi.Srivatsavai@Sun.COM STP_port_create (STPM_T* stpm, int port_index) 46*10491SRishi.Srivatsavai@Sun.COM { 47*10491SRishi.Srivatsavai@Sun.COM PORT_T* this; 48*10491SRishi.Srivatsavai@Sun.COM UID_STP_PORT_CFG_T port_cfg; 49*10491SRishi.Srivatsavai@Sun.COM register int iii; 50*10491SRishi.Srivatsavai@Sun.COM unsigned short port_prio; 51*10491SRishi.Srivatsavai@Sun.COM 52*10491SRishi.Srivatsavai@Sun.COM /* check, if the port has just been added */ 53*10491SRishi.Srivatsavai@Sun.COM for (this = stpm->ports; this; this = this->next) { 54*10491SRishi.Srivatsavai@Sun.COM if (this->port_index == port_index) { 55*10491SRishi.Srivatsavai@Sun.COM return NULL; 56*10491SRishi.Srivatsavai@Sun.COM } 57*10491SRishi.Srivatsavai@Sun.COM } 58*10491SRishi.Srivatsavai@Sun.COM 59*10491SRishi.Srivatsavai@Sun.COM STP_NEW_IN_LIST(this, PORT_T, stpm->ports, "port create"); 60*10491SRishi.Srivatsavai@Sun.COM 61*10491SRishi.Srivatsavai@Sun.COM this->owner = stpm; 62*10491SRishi.Srivatsavai@Sun.COM this->machines = NULL; 63*10491SRishi.Srivatsavai@Sun.COM this->port_index = port_index; 64*10491SRishi.Srivatsavai@Sun.COM this->port_name = strdup (STP_OUT_get_port_name (port_index)); 65*10491SRishi.Srivatsavai@Sun.COM this->uptime = 0; 66*10491SRishi.Srivatsavai@Sun.COM 67*10491SRishi.Srivatsavai@Sun.COM STP_OUT_get_init_port_cfg (stpm->vlan_id, port_index, &port_cfg); 68*10491SRishi.Srivatsavai@Sun.COM port_prio = port_cfg.port_priority; 69*10491SRishi.Srivatsavai@Sun.COM this->admin_non_stp = port_cfg.admin_non_stp; 70*10491SRishi.Srivatsavai@Sun.COM this->adminEdge = port_cfg.admin_edge; 71*10491SRishi.Srivatsavai@Sun.COM this->adminPCost = port_cfg.admin_port_path_cost; 72*10491SRishi.Srivatsavai@Sun.COM this->adminPointToPointMac = port_cfg.admin_point2point; 73*10491SRishi.Srivatsavai@Sun.COM 74*10491SRishi.Srivatsavai@Sun.COM this->LinkDelay = DEF_LINK_DELAY; 75*10491SRishi.Srivatsavai@Sun.COM this->port_id = (port_prio << 8) + port_index; 76*10491SRishi.Srivatsavai@Sun.COM 77*10491SRishi.Srivatsavai@Sun.COM iii = 0; 78*10491SRishi.Srivatsavai@Sun.COM this->timers[iii++] = &this->fdWhile; 79*10491SRishi.Srivatsavai@Sun.COM this->timers[iii++] = &this->helloWhen; 80*10491SRishi.Srivatsavai@Sun.COM this->timers[iii++] = &this->mdelayWhile; 81*10491SRishi.Srivatsavai@Sun.COM this->timers[iii++] = &this->rbWhile; 82*10491SRishi.Srivatsavai@Sun.COM this->timers[iii++] = &this->rcvdInfoWhile; 83*10491SRishi.Srivatsavai@Sun.COM this->timers[iii++] = &this->rrWhile; 84*10491SRishi.Srivatsavai@Sun.COM this->timers[iii++] = &this->tcWhile; 85*10491SRishi.Srivatsavai@Sun.COM this->timers[iii++] = &this->txCount; 86*10491SRishi.Srivatsavai@Sun.COM this->timers[iii++] = &this->lnkWhile; 87*10491SRishi.Srivatsavai@Sun.COM 88*10491SRishi.Srivatsavai@Sun.COM /* create and bind port state machines */ 89*10491SRishi.Srivatsavai@Sun.COM STP_STATE_MACH_IN_LIST(topoch); 90*10491SRishi.Srivatsavai@Sun.COM 91*10491SRishi.Srivatsavai@Sun.COM STP_STATE_MACH_IN_LIST(migrate); 92*10491SRishi.Srivatsavai@Sun.COM 93*10491SRishi.Srivatsavai@Sun.COM STP_STATE_MACH_IN_LIST(p2p); 94*10491SRishi.Srivatsavai@Sun.COM 95*10491SRishi.Srivatsavai@Sun.COM STP_STATE_MACH_IN_LIST(edge); 96*10491SRishi.Srivatsavai@Sun.COM 97*10491SRishi.Srivatsavai@Sun.COM STP_STATE_MACH_IN_LIST(pcost) 98*10491SRishi.Srivatsavai@Sun.COM 99*10491SRishi.Srivatsavai@Sun.COM STP_STATE_MACH_IN_LIST(info); 100*10491SRishi.Srivatsavai@Sun.COM 101*10491SRishi.Srivatsavai@Sun.COM STP_STATE_MACH_IN_LIST(roletrns); 102*10491SRishi.Srivatsavai@Sun.COM 103*10491SRishi.Srivatsavai@Sun.COM STP_STATE_MACH_IN_LIST(sttrans); 104*10491SRishi.Srivatsavai@Sun.COM 105*10491SRishi.Srivatsavai@Sun.COM STP_STATE_MACH_IN_LIST(transmit); 106*10491SRishi.Srivatsavai@Sun.COM 107*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG 108*10491SRishi.Srivatsavai@Sun.COM 109*10491SRishi.Srivatsavai@Sun.COM #if 0 110*10491SRishi.Srivatsavai@Sun.COM this->roletrns->ignoreHop2State = 14; /* DESIGNATED_PORT; */ 111*10491SRishi.Srivatsavai@Sun.COM this->info->ignoreHop2State = 3; /* CURRENT */ 112*10491SRishi.Srivatsavai@Sun.COM this->transmit->ignoreHop2State = 3; /* IDLE */ 113*10491SRishi.Srivatsavai@Sun.COM this->edge->ignoreHop2State = 0; /* DISABLED; */ 114*10491SRishi.Srivatsavai@Sun.COM #endif 115*10491SRishi.Srivatsavai@Sun.COM 116*10491SRishi.Srivatsavai@Sun.COM #if 0 117*10491SRishi.Srivatsavai@Sun.COM this->info->debug = 1; 118*10491SRishi.Srivatsavai@Sun.COM this->pcost->debug = 1; 119*10491SRishi.Srivatsavai@Sun.COM this->p2p->debug = 1; 120*10491SRishi.Srivatsavai@Sun.COM this->edge->debug = 1; 121*10491SRishi.Srivatsavai@Sun.COM this->migrate->debug = 1; 122*10491SRishi.Srivatsavai@Sun.COM this->sttrans->debug = 1; 123*10491SRishi.Srivatsavai@Sun.COM this->topoch->debug = 1; 124*10491SRishi.Srivatsavai@Sun.COM this->roletrns->debug = 1; 125*10491SRishi.Srivatsavai@Sun.COM #endif 126*10491SRishi.Srivatsavai@Sun.COM this->sttrans->debug = 1; 127*10491SRishi.Srivatsavai@Sun.COM 128*10491SRishi.Srivatsavai@Sun.COM #endif 129*10491SRishi.Srivatsavai@Sun.COM return this; 130*10491SRishi.Srivatsavai@Sun.COM } 131*10491SRishi.Srivatsavai@Sun.COM 132*10491SRishi.Srivatsavai@Sun.COM void 133*10491SRishi.Srivatsavai@Sun.COM STP_port_init (PORT_T* this, STPM_T* stpm, Bool check_link) 134*10491SRishi.Srivatsavai@Sun.COM { 135*10491SRishi.Srivatsavai@Sun.COM if (check_link) { 136*10491SRishi.Srivatsavai@Sun.COM this->adminEnable = STP_OUT_get_port_link_status (this->port_index); 137*10491SRishi.Srivatsavai@Sun.COM STP_VECT_create (&this->designPrio, 138*10491SRishi.Srivatsavai@Sun.COM &stpm->BrId, 139*10491SRishi.Srivatsavai@Sun.COM 0, 140*10491SRishi.Srivatsavai@Sun.COM &stpm->BrId, 141*10491SRishi.Srivatsavai@Sun.COM this->port_id, 142*10491SRishi.Srivatsavai@Sun.COM this->port_id); 143*10491SRishi.Srivatsavai@Sun.COM STP_copy_times (&this->designTimes, &stpm->rootTimes); 144*10491SRishi.Srivatsavai@Sun.COM } 145*10491SRishi.Srivatsavai@Sun.COM 146*10491SRishi.Srivatsavai@Sun.COM /* reset timers */ 147*10491SRishi.Srivatsavai@Sun.COM this->fdWhile = 148*10491SRishi.Srivatsavai@Sun.COM this->helloWhen = 149*10491SRishi.Srivatsavai@Sun.COM this->mdelayWhile = 150*10491SRishi.Srivatsavai@Sun.COM this->rbWhile = 151*10491SRishi.Srivatsavai@Sun.COM this->rcvdInfoWhile = 152*10491SRishi.Srivatsavai@Sun.COM this->rrWhile = 153*10491SRishi.Srivatsavai@Sun.COM this->tcWhile = 154*10491SRishi.Srivatsavai@Sun.COM this->txCount = 0; 155*10491SRishi.Srivatsavai@Sun.COM 156*10491SRishi.Srivatsavai@Sun.COM this->msgPortRole = RSTP_PORT_ROLE_UNKN; 157*10491SRishi.Srivatsavai@Sun.COM this->selectedRole = DisabledPort; 158*10491SRishi.Srivatsavai@Sun.COM this->sendRSTP = True; 159*10491SRishi.Srivatsavai@Sun.COM this->operSpeed = STP_OUT_get_port_oper_speed (this->port_index); 160*10491SRishi.Srivatsavai@Sun.COM this->p2p_recompute = True; 161*10491SRishi.Srivatsavai@Sun.COM } 162*10491SRishi.Srivatsavai@Sun.COM 163*10491SRishi.Srivatsavai@Sun.COM void 164*10491SRishi.Srivatsavai@Sun.COM STP_port_delete (PORT_T* this) 165*10491SRishi.Srivatsavai@Sun.COM { 166*10491SRishi.Srivatsavai@Sun.COM STPM_T* stpm; 167*10491SRishi.Srivatsavai@Sun.COM register PORT_T* prev; 168*10491SRishi.Srivatsavai@Sun.COM register PORT_T* tmp; 169*10491SRishi.Srivatsavai@Sun.COM register STATE_MACH_T* stater; 170*10491SRishi.Srivatsavai@Sun.COM register void* pv; 171*10491SRishi.Srivatsavai@Sun.COM 172*10491SRishi.Srivatsavai@Sun.COM stpm = this->owner; 173*10491SRishi.Srivatsavai@Sun.COM 174*10491SRishi.Srivatsavai@Sun.COM free (this->port_name); 175*10491SRishi.Srivatsavai@Sun.COM for (stater = this->machines; stater; ) { 176*10491SRishi.Srivatsavai@Sun.COM pv = (void*) stater->next; 177*10491SRishi.Srivatsavai@Sun.COM STP_state_mach_delete (stater); 178*10491SRishi.Srivatsavai@Sun.COM stater = (STATE_MACH_T*) pv; 179*10491SRishi.Srivatsavai@Sun.COM } 180*10491SRishi.Srivatsavai@Sun.COM 181*10491SRishi.Srivatsavai@Sun.COM prev = NULL; 182*10491SRishi.Srivatsavai@Sun.COM for (tmp = stpm->ports; tmp; tmp = tmp->next) { 183*10491SRishi.Srivatsavai@Sun.COM if (tmp->port_index == this->port_index) { 184*10491SRishi.Srivatsavai@Sun.COM if (prev) { 185*10491SRishi.Srivatsavai@Sun.COM prev->next = this->next; 186*10491SRishi.Srivatsavai@Sun.COM } else { 187*10491SRishi.Srivatsavai@Sun.COM stpm->ports = this->next; 188*10491SRishi.Srivatsavai@Sun.COM } 189*10491SRishi.Srivatsavai@Sun.COM STP_FREE(this, "stp instance"); 190*10491SRishi.Srivatsavai@Sun.COM break; 191*10491SRishi.Srivatsavai@Sun.COM } 192*10491SRishi.Srivatsavai@Sun.COM prev = tmp; 193*10491SRishi.Srivatsavai@Sun.COM } 194*10491SRishi.Srivatsavai@Sun.COM } 195*10491SRishi.Srivatsavai@Sun.COM 196*10491SRishi.Srivatsavai@Sun.COM int 197*10491SRishi.Srivatsavai@Sun.COM STP_port_rx_bpdu (PORT_T* this, BPDU_T* bpdu, size_t len) 198*10491SRishi.Srivatsavai@Sun.COM { 199*10491SRishi.Srivatsavai@Sun.COM STP_info_rx_bpdu (this, bpdu, len); 200*10491SRishi.Srivatsavai@Sun.COM 201*10491SRishi.Srivatsavai@Sun.COM return 0; 202*10491SRishi.Srivatsavai@Sun.COM } 203*10491SRishi.Srivatsavai@Sun.COM 204*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG 205*10491SRishi.Srivatsavai@Sun.COM int STP_port_trace_state_machine (PORT_T* this, char* mach_name, int enadis) 206*10491SRishi.Srivatsavai@Sun.COM { 207*10491SRishi.Srivatsavai@Sun.COM STATE_MACH_T *stater; 208*10491SRishi.Srivatsavai@Sun.COM int nmatch = 0; 209*10491SRishi.Srivatsavai@Sun.COM 210*10491SRishi.Srivatsavai@Sun.COM for (stater = this->machines; stater; stater = stater->next) { 211*10491SRishi.Srivatsavai@Sun.COM if (! strcmp (mach_name, "all") || ! strcmp (mach_name, stater->name)) { 212*10491SRishi.Srivatsavai@Sun.COM if (stater->debug != enadis) 213*10491SRishi.Srivatsavai@Sun.COM { 214*10491SRishi.Srivatsavai@Sun.COM stp_trace ("port %s on %s trace %-8s (was %s) now %s", 215*10491SRishi.Srivatsavai@Sun.COM this->port_name, this->owner->name, 216*10491SRishi.Srivatsavai@Sun.COM stater->name, 217*10491SRishi.Srivatsavai@Sun.COM stater->debug ? " enabled" :"disabled", 218*10491SRishi.Srivatsavai@Sun.COM enadis ? " enabled" :"disabled"); 219*10491SRishi.Srivatsavai@Sun.COM } 220*10491SRishi.Srivatsavai@Sun.COM stater->debug = enadis; 221*10491SRishi.Srivatsavai@Sun.COM nmatch++; 222*10491SRishi.Srivatsavai@Sun.COM } 223*10491SRishi.Srivatsavai@Sun.COM } 224*10491SRishi.Srivatsavai@Sun.COM 225*10491SRishi.Srivatsavai@Sun.COM if (nmatch == 0) { 226*10491SRishi.Srivatsavai@Sun.COM stp_trace("port %s no such state machine as '%s'", this->port_name, 227*10491SRishi.Srivatsavai@Sun.COM mach_name); 228*10491SRishi.Srivatsavai@Sun.COM return STP_No_Such_State_Machine; 229*10491SRishi.Srivatsavai@Sun.COM } 230*10491SRishi.Srivatsavai@Sun.COM 231*10491SRishi.Srivatsavai@Sun.COM return 0; 232*10491SRishi.Srivatsavai@Sun.COM } 233*10491SRishi.Srivatsavai@Sun.COM 234*10491SRishi.Srivatsavai@Sun.COM void STP_port_trace_flags (char* title, PORT_T* this) 235*10491SRishi.Srivatsavai@Sun.COM { 236*10491SRishi.Srivatsavai@Sun.COM unsigned long flag = 0L; 237*10491SRishi.Srivatsavai@Sun.COM 238*10491SRishi.Srivatsavai@Sun.COM if (!port_trace_flags) return; 239*10491SRishi.Srivatsavai@Sun.COM 240*10491SRishi.Srivatsavai@Sun.COM if (this->reRoot) flag |= 0x000001L; 241*10491SRishi.Srivatsavai@Sun.COM if (this->sync) flag |= 0x000002L; 242*10491SRishi.Srivatsavai@Sun.COM if (this->synced) flag |= 0x000004L; 243*10491SRishi.Srivatsavai@Sun.COM 244*10491SRishi.Srivatsavai@Sun.COM if (this->proposed) flag |= 0x000010L; 245*10491SRishi.Srivatsavai@Sun.COM if (this->proposing) flag |= 0x000020L; 246*10491SRishi.Srivatsavai@Sun.COM if (this->agreed) flag |= 0x000040L; 247*10491SRishi.Srivatsavai@Sun.COM if (this->updtInfo) flag |= 0x000080L; 248*10491SRishi.Srivatsavai@Sun.COM 249*10491SRishi.Srivatsavai@Sun.COM if (this->operEdge) flag |= 0x000100L; 250*10491SRishi.Srivatsavai@Sun.COM stp_trace (" %-12s: flags=0x%04lx fdWhile=%d port=%s", title, flag, this->fdWhile, this->port_name); 251*10491SRishi.Srivatsavai@Sun.COM } 252*10491SRishi.Srivatsavai@Sun.COM 253*10491SRishi.Srivatsavai@Sun.COM #endif 254