⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 portinfo.c

📁 rstp for switch in vxworks
💻 C
📖 第 1 页 / 共 2 页
字号:

/************************************************************************ 
 * 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 + -