📄 rolesel.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.
**********************************************************************/
/* Port Role Selection state machine : 17.22 */
#include "base.h"
#include "stpm.h"
#define STATES { \
CHOOSE(INIT_BRIDGE), \
CHOOSE(ROLE_SELECTION), \
}
#define INIT_BRIDGE 2
#define ROLE_SELECTION 3
extern int mn_fd_printf(int fd,const char *format, ...);
extern int cl_serv_console_fd;
#define GET_STATE_NAME STP_rolesel_get_state_name
#include "choose.h"
#ifdef STP_DBG
void stp_dbg_break_point (struct net_bridge_port * port, net_bridge* stpm)
{
}
#endif
/************************************************************************************
函数名称:
功能描述: 判断端口是否为backup port.
输入参数:
输出参数:
返回值:
备注: 根据17.19.21 k)端口优先级向量的指定桥和指定端口元素
反应了这个桥上的另一个端口
*************************************************************************************/
static Bool _is_backup_port (struct net_bridge_port* port, struct net_bridge * this)
{
if (!STP_VECT_compare_bridge_id (&port->portPrio.design_bridge,
&this->BrId)) /*如果Designated_bridge和当前的brID一致,则为真*/
{
#if 0 /* def STP_DBG */
if (port->info->debug)
{
STP_VECT_br_id_print ("portPrio.design_bridge",
&port->portPrio.design_bridge, True);
STP_VECT_br_id_print (" this->BrId", &this->BrId, True);
}
stp_dbg_break_point (port, this);
#endif
return True;
}
else
{
return False;
}
}
/************************************************************************************
function:
purpose: 根据newRole,更新port->selectedRole
input: reason,stpm,port,newRole
output: port->selectedRole
return:
remark:
*************************************************************************************/
static void setRoleSelected (char *reason, struct net_bridge * stpm, struct net_bridge_port * port,
PORT_ROLE_T newRole)
{
char *new_role_name;
port->selectedRole = newRole;
if (newRole == port->role)
return;
switch (newRole)
{
case DisabledPort:
new_role_name = "Disabled";
break;
case AlternatePort:
new_role_name = "Alternate";
break;
case BackupPort:
new_role_name = "Backup";
break;
case RootPort:
new_role_name = "Root";
break;
case DesignatedPort:
new_role_name = "Designated";
break;
case NonStpPort: /*如果newRole为NonStpPort,则将role赋值*/
new_role_name = "NonStp";
port->role = newRole;
break;
default:
/*stp_trace ("%s-%s:port %s => Unknown (%d ?)", reason, stpm->name,
port->port_name, (int) newRole);*/
return;
}
#ifdef STP_DBG
if (port->roletrns->debug)
stp_trace ("%s(%s-%s) => %s", reason, stpm->name, port->port_name,
new_role_name);
#endif
}
/************************************************************************************
function:
purpose: 将Bridge中所有的端口的selectedRole设置为DisablePort
input:
output:
return:
remark:
*************************************************************************************/
static void updtRoleDisableBridge (struct net_bridge* this)
{ /* 17.19.20 */
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->selectedRole = DisabledPort;
}
}
/************************************************************************************
function:
purpose: 将Bridge的所有的端口的reselect置假
input:
output:
return:
remark:
*************************************************************************************/
static void clearReselectBridge (struct net_bridge * this)
{ /* 17.19.1 */
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 = False;
}
}
int rstp_debug1= 1;
int rstp_debug2 =1;
int rstp_debug3 =1;
int rstp_debug4 = 0;
/************************************************************************************
function:
purpose: 用更好的vector来代替现在的
input:
output:
return:
remark:
*************************************************************************************/
static void updtRootPrio (STATE_MACH_T * this)
{
PRIO_VECTOR_T rootPathPrio; /* 17.4.2.2 */
register struct net_bridge_port *port;
register struct net_bridge *stpm;
register unsigned int dm;
stpm = this->owner.stpm;
for (port = stpm->port_list; port; port = port->next)
{
if (rstp_debug4==0)
{
if (!is_port_uplink_port(port->port_no))
continue;
}
if (port->admin_non_stp)
{
continue;
}
if (Disabled == port->infoIs)
continue;
if (Aged == port->infoIs)
continue;
if (Mine == port->infoIs)
{
#if 0 /* def STP_DBG */
stp_dbg_break_point (port); /* for debugger break point */
#endif
continue;
}
STP_VECT_copy (&rootPathPrio, &port->portPrio);
rootPathPrio.root_path_cost += port->operPCost;
if (STP_VECT_compare_vector (&rootPathPrio, &stpm->rootPrio) < 0)
{
/*如果端口收到的向量优于现有的*/
STP_VECT_copy (&stpm->rootPrio, &rootPathPrio);
STP_copy_times (&stpm->rootTimes, &port->portTimes);
dm = (8 + stpm->rootTimes.MaxAge) / 16;/*为什么要+8*/
if (!dm)
dm = 1;
stpm->rootTimes.MessageAge += dm;
#ifdef STP_DBG
if (port->roletrns->debug)
stp_trace
("updtRootPrio: dm=%d rootTimes.MessageAge=%d on port %s",
(int) dm, (int) stpm->rootTimes.MessageAge,
port->port_name);
#endif
}
}
}
/************************************************************************************
function:
purpose:
input:
output:
return:
remark:
*************************************************************************************/
static void updtRolesBridge (STATE_MACH_T * this)
{ /* 17.19.21 */
register struct net_bridge_port *port;
register struct net_bridge *stpm;
PORT_ID old_root_port; /* for tracing of root port changing */
/*printf("wl_debug:updateRolsBridge.\r\n");*/
if (rstp_debug1 ==1)
{
stpm = this->owner.stpm;
old_root_port = stpm->rootPortId;
/*printf("stpm= 0x%x\r\n",stpm);*/
/*填充优先级向量{BrId,0,BrId,0,0} */
if (rstp_debug2 ==1)
STP_VECT_create (&stpm->rootPrio, &stpm->BrId, 0, &stpm->BrId, 0, 0);
STP_copy_times (&stpm->rootTimes, &stpm->BrTimes);
stpm->rootPortId = 0;
/*printf("1111111111\r\n%x:%x:%x:%x:%x:%x\r\n",stpm->rootPrio.design_bridge.addr[0],
stpm->rootPrio.design_bridge.addr[1],
stpm->rootPrio.design_bridge.addr[2],
stpm->rootPrio.design_bridge.addr[3],
stpm->rootPrio.design_bridge.addr[4],
stpm->rootPrio.design_bridge.addr[5]
);*/
if (rstp_debug3 ==1)
updtRootPrio (this);
/*printf("22222222222222\r\n%x:%x:%x:%x:%x:%x\r\n",stpm->rootPrio.design_bridge.addr[0],
stpm->rootPrio.design_bridge.addr[1],
stpm->rootPrio.design_bridge.addr[2],
stpm->rootPrio.design_bridge.addr[3],
stpm->rootPrio.design_bridge.addr[4],
stpm->rootPrio.design_bridge.addr[5]
);*/
/*
遍历所有的端口,创建designated Priority vector,
并拷贝定时器
*/
for (port = stpm->port_list; port; port = port->next)
{
if (port->admin_non_stp)
{
continue;
}
if (is_port_uplink_port(port->port_no)!=1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -