📄 stpm.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.
**********************************************************************/
/* STP machine instance : bridge per VLAN: 17.17 */
#include "base.h"
#include "stpm.h"
#include "stp_to.h" /* for STP_OUT_flush_lt */
#include "../switch/port.h"
static struct net_bridge *bridges = NULL;
/************************************************************************************
函数名称:
输入参数:
输出参数:
功能描述: 初始化状态机BEGIN状态,并进入状态操作函数
返回值 :
备注 :
作者 :
日期 :
************************************************************************************/
static int _stp_stpm_init_machine (STATE_MACH_T * this)
{
if (!this)
{
return -1;
}
this->State = BEGIN; /*状态机的首状态为BEGIN*/
if (this->concreteEnterState)
(*(this->concreteEnterState)) (this);/*进入状态操作函数*/
return 0;
}
/************************************************************************************
函数名称:
输入参数:
输出参数:
功能描述: 循环执行交换机所有状态机的check condition,(FALSE)函数或
者enter state (TRUE) 函数
返回值:
备注 :
作者 :
日期 :
************************************************************************************/
static int _stp_stpm_iterate_machines (struct net_bridge* this,
int (*iter_callb) (STATE_MACH_T *),
/*以STATE_MACH_T *为参数的一个函数作为参数*/
Bool exit_on_non_zero_ret)
{
register STATE_MACH_T *stater;
register struct net_bridge_port *port;
int iret, mret = 0;
/* state machines per bridge
对桥一级的状态机变量进行具体的iter_callb 操作,如条件转移等*/
for (stater = this->machines; stater; stater = stater->next)
{
iret = (*iter_callb) (stater); /*根据调用的具体函数完成不同的功能
如根据条件进行状态转移等*/
if (exit_on_non_zero_ret && iret)
{
return iret; /*返回真*/
}
else
{
mret += iret;
}
}
/* state machines per port
只有在 if (exit_on_non_zero_ret && iret) 不成立时,以下代码才会被执行*/
for (port = this->port_list; port; port = port->next)
{
if (!is_port_uplink_port(port->port_no))
continue;
for (stater = port->machines; stater; stater = stater->next)
{
iret = (*iter_callb) (stater);
if (exit_on_non_zero_ret && iret)
{
return iret;
}
else
{
mret += iret;
}
}
}
return mret;
}
void _stp_stpm_iterate_init_machines (struct net_bridge* this
)
{
register STATE_MACH_T *stater;
register struct net_bridge_port *port;
int iret, mret = 0;
/* */
for (stater = this->machines; stater; stater = stater->next)
{
_stp_stpm_init_machine (stater); /*根据调用的具体函数完成不同的功能*/
}
/* */
for (port = this->port_list; port; port = port->next)
{
if (is_port_uplink_port())/*added by wl 2006-2-10*/
{
for (stater = port->machines; stater; stater = stater->next)
{
_stp_stpm_init_machine(stater);
}
}
}
return ;
}
static int _stp_stpm_iterate_check_condition_machines (struct net_bridge* this )
{
register STATE_MACH_T *stater;
register struct net_bridge_port *port;
int iret, mret = 0;
/* state machines per bridge 对桥一级的状态机变量进行具体的iter_callb 操作,如条件转移等*/
for (stater = this->machines; stater; stater = stater->next)
{
iret = STP_check_condition (stater); /*根据调用的具体函数完成不同的功能
如根据条件进行状态转移等*/
if ( iret)
{
return iret; /*返回真*/
}
else
{
mret += iret;
}
}
/* state machines per port 只有在 if (exit_on_non_zero_ret && iret) 不成立时,以下代码才会被执行*/
for (port = this->port_list; port; port = port->next)
{
if (!is_port_uplink_port(port->port_no))
continue;
#ifdef _AN2200_02_
if ((port->port_no>=17) && (port->port_no<=24))
#endif
#ifdef _AN2200_06_
if ((port->port_no>=6) && (port->port_no<=12))
#endif
{
for (stater = port->machines; stater; stater = stater->next)
{
iret = STP_check_condition(stater);
if ( iret)
{
return iret;
}
else
{
mret += iret;
}
}
}
}
return mret;
}
static int _stp_stpm_iterate_change_state_machines (struct net_bridge* this )
{
register STATE_MACH_T *stater;
register struct net_bridge_port *port;
int iret, mret = 0;
/* state machines per bridge 对桥一级的状态机变量进行具体的iter_callb 操作,如条件转移等*/
for (stater = this->machines; stater; stater = stater->next)
{
iret = STP_change_state(stater); /*根据调用的具体函数完成不同的功能
如根据条件进行状态转移等*/
mret += iret;
}
/* state machines per port
只有在 if (exit_on_non_zero_ret && iret) 不成立时,以下代码才会被执行*/
for (port = this->port_list; port; port = port->next)
{
if (!is_port_uplink_port(port->port_no))
continue;
for (stater = port->machines; stater; stater = stater->next)
{
iret = STP_change_state (stater);
mret += iret;
}
}
return mret;
}
/************************************************************************************
函数名称:
输入参数:
输出参数:
功能描述: a) 创建stp 向量
b) 把BrTimer的值复制到rootTimers
返回值:
备注 :
作者 :
日期 :
************************************************************************************/
void _stp_stpm_init_data (struct net_bridge * this)
{
/*printf("wl_debug:_stp_stpm_init_data(0x%x)\r\n",this);*/
STP_VECT_create (&this->rootPrio, &this->BrId, 0, &this->BrId, 0, 0);
this->BrTimes.MessageAge = 0;
STP_copy_times (&this->rootTimes, &this->BrTimes);
}
/************************************************************************************
函数名称:
输入参数:
输出参数:
功能描述: 判断交换机是否有拓扑变化.任何一个端口的tcWhile !=0,
表示有拓扑变化,否则表示无拓扑变化
返回值: 1 -有拓扑变化
0 - 无拓扑变化
备注 :
作者 :
日期 :
************************************************************************************/
static unsigned char _check_topoch (struct net_bridge * this)
{
register struct net_bridge_port *port;
/*如果任意一个ile参数不为0,则返回1
17.15.7*/
for (port = this->port_list; port; port = port->next)
{
if (!is_port_uplink_port(port->port_no))
continue;
if (port->tcWhile)
{
return 1;
}
}
return 0;
}
/***********************************************************************************
* 函数名称: STP_stpm_one_second
功能描述: 将所有timer减一,进入STP_stpm_update (this) 一次,进行一次状态
更新
输入参数:
输出参数:
返回值 :
备注:
*
***********************************************************************************/
void STP_stpm_one_second (struct net_bridge * param)
{
struct net_bridge *this = (struct net_bridge *) param;
register struct net_bridge_port *port;
register int iii;
unsigned int time_value = 0;
/*如果STP功能未打开,直接返回*/
if (STP_ENABLED != this->admin_state)
{
return;
}
for (port = this->port_list; port; port = port->next)
{
/*将所有的timer值减一*/
if (!is_port_uplink_port(port->port_no))
continue;
for (iii = 0; iii < TIMERS_NUMBER; iii++)
{
/*if (*(port->timers[iii]) > 0)
{
(*port->timers[iii])--;
}*/
time_value = *(port->timers[iii]);
if (time_value >0)
{
time_value --;
*(port->timers[iii]) = time_value;
}
}
port->uptime++; /*标记一个端口从上次重启或者初始化后经过的
时间*/
}
STP_stpm_update (this);
this->Topo_Change = _check_topoch (this);
if (this->Topo_Change)
{
this->Topo_Change_Count++;
this->timeSince_Topo_Change = 0;
}
else
{
this->Topo_Change_Count = 0;
this->timeSince_Topo_Change++;
}
}
/************************************************************************************
函数名称:
输入参数:
输出参数:
功能描述: 建立bridges链表,装入rolesel状态机
返回值: 当前建立的STPM_T
备注 :
作者 :
日期 :
************************************************************************************/
struct net_bridge *STP_stpm_create (int vlan_id, char *name)
{
struct net_bridge *this;
#if 0
/*建立bridges链表,即STPM_T结构形成的链表*/
STP_NEW_IN_LIST (this, STPM_T, bridges, "stp instance");
this->admin_state = STP_DISABLED;
this->vlan_id = vlan_id;
if (name)
{
STP_STRDUP (this->name, name, "stp bridge name");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -