diff options
Diffstat (limited to 'usr/src/lib/librstp/common/port.c')
| -rw-r--r-- | usr/src/lib/librstp/common/port.c | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/usr/src/lib/librstp/common/port.c b/usr/src/lib/librstp/common/port.c new file mode 100644 index 0000000000..30ba26a72e --- /dev/null +++ b/usr/src/lib/librstp/common/port.c @@ -0,0 +1,253 @@ +/************************************************************************ + * RSTP library - Rapid Spanning Tree (802.1t, 802.1w) + * Copyright (C) 2001-2003 Optical Access + * Author: Alex Rozin + * + * This file is part of RSTP library. + * + * RSTP library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; version 2.1 + * + * RSTP library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with RSTP library; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + **********************************************************************/ + +/* STP PORT instance : 17.18, 17.15 */ + +#include "base.h" +#include "stpm.h" +#include "stp_in.h" + +/* #include "rolesel.h" */ +#include "portinfo.h" +#include "roletrns.h" +#include "sttrans.h" +#include "topoch.h" +#include "migrate.h" +#include "transmit.h" +#include "p2p.h" +#include "pcost.h" +#include "edge.h" + +#include "stp_to.h" /* for STP_OUT_get_port_name & STP_OUT_get_port_link_status */ + +int port_trace_flags; + +PORT_T * +STP_port_create (STPM_T* stpm, int port_index) +{ + PORT_T* this; + UID_STP_PORT_CFG_T port_cfg; + register int iii; + unsigned short port_prio; + + /* check, if the port has just been added */ + for (this = stpm->ports; this; this = this->next) { + if (this->port_index == port_index) { + return NULL; + } + } + + STP_NEW_IN_LIST(this, PORT_T, stpm->ports, "port create"); + + this->owner = stpm; + this->machines = NULL; + this->port_index = port_index; + this->port_name = strdup (STP_OUT_get_port_name (port_index)); + this->uptime = 0; + + STP_OUT_get_init_port_cfg (stpm->vlan_id, port_index, &port_cfg); + port_prio = port_cfg.port_priority; + this->admin_non_stp = port_cfg.admin_non_stp; + this->adminEdge = port_cfg.admin_edge; + this->adminPCost = port_cfg.admin_port_path_cost; + this->adminPointToPointMac = port_cfg.admin_point2point; + + this->LinkDelay = DEF_LINK_DELAY; + this->port_id = (port_prio << 8) + port_index; + + iii = 0; + this->timers[iii++] = &this->fdWhile; + this->timers[iii++] = &this->helloWhen; + this->timers[iii++] = &this->mdelayWhile; + this->timers[iii++] = &this->rbWhile; + this->timers[iii++] = &this->rcvdInfoWhile; + this->timers[iii++] = &this->rrWhile; + this->timers[iii++] = &this->tcWhile; + this->timers[iii++] = &this->txCount; + this->timers[iii++] = &this->lnkWhile; + + /* create and bind port state machines */ + STP_STATE_MACH_IN_LIST(topoch); + + STP_STATE_MACH_IN_LIST(migrate); + + STP_STATE_MACH_IN_LIST(p2p); + + STP_STATE_MACH_IN_LIST(edge); + + STP_STATE_MACH_IN_LIST(pcost) + + STP_STATE_MACH_IN_LIST(info); + + STP_STATE_MACH_IN_LIST(roletrns); + + STP_STATE_MACH_IN_LIST(sttrans); + + STP_STATE_MACH_IN_LIST(transmit); + +#ifdef STP_DBG + +#if 0 + this->roletrns->ignoreHop2State = 14; /* DESIGNATED_PORT; */ + this->info->ignoreHop2State = 3; /* CURRENT */ + this->transmit->ignoreHop2State = 3; /* IDLE */ + this->edge->ignoreHop2State = 0; /* DISABLED; */ +#endif + +#if 0 + this->info->debug = 1; + this->pcost->debug = 1; + this->p2p->debug = 1; + this->edge->debug = 1; + this->migrate->debug = 1; + this->sttrans->debug = 1; + this->topoch->debug = 1; + this->roletrns->debug = 1; +#endif + this->sttrans->debug = 1; + +#endif + return this; +} + +void +STP_port_init (PORT_T* this, STPM_T* stpm, Bool check_link) +{ + if (check_link) { + this->adminEnable = STP_OUT_get_port_link_status (this->port_index); + STP_VECT_create (&this->designPrio, + &stpm->BrId, + 0, + &stpm->BrId, + this->port_id, + this->port_id); + STP_copy_times (&this->designTimes, &stpm->rootTimes); + } + + /* reset timers */ + this->fdWhile = + this->helloWhen = + this->mdelayWhile = + this->rbWhile = + this->rcvdInfoWhile = + this->rrWhile = + this->tcWhile = + this->txCount = 0; + + this->msgPortRole = RSTP_PORT_ROLE_UNKN; + this->selectedRole = DisabledPort; + this->sendRSTP = True; + this->operSpeed = STP_OUT_get_port_oper_speed (this->port_index); + this->p2p_recompute = True; +} + +void +STP_port_delete (PORT_T* this) +{ + STPM_T* stpm; + register PORT_T* prev; + register PORT_T* tmp; + register STATE_MACH_T* stater; + register void* pv; + + stpm = this->owner; + + free (this->port_name); + for (stater = this->machines; stater; ) { + pv = (void*) stater->next; + STP_state_mach_delete (stater); + stater = (STATE_MACH_T*) pv; + } + + prev = NULL; + for (tmp = stpm->ports; tmp; tmp = tmp->next) { + if (tmp->port_index == this->port_index) { + if (prev) { + prev->next = this->next; + } else { + stpm->ports = this->next; + } + STP_FREE(this, "stp instance"); + break; + } + prev = tmp; + } +} + +int +STP_port_rx_bpdu (PORT_T* this, BPDU_T* bpdu, size_t len) +{ + STP_info_rx_bpdu (this, bpdu, len); + + return 0; +} + +#ifdef STP_DBG +int STP_port_trace_state_machine (PORT_T* this, char* mach_name, int enadis) +{ + STATE_MACH_T *stater; + int nmatch = 0; + + for (stater = this->machines; stater; stater = stater->next) { + if (! strcmp (mach_name, "all") || ! strcmp (mach_name, stater->name)) { + if (stater->debug != enadis) + { + stp_trace ("port %s on %s trace %-8s (was %s) now %s", + this->port_name, this->owner->name, + stater->name, + stater->debug ? " enabled" :"disabled", + enadis ? " enabled" :"disabled"); + } + stater->debug = enadis; + nmatch++; + } + } + + if (nmatch == 0) { + stp_trace("port %s no such state machine as '%s'", this->port_name, + mach_name); + return STP_No_Such_State_Machine; + } + + return 0; +} + +void STP_port_trace_flags (char* title, PORT_T* this) +{ + unsigned long flag = 0L; + + if (!port_trace_flags) return; + + if (this->reRoot) flag |= 0x000001L; + if (this->sync) flag |= 0x000002L; + if (this->synced) flag |= 0x000004L; + + if (this->proposed) flag |= 0x000010L; + if (this->proposing) flag |= 0x000020L; + if (this->agreed) flag |= 0x000040L; + if (this->updtInfo) flag |= 0x000080L; + + if (this->operEdge) flag |= 0x000100L; + stp_trace (" %-12s: flags=0x%04lx fdWhile=%d port=%s", title, flag, this->fdWhile, this->port_name); +} + +#endif |
