📄 stp_in.c
字号:
/************************************************************************ * 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. **********************************************************************//* This file contains API from an operation system to the RSTP library */#include "base.h"#include "stpm.h"#include "stp_in.h"#include "stp_to.h"int max_port = 1024;#define INCR100(nev) { nev++; if (nev > 99) nev = 0;}RSTP_EVENT_T tev = RSTP_EVENT_LAST_DUMMY;int nev = 0;void *stp_in_stpm_create (int vlan_id, char* name, BITMAP_T* port_bmp, int* err_code){ int port_index; register STPM_T* this; /* stp_trace ("stp_in_stpm_create(%s)", name); */ this = stpapi_stpm_find (vlan_id); if (this) { /* it had just been created :( */ *err_code = STP_Nothing_To_Do; return this; } this = STP_stpm_create (vlan_id, name); if (! this) { /* can't create stpm :( */ *err_code = STP_Cannot_Create_Instance_For_Vlan; return NULL; } for (port_index = 1; port_index <= max_port; port_index++) { if (BitmapGetBit(port_bmp, (port_index - 1))) { if (! STP_port_create (this, port_index)) { /* can't add port :( */ stp_trace ("can't create port %d", (int) port_index); STP_stpm_delete (this); *err_code =STP_Cannot_Create_Instance_For_Port; return NULL; } } } *err_code = STP_OK; return this;}int_stp_in_stpm_enable (int vlan_id, char* name, BITMAP_T* port_bmp, UID_STP_MODE_T admin_state){ register STPM_T* this; Bool created_here = False; int rc, err_code; /* stp_trace ("_stp_in_stpm_enable(%s)", name); */ this = stpapi_stpm_find (vlan_id); if (STP_DISABLED != admin_state) { if (! vlan_id) { /* STP_IN_stop_all (); */ register STPM_T* stpm; for (stpm = STP_stpm_get_the_list (); stpm; stpm = stpm->next) { if (STP_DISABLED != stpm->admin_state) { STP_OUT_set_hardware_mode (stpm->vlan_id, STP_DISABLED); STP_stpm_enable (stpm, STP_DISABLED); } } } } if (! this) { /* it had not yet been created */ if (STP_ENABLED == admin_state) {/* try to create it */ stp_trace ("implicit create to vlan '%s'", name); this = stp_in_stpm_create (vlan_id, name, port_bmp, &err_code); if (! this) { stp_trace ("implicit create to vlan '%s' failed", name); return STP_Imlicite_Instance_Create_Failed; } created_here = True; } else {/* try to disable nothing ? */ return 0; } } if (this->admin_state == admin_state) { /* nothing to do :) */ return 0; } rc = STP_stpm_enable (this, admin_state); if (! rc) { STP_OUT_set_hardware_mode (vlan_id, admin_state); } if (rc && created_here) { STP_stpm_delete (this); } return rc;}STPM_T *stpapi_stpm_find (int vlan_id){ register STPM_T* this; for (this = STP_stpm_get_the_list (); this; this = this->next) if (vlan_id == this->vlan_id) return this; return NULL;}static PORT_T *_stpapi_port_find (STPM_T* this, int port_index){ register PORT_T* port; for (port = this->ports; port; port = port->next) if (port_index == port->port_index) { return port; } return NULL;}static void_conv_br_id_2_uid (IN BRIDGE_ID* f, OUT UID_BRIDGE_ID_T* t){ memcpy (t, f, sizeof (UID_BRIDGE_ID_T));}static int_check_stpm_config (IN UID_STP_CFG_T* uid_cfg){ if (uid_cfg->bridge_priority < MIN_BR_PRIO) { stp_trace ("%d bridge_priority small", (int) uid_cfg->bridge_priority); return STP_Small_Bridge_Priority; } if (uid_cfg->bridge_priority > MAX_BR_PRIO) { stp_trace ("%d bridge_priority large", (int) uid_cfg->bridge_priority); return STP_Large_Bridge_Priority; } if (uid_cfg->hello_time < MIN_BR_HELLOT) { stp_trace ("%d hello_time small", (int) uid_cfg->hello_time); return STP_Small_Hello_Time; } if (uid_cfg->hello_time > MAX_BR_HELLOT) { stp_trace ("%d hello_time large", (int) uid_cfg->hello_time); return STP_Large_Hello_Time; } if (uid_cfg->max_age < MIN_BR_MAXAGE) { stp_trace ("%d max_age small", (int) uid_cfg->max_age); return STP_Small_Max_Age; } if (uid_cfg->max_age > MAX_BR_MAXAGE) { stp_trace ("%d max_age large", (int) uid_cfg->max_age); return STP_Large_Max_Age; } if (uid_cfg->forward_delay < MIN_BR_FWDELAY) { stp_trace ("%d forward_delay small", (int) uid_cfg->forward_delay); return STP_Small_Forward_Delay; } if (uid_cfg->forward_delay > MAX_BR_FWDELAY) { stp_trace ("%d forward_delay large", (int) uid_cfg->forward_delay); return STP_Large_Forward_Delay; } if (2 * (uid_cfg->forward_delay - 1) < uid_cfg->max_age) { return STP_Forward_Delay_And_Max_Age_Are_Inconsistent; } if (uid_cfg->max_age < 2 * (uid_cfg->hello_time + 1)) { return STP_Hello_Time_And_Max_Age_Are_Inconsistent; } return 0;}static void_stp_in_enable_port_on_stpm (STPM_T* stpm, int port_index, Bool enable){ register PORT_T* port; port = _stpapi_port_find (stpm, port_index); if (! port) return; if (port->portEnabled == enable) {/* nothing to do :) */ return; } port->uptime = 0; if (enable) { /* clear port statistics */ port->rx_cfg_bpdu_cnt = port->rx_rstp_bpdu_cnt = port->rx_tcn_bpdu_cnt = 0; } #ifdef STP_DBG if (port->edge->debug) { stp_trace ("Port %s became '%s' adminEdge=%c", port->port_name, enable ? "enable" : "disable", port->adminEdge ? 'Y' : 'N'); }#endif port->adminEnable = enable; STP_port_init (port, stpm, False); port->reselect = True; port->selected = False; }void STP_IN_init (int max_port_index){ max_port = max_port_index; RSTP_INIT_CRITICAL_PATH_PROTECTIO;}intSTP_IN_stpm_get_cfg (IN int vlan_id, OUT UID_STP_CFG_T* uid_cfg){ register STPM_T* this; uid_cfg->field_mask = 0; RSTP_CRITICAL_PATH_START; this = stpapi_stpm_find (vlan_id); if (!this) { /* it had not yet been created :( */ RSTP_CRITICAL_PATH_END; return STP_Vlan_Had_Not_Yet_Been_Created; } if (this->admin_state != STP_DISABLED) { uid_cfg->field_mask |= BR_CFG_STATE; } uid_cfg->stp_enabled = this->admin_state; if (this->ForceVersion != 2) { uid_cfg->field_mask |= BR_CFG_FORCE_VER; } uid_cfg->force_version = this->ForceVersion; if (this->BrId.prio != DEF_BR_PRIO) { uid_cfg->field_mask |= BR_CFG_PRIO; } uid_cfg->bridge_priority = this->BrId.prio; if (this->BrTimes.MaxAge != DEF_BR_MAXAGE) { uid_cfg->field_mask |= BR_CFG_AGE; } uid_cfg->max_age = this->BrTimes.MaxAge; if (this->BrTimes.HelloTime != DEF_BR_HELLOT) { uid_cfg->field_mask |= BR_CFG_HELLO; } uid_cfg->hello_time = this->BrTimes.HelloTime; if (this->BrTimes.ForwardDelay != DEF_BR_FWDELAY) { uid_cfg->field_mask |= BR_CFG_DELAY; } uid_cfg->forward_delay = this->BrTimes.ForwardDelay; uid_cfg->hold_time = TxHoldCount; RSTP_CRITICAL_PATH_END; return 0;} intSTP_IN_port_get_cfg (int vlan_id, int port_index, UID_STP_PORT_CFG_T* uid_cfg){ register STPM_T* this; register PORT_T* port; RSTP_CRITICAL_PATH_START; this = stpapi_stpm_find (vlan_id); if (!this) { /* it had not yet been created :( */ RSTP_CRITICAL_PATH_END; return STP_Vlan_Had_Not_Yet_Been_Created; } port = _stpapi_port_find (this, port_index); if (! port) {/* port is absent in the stpm :( */ RSTP_CRITICAL_PATH_END; return STP_Port_Is_Absent_In_The_Vlan; } uid_cfg->field_mask = 0; uid_cfg->port_priority = port->port_id >> 8; if (uid_cfg->port_priority != DEF_PORT_PRIO) uid_cfg->field_mask |= PT_CFG_PRIO; uid_cfg->admin_port_path_cost = port->adminPCost; if (uid_cfg->admin_port_path_cost != ADMIN_PORT_PATH_COST_AUTO) uid_cfg->field_mask |= PT_CFG_COST; uid_cfg->admin_point2point = port->adminPointToPointMac; if (uid_cfg->admin_point2point != DEF_P2P) uid_cfg->field_mask |= PT_CFG_P2P; uid_cfg->admin_edge = port->adminEdge; if (uid_cfg->admin_edge != DEF_ADMIN_EDGE) uid_cfg->field_mask |= PT_CFG_EDGE; RSTP_CRITICAL_PATH_END; return 0;}intSTP_IN_port_get_state (IN int vlan_id, INOUT UID_STP_PORT_STATE_T* entry){ register STPM_T* this; register PORT_T* port; RSTP_CRITICAL_PATH_START; this = stpapi_stpm_find (vlan_id); if (!this) { /* it had not yet been created :( */ RSTP_CRITICAL_PATH_END; return STP_Vlan_Had_Not_Yet_Been_Created; } port = _stpapi_port_find (this, entry->port_no); if (! port) {/* port is absent in the stpm :( */ RSTP_CRITICAL_PATH_END; return STP_Port_Is_Absent_In_The_Vlan; } entry->port_id = port->port_id; if (DisabledPort == port->role) { entry->state = UID_PORT_DISABLED; } else if (! port->forward && ! port->learn) { entry->state = UID_PORT_DISCARDING; } else if (! port->forward && port->learn) { entry->state = UID_PORT_LEARNING; } else { entry->state = UID_PORT_FORWARDING; } entry->uptime = port->uptime; entry->path_cost = port->operPCost; _conv_br_id_2_uid (&port->portPrio.root_bridge, &entry->designated_root); entry->designated_cost = port->portPrio.root_path_cost; _conv_br_id_2_uid (&port->portPrio.design_bridge, &entry->designated_bridge); entry->designated_port = port->portPrio.design_port; switch (port->role) { case DisabledPort: entry->role = ' '; break; case AlternatePort: entry->role = 'A'; break; case BackupPort: entry->role = 'B'; break; case RootPort: entry->role = 'R'; break; case DesignatedPort: entry->role = 'D'; break; case NonStpPort: entry->role = '-'; break; default: entry->role = '?'; break; } if (DisabledPort == port->role || NonStpPort == port->role) { memset (&entry->designated_root, 0, sizeof (UID_BRIDGE_ID_T)); memset (&entry->designated_bridge, 0, sizeof (UID_BRIDGE_ID_T)); entry->designated_cost = 0; entry->designated_port = port->port_id; } if (DisabledPort == port->role) { entry->oper_point2point = (P2P_FORCE_FALSE == port->adminPointToPointMac) ? 0 : 1; entry->oper_edge = port->adminEdge; entry->oper_stp_neigb = 0; } else { entry->oper_point2point = port->operPointToPointMac ? 1 : 0; entry->oper_edge = port->operEdge ? 1 : 0; entry->oper_stp_neigb = port->sendRSTP ? 0 : 1; } entry->oper_port_path_cost = port->operPCost; entry->rx_cfg_bpdu_cnt = port->rx_cfg_bpdu_cnt; entry->rx_rstp_bpdu_cnt = port->rx_rstp_bpdu_cnt; entry->rx_tcn_bpdu_cnt = port->rx_tcn_bpdu_cnt; entry->fdWhile = port->fdWhile; /* 17.15.1 */ entry->helloWhen = port->helloWhen; /* 17.15.2 */ entry->mdelayWhile = port->mdelayWhile; /* 17.15.3 */ entry->rbWhile = port->rbWhile; /* 17.15.4 */ entry->rcvdInfoWhile = port->rcvdInfoWhile;/* 17.15.5 */ entry->rrWhile = port->rrWhile; /* 17.15.6 */ entry->tcWhile = port->tcWhile; /* 17.15.7 */ entry->txCount = port->txCount; /* 17.18.40 */ entry->lnkWhile = port->lnkWhile; entry->rcvdInfoWhile = port->rcvdInfoWhile; entry->top_change_ack = port->tcAck; entry->tc = port->tc; RSTP_CRITICAL_PATH_END; return 0; }intSTP_IN_stpm_get_state (IN int vlan_id, OUT UID_STP_STATE_T* entry){ register STPM_T* this; RSTP_CRITICAL_PATH_START; this = stpapi_stpm_find (vlan_id); if (!this) { /* it had not yet been created :( */ RSTP_CRITICAL_PATH_END; return STP_Vlan_Had_Not_Yet_Been_Created; } strncpy (entry->vlan_name, this->name, NAME_LEN); entry->vlan_id = this->vlan_id; _conv_br_id_2_uid (&this->rootPrio.root_bridge, &entry->designated_root); entry->root_path_cost = this->rootPrio.root_path_cost; entry->root_port = this->rootPortId; entry->max_age = this->rootTimes.MaxAge; entry->forward_delay = this->rootTimes.ForwardDelay; entry->hello_time = this->rootTimes.HelloTime; _conv_br_id_2_uid (&this->BrId, &entry->bridge_id); entry->stp_enabled = this->admin_state; entry->timeSince_Topo_Change = this->timeSince_Topo_Change; entry->Topo_Change_Count = this->Topo_Change_Count; entry->Topo_Change = this->Topo_Change; RSTP_CRITICAL_PATH_END; return 0;}intSTP_IN_stpm_get_name_by_vlan_id (int vlan_id, char* name, size_t buffsize){ register STPM_T* stpm; int iret = -1; RSTP_CRITICAL_PATH_START; for (stpm = STP_stpm_get_the_list (); stpm; stpm = stpm->next) { if (vlan_id == stpm->vlan_id) { if (stpm->name) strncpy (name, stpm->name, buffsize);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -