📄 portinfo.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.
**********************************************************************/
#include "base.h"
#include "stpm.h"
#include "vector.h"
/* The Port Information State Machine : 17.21 */
#define STATES { \
CHOOSE(DISABLED), \
CHOOSE(ENABLED), \
CHOOSE(AGED), \
CHOOSE(UPDATE), \
CHOOSE(CURRENT), \
CHOOSE(RECEIVE), \
CHOOSE(SUPERIOR), \
CHOOSE(REPEAT), \
CHOOSE(AGREEMENT), \
}
#define DISABLED 2
#define ENABLED 3
#define AGED 4
#define UPDATE 5
#define CURRENT 6
#define RECEIVE 7
#define SUPERIOR 8
#define REPEAT 9
#define AGREEMENT 10
#define GET_STATE_NAME STP_info_get_state_name
#include "choose.h"
extern int mn_fd_printf(int fd,const char *format, ...);
extern int cl_serv_console_fd;
#if 0 /* for debug */
void _stp_dump (char *title, unsigned char *buff, int len)
{
register int iii;
printf ("\n%s:", title);
for (iii = 0; iii < len; iii++)
{
if (!(iii % 24))
Print ("\n%6d:", iii);
if (!(iii % 8))
Print (" ");
Print ("%02lx", (unsigned long) buff[iii]);
}
Print ("\n");
}
#endif
/************************************************************************************
* function:
purpose:
input:
output:
return:
*
*
************************************************************************************/
static RCVD_MSG_T rcvBpdu (STATE_MACH_T * this)
{ /* 17.19.8 */
int bridcmp;
register struct net_bridge_port *port = this->owner.port;
if (port->msgBpduType == BPDU_TOPO_CHANGE_TYPE)
{
#ifdef STP_DBG
if (this->debug)
{
stp_trace ("%s", "OtherMsg:BPDU_TOPO_CHANGE_TYPE");
}
#endif
return OtherMsg;
}
port->msgPortRole = RSTP_PORT_ROLE_UNKN;
if (BPDU_RSTP == port->msgBpduType)
{
port->msgPortRole = (port->msgFlags & PORT_ROLE_MASK) >> PORT_ROLE_OFFS;
}
if (RSTP_PORT_ROLE_DESGN == port->msgPortRole ||
BPDU_CONFIG_TYPE == port->msgBpduType)
{
bridcmp = STP_VECT_compare_vector (&port->msgPrio, &port->portPrio);
if (bridcmp < 0 ||
(!STP_VECT_compare_bridge_id (&port->msgPrio.design_bridge,
&port->portPrio.design_bridge) &&
port->msgPrio.design_port == port->portPrio.design_port &&
STP_compare_times (&port->msgTimes, &port->portTimes)))
{
#ifdef STP_DBG
if (this->debug)
{
stp_trace ("SuperiorDesignateMsg:bridcmp=%d", (int) bridcmp);
}
#endif
return SuperiorDesignateMsg;
}
}
if (BPDU_CONFIG_TYPE == port->msgBpduType ||
RSTP_PORT_ROLE_DESGN == port->msgPortRole)
{
if (!STP_VECT_compare_vector (&port->msgPrio, &port->portPrio) &&
!STP_compare_times (&port->msgTimes, &port->portTimes))
{
#ifdef STP_DBG
if (this->debug)
{
stp_trace ("%s", "RepeatedDesignateMsg");
}
#endif
return RepeatedDesignateMsg;
}
}
if (RSTP_PORT_ROLE_ROOT == port->msgBpduType && port->operPointToPointMac &&
!STP_VECT_compare_bridge_id (&port->msgPrio.design_bridge,
&port->portPrio.design_bridge) && AGREEMENT_BIT & port->msgFlags)
{
#ifdef STP_DBG
if (this->debug)
{
stp_trace ("%s", "ConfirmedRootMsg");
}
#endif
return ConfirmedRootMsg;
}
#ifdef STP_DBG
if (this->debug)
{
stp_trace ("%s", "OtherMsg");
}
#endif
return OtherMsg;
}
/************************************************************************************
* function:
purpose: 用来确定port的proposed值是否被置位。
input:
output:
return:
*
*
************************************************************************************/
static Bool recordProposed (STATE_MACH_T * this, char *reason)
{ /* 17.19.9 */
register struct net_bridge_port *port = this->owner.port;
if (RSTP_PORT_ROLE_DESGN == port->msgPortRole
&& (PROPOSAL_BIT & port->msgFlags)
&& port->operPointToPointMac)
{
return True;
}
return False;
}
/************************************************************************************
* function:
purpose: 根据接收到的包不同,改变port的参数
input:
output: rcvdTc,rcvdAck,rcvdTcn
return:
*
*
************************************************************************************/
static Bool setTcFlags (STATE_MACH_T * this)
{ /* 17.19.13 */
register struct net_bridge_port *port = this->owner.port;
if (BPDU_TOPO_CHANGE_TYPE == port->msgBpduType)
{
#ifdef STP_DBG
if (this->debug)
{
stp_trace ("port %s rx rcvdTcn", port->port_name);
}
#endif
port->rcvdTcn = True;
}
else
{
if (TOLPLOGY_CHANGE_BIT & port->msgFlags)
{
#ifdef STP_DBG
if (this->debug)
{
stp_trace ("(%s-%s) rx rcvdTc 0X%lx", port->owner->name,
port->port_name, (unsigned long) port->msgFlags);
}
#endif
port->rcvdTc = True;
}
if (TOLPLOGY_CHANGE_ACK_BIT & port->msgFlags)
{
#ifdef STP_DBG
if (this->debug)
{
stp_trace ("port %s rx rcvdTcAck 0X%lx", port->port_name,
(unsigned long) port->msgFlags);
}
#endif
port->rcvdTcAck = True;
}
}
return True;
}
/************************************************************************************
* function:
purpose: 判断收到的BPDU是何版本
input:
output: rcvdSTP,rcvdRSTP
return:
*
*
************************************************************************************/
static Bool updtBPDUVersion (STATE_MACH_T * this)
{ /* 17.19.18 */
register struct net_bridge_port *port = this->owner.port;
if (BPDU_TOPO_CHANGE_TYPE == port->msgBpduType)
{
port->rcvdSTP = True;
}
if (port->msgBpduVersion < 2)
{
port->rcvdSTP = True;
}
if (BPDU_RSTP == port->msgBpduType)
{
/* port->port->owner->ForceVersion >= NORMAL_RSTP
we have checked in STP_info_rx_bpdu */
port->rcvdRSTP = True;
}
return True;
}
/************************************************************************************
* function:
purpose: 计算rcvdInfoWhile的值
input:
output:
return:
*
*
************************************************************************************/
static Bool updtRcvdInfoWhile (STATE_MACH_T * this)
{ /* 17.19.19 */
register int effective_age, dm, dt;
register int hello3;
register struct net_bridge_port *port = this->owner.port;
effective_age = (+port->portTimes.MaxAge) / 16;
if (effective_age < 1)
effective_age = 1;
effective_age += port->portTimes.MessageAge;
if (effective_age <= port->portTimes.MaxAge)
{
hello3 = 3 * port->portTimes.HelloTime;
dm = port->portTimes.MaxAge - effective_age;
if (dm > hello3)
dt = hello3;
else
dt = dm;
port->rcvdInfoWhile = dt;
/****
stp_trace ("ma=%d eff_age=%d dm=%d dt=%d p=%s",
(int) port->portTimes.MessageAge,
(int) eff_age, (int) dm, (int) dt, port->port_name);
****/
}
else
{
port->rcvdInfoWhile = 0;
#ifdef STP_DBG
stp_trace
("port %s: MaxAge=%d MessageAge=%d HelloTime=%d rcvdInfoWhile=null !",
port->port_name, (int) port->portTimes.MaxAge,
(int) port->portTimes.MessageAge,
(int) port->portTimes.HelloTime);
#endif
}
return True;
}
void STP_info_rx_bpdu (struct net_bridge_port * port, struct stp_bpdu_t *bpdu/*, size_t len*/)
{
#if 0
_stp_dump ("\nall BPDU", ((unsigned char *) bpdu) - 12, len + 12);
_stp_dump ("ETH_HEADER", (unsigned char *) &bpdu->eth, 5);
_stp_dump ("BPDU_HEADER", (unsigned char *) &bpdu->hdr, 4);
printf ("protocol=%02x%02x version=%02x bpdu_type=%02x\n",
bpdu->hdr.protocol[0], bpdu->hdr.protocol[1], bpdu->hdr.version,
bpdu->hdr.bpdu_type);
_stp_dump ("\nBPDU_BODY", (unsigned char *) &bpdu->body,
sizeof (BPDU_BODY_T) + 2);
printf ("flags=%02x\n", bpdu->body.flags);
_stp_dump ("root_id", bpdu->body.root_id, 8);
_stp_dump ("root_path_cost", bpdu->body.root_path_cost, 4);
_stp_dump ("bridge_id", bpdu->body.bridge_id, 8);
_stp_dump ("port_id", bpdu->body.port_id, 2);
_stp_dump ("message_age", bpdu->body.message_age, 2);
_stp_dump ("max_age", bpdu->body.max_age, 2);
_stp_dump ("hello_time", bpdu->body.hello_time, 2);
_stp_dump ("forward_delay", bpdu->body.forward_delay, 2);
_stp_dump ("ver_1_len", bpdu->ver_1_len, 2);
#endif
/* check bpdu type */
switch (bpdu->hdr.bpdu_type)
{
case BPDU_CONFIG_TYPE:
port->rx_cfg_bpdu_cnt++;
#if 0 /* def STP_DBG */
if (port->info->debug)
stp_trace ("CfgBpdu on port %s", port->port_name);
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -