📄 stpm.c
字号:
}
this->machines = NULL;
this->ports = NULL;
STP_STATE_MACH_IN_LIST (rolesel);/*在桥一级,只有roleSel状态机,装入此状态机*/
#ifdef STP_DBG
/* this->rolesel->debug = 2; */
#endif
#endif
return this;
}
/************************************************************************************
函数名称:
输入参数:
输出参数:
功能描述: 根据admin_state设置bridge的rstp状态
返回值:
备注 :
作者 :
日期 :
************************************************************************************/
int STP_stpm_enable (struct net_bridge * this, UID_STP_MODE_T admin_state)
{
int rc = 0;
/*printf("wl_debug,STP_stpm_enable(0x%x,%d)\r\n",this,admin_state);*/
/*如果设置状态和当前状态一样,则返回*/
if (admin_state == this->admin_state)
{
/* nothing to do :) */
return 0;
}
/*当前状态和设置状态不一样,需要重新设置*/
/*Enable:开始stp_stpm,并更新admin_state*/
if (STP_ENABLED == admin_state)
{
rc = STP_stpm_start (this);
this->admin_state = admin_state;
}
/*disable:更新admin_state,并停止stpm*/
else
{
this->admin_state = admin_state;
STP_stpm_stop (this);
}
return rc;
}
/************************************************************************************
* purpose:删除主stp进程,释放所有结构。
*
************************************************************************************/
void STP_stpm_delete (struct net_bridge* this)
{
register struct net_bridge *tmp;
register struct net_bridge *prev;
register STATE_MACH_T *stater;
register struct net_bridge_port *port;
register void *pv;
printf ("STP_stpm_delete\r\n");
/*1) 将stpm的状态设为stp_disabled*/
STP_stpm_enable (this, STP_DISABLED);
/* 2) 依次删除所有的状态机*/
for (stater = this->machines; stater;)
{
pv = (void *) stater->next;
STP_state_mach_delete (stater);
this->machines = stater = (STATE_MACH_T *) pv;
}
/* 3) 依次删除所有的端口*/
#if 0 /*added by wl for compling .03-07*/
for (port = this->port_list; port;)
{
pv = (void *) port->next;
STP_port_delete (port);
this->port_list = port = (struct net_bridge_port *) pv;
}
#endif
prev = NULL;
#if 0 /*added by wl for compile*/
for (tmp = bridges; tmp; tmp = tmp->next)
{
if (tmp->vlan_id == this->vlan_id)
{
if (prev)
{
prev->next = this->next;
}
else
{
bridges = this->next;
}
if (this->name)
STP_FREE (this->name, "stp bridge name");
STP_FREE (this, "stp instance");
break;
}
prev = tmp;
}
#endif
}
/************************************************************************************
函数名称:
输入参数:
输出参数:
功能描述:
返回值:
备注 :
作者 :
日期 :
************************************************************************************/
int STP_stpm_start (struct net_bridge* this)
{
register struct net_bridge_port *port;
int loops = 0;;
/*printf("wl_debug:STP_stpm_start(0x%x):\r\n",this);*/
if (!this->port_list)
{ /* there are not any ports :( */
/* printf("wl_debug:STP_stpm_start,return -1:\r\n"); */
return -1;
}
if (!STP_compute_bridge_id (this))
{ /* can't compute bridge id ? :( */
/*printf("wl_debug:STP_stpm_start,return -2:\r\n"); */
return -2;
}
/* check, that the stpm has unique bridge Id */
if (0 != STP_stpm_check_bridge_priority (this))
{
/* there is an enabled bridge with same ID :( */
/*printf("wl_debug:STP_stpm_start,return -3:\r\n"); */
return -3;
}
/*以上都为判断错误,下面才是主要的操作*/
_stp_stpm_init_data (this);
/*初始化所有的端口*/
for (port = this->port_list; port; port = port->next)
{
if (!is_port_uplink_port(port->port_no))
continue;
STP_port_init (port, this, True);
}
#ifndef STRONGLY_SPEC_802_1W
/* A. see comment near STRONGLY_SPEC_802_1W in topoch.c */
/* B. port=0 here means: delete for all ports */
#ifdef STP_DBG
stp_trace ("%s (all, start stpm)", "clearFDB");
#endif
/*清除fdb表*/
/* STP_OUT_flush_lt (0, this->vlan_id, LT_FLASH_ONLY_THE_PORT, "start stpm");*/
#endif
/*调用了_stp_stpm_init_machine,并带入参数False*/
_stp_stpm_iterate_init_machines(this);
loops = STP_stpm_update (this);
/*mn_fd_printf(cl_serv_console_fd, "loops = %d\r\n" , loops);*/
return 0;
}
void STP_stpm_stop (struct net_bridge * this)
{
}
/***********************************************************************************
*
*好像是计算循环的次数
***********************************************************************************/
int STP_stpm_update (struct net_bridge * this) /* returns number of loops */
{
register Bool need_state_change;
register int number_of_loops = 0;
need_state_change = False;
/*每次的状态转移都到一个相对稳定的状态返回*/
for (;;)
{ /* loop until not need changes */
/*是否有状态机转移*/
need_state_change = _stp_stpm_iterate_check_condition_machines(this);
/*如果没有转移,则返回*/
if (!need_state_change)
{
return number_of_loops;
}
number_of_loops++;
/* here we know, that at least one stater must be
updated (it has changed state) */
/* 得到状态机改变的总次数*/
number_of_loops += _stp_stpm_iterate_change_state_machines(this);
}
return number_of_loops;
}
/************************************************************************************
函数名称:
输入参数:
输出参数:
功能描述:
返回值:
备注 :
作者 :
日期 :
************************************************************************************/
BRIDGE_ID *STP_compute_bridge_id (struct net_bridge* this)
{
register struct net_bridge_port *port;
register struct net_bridge_port *min_num_port;
int port_index = 0;
for (port = this->port_list; port; port = port->next)
{
if (!is_port_uplink_port(port->port_no))
continue;
if (!port_index || port->port_id < port_index)
{
min_num_port = port;
port_index = port->port_id;
}
}
if (!min_num_port)
{
return NULL; /* IMHO, it may not be */
}
/*STP_OUT_get_port_mac (min_num_port->port_id, this->BrId.addr);*/
return &this->BrId;
}
struct net_bridge *STP_stpm_get_the_list (void)
{
return bridges;
}
/************************************************************************************
函数名称: STP_stpm_update_after_bridge_management
输入参数: this-桥结构
输出参数:
功能描述: 在bridge management操作进行后,运行的函数.
更新selected和reselect让Port Role Selection状态机能够转移到
ROLE_SELECTION状态去更新端口角色
返回值:
备注 :
作者 :
日期 :
************************************************************************************/
void STP_stpm_update_after_bridge_management (struct net_bridge* this)
{
register struct net_bridge_port *port;
for (port = this->port_list; port; port = port->next)
{
if (!is_port_uplink_port(port->port_no))
continue;
port->reselect = True;
port->selected = False;
}
}
/************************************************************************************
函数名称:
输入参数:
输出参数:
功能描述: 判断在bridges链表中是否有元素在桥优先级上一致
返回值:
备注 :
作者 :
日期 :
************************************************************************************/
int STP_stpm_check_bridge_priority (struct net_bridge * this)
{
register struct net_bridge *oth;
for (oth = bridges; oth; oth = oth->next)
{
if (STP_ENABLED == oth->admin_state
&& oth != this
&& !STP_VECT_compare_bridge_id (&this->BrId, &oth->BrId))
{
return STP_Invalid_Bridge_Priority;
}
}
return 0;
}
/************************************************************************************
函数名称:
输入参数:
输出参数:
功能描述: 根据port_id,在(STPM_T*) this中得到port的名字
返回值:
备注 :
作者 :
日期 :
************************************************************************************/
const char *STP_stpm_get_port_name_by_id (struct net_bridge * this, PORT_ID port_id)
{
register struct net_bridge_port *port;
/* for (port = this->port_list; port; port = port->next)
{
if (port_id == port->port_id)
{
return port->port_name;
}
}
*/ /*added by wl for compile*/
return "Undef?";
}
void STP_port_init (struct net_bridge_port * this, struct net_bridge * stpm, Bool check_link)
{
/*如果端口link up,则重新计算一次向量5元*/
if (check_link)
{
if (this->flags &PortFlagLinked)
{
this->adminEnable = 1;
}
else
{
this->adminEnable = 0;
}
STP_VECT_create (&this->designPrio, &stpm->BrId, 0, &stpm->BrId,
this->port_no, this->port_no);
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_id);
this->p2p_recompute = True;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -