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

📄 topoch.c

📁 rstp for switch in vxworks
💻 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. 
 **********************************************************************/

/* Topolgy Change state machine : 17.25 */

#include "base.h"
#include "stpm.h"
#include "stp_to.h"	/* for STP_OUT_flush_lt */

#define STATES { \
  CHOOSE(INIT),             \
  CHOOSE(INACTIVE),         \
  CHOOSE(TCACTIVE),         \
  CHOOSE(DETECTED),         \
  CHOOSE(NOTIFIED_TC),          \
  CHOOSE(PROPAGATING),          \
  CHOOSE(ACKNOWLEDGED),         \
  CHOOSE(NOTIFIED_TCN),         \
}

#define INIT           2
#define INACTIVE       3
#define TCACTIVE       4
#define DETECTED       5
#define NOTIFIED_TC    6
#define PROPAGATING    7
#define ACKNOWLEDGED   8
#define NOTIFIED_TCN   9

#define GET_STATE_NAME STP_topoch_get_state_name
#include "choose.h"

#ifndef STRONGLY_SPEC_802_1W
/* 
 * In many kinds of hardware the function
 * STP_OUT_flush_lt is a) is very hard and b) cannot
 * delete learning emtries per port. The alternate
 * method may be used: we don't care operEdge flag here,
 * but clean learning table once for TopologyChange
 * for all ports, except the received port. I am ready to discuss :(
 * See below word STRONGLY_SPEC_802_1W
 在许多的硬件中,STP_OUT_flush_it是a)非常难的
 b) 不能为每个端口删除学习信息。
 代替的方法是这样的:我们不需要关心operEdge
 Flag,但是为TopologyChage把所有的学习表都清理
 一次,除了接收端口。我将讨论。看看下面的
 文字STRONGLY_SPEC_802_1W
 */
#else

/************************************************************************************
  函数名称:
  输入参数:
  输出参数:
  功能描述:  
  返回值     :
  备注           :  17.19.6.
  作者           :  
  日期           :
  ************************************************************************************/

static Bool flush (STATE_MACH_T * this, char *reason)	/* 17.19.6 */
{
	register struct net_bridge_port  *port = this->owner.port;
	Bool bret;

	if (port->operEdge)
	{
	 	return True;
	}

	if (this->debug)
	{
		stp_trace ("%s (%s, %s, %s, '%s')", "flush", port->port_name,
			port->owner->name,
			LT_FLASH_ONLY_THE_PORT == type ? "this port" : "other ports",
			reason);
	}

	bret =STP_OUT_flush_lt (port->port_index, port->owner->vlan_id,
		LT_FLASH_ONLY_THE_PORT, reason);
}
#endif


/************************************************************************************
  函数名称:
  输入参数:
  输出参数:
  功能描述:  将所有端口的tcProp设置为TRUE,除了引起此函数的端口
  返回值     :
  备注           :  17.19.14.
  作者           :  
  日期           :
  ************************************************************************************/
static void setTcPropBridge (STATE_MACH_T * this, char *reason)	/* 17.19.14 */
{
	register struct net_bridge_port *port = this->owner.port;
	register struct net_bridge_port  *tmp;

	for (tmp = port->br->port_list; tmp; tmp = tmp->next)
	{
		if (!is_port_uplink_port(port->port_no))
				continue;


		if (tmp->port_id != port->port_id)
			tmp->tcProp = True;
	}

#ifndef STRONGLY_SPEC_802_1W
#ifdef STP_DBG
	if (this->debug)
	{
		stp_trace ("%s (%s, %s, %s, '%s')", "clearFDB", port->port_name,
			port->owner->name, "other ports", reason);
	}
#endif

/*	STP_OUT_flush_lt (port->port_index, port->owner->vlan_id,
		LT_FLASH_ALL_PORTS_EXCLUDE_THIS, reason);
*/
#endif
}

/************************************************************************************
  函数名称:
  输入参数:
  输出参数:
  功能描述:  设置TcWhile
  返回值     :
  备注           :  17.19.7.
  作者           :  
  日期           :
  ************************************************************************************/
static unsigned int newTcWhile (STATE_MACH_T * this)	/* 17.19.7 */
{
	register struct net_bridge_port *port = this->owner.port;

	if (port->sendRSTP && port->operPointToPointMac)
	{
		return 2 * port->br->rootTimes.HelloTime;
	}
	return port->br->rootTimes.MaxAge;
}

/************************************************************************************
  函数名称:
  输入参数:
  输出参数:
  功能描述:  
  返回值     :
  备注           :  17.19.25.
  作者           :  
  日期           :
  ************************************************************************************/
void STP_topoch_enter_state (STATE_MACH_T * this)
{
	register struct net_bridge_port *port = this->owner.port;

	switch (this->State)
	{
		case BEGIN:
		case INIT:
#ifdef STRONGLY_SPEC_802_1W
                     /*移除端口上学到的fdb信息*/
                     flush (this, "topoch INIT");
#endif
			port->tcWhile = 0;
			port->tc = port->tcProp = port->tcAck = False;
			break;
		case INACTIVE:
			port->rcvdTc = port->rcvdTcn = port->rcvdTcAck = port->tc =
				port->tcProp = False;
			break;
		case TCACTIVE:
			break;
		case DETECTED:
			port->tcWhile = newTcWhile (this);/*重新设置tcWhile*/
#ifdef STP_DBG
			if (this->debug)
				stp_trace ("DETECTED: tcWhile=%d on port %s", port->tcWhile,
					port->port_name);
#endif

                       /*
                         设置桥中其它端口的Tcprop,
                         通知它们如果是活动拓扑中
                         的一部分,就传播TC信息
                       */
                     setTcPropBridge (this, "DETECTED");
			port->tc = False;/*已经侦测到变化,清除tc*/
			break;
              case NOTIFIED_TCN:
			port->tcWhile = newTcWhile (this);
#ifdef STP_DBG
			if (this->debug)
				stp_trace ("NOTIFIED_TCN: tcWhile=%d on port %s", port->tcWhile,
					port->port_name);
#endif
			break;
     		case NOTIFIED_TC:
			port->rcvdTcn = port->rcvdTc = False;/*引起状态转移的变量要恢复*/
			if (port->role == DesignatedPort)
			{
				port->tcAck = True;/*拓扑变化应答*/
			}

			/*
			  *  设置桥中其它端口的Tcprop,
                       *  通知它们如果是活动拓扑中
                       *  的一部分,就传播TC信息
                      */
			setTcPropBridge (this, "NOTIFIED_TC");
			break;

		case PROPAGATING:
			port->tcWhile = newTcWhile (this);/*tcWhile重置*/
#ifdef STP_DBG
			if (this->debug)
				stp_trace ("PROPAGATING: tcWhile=%d on port %s", port->tcWhile,
					port->port_name);
#endif
#ifdef STRONGLY_SPEC_802_1W
			flush (this, "topoch PROPAGATING");
#endif
			port->tcProp = False;/*引起变化的变量恢复*/
			break;
		case ACKNOWLEDGED:
			port->tcWhile = 0; /*拓扑变化已经被应答了,tcWhile = 0,结束*/
#ifdef STP_DBG
			if (this->debug)
				stp_trace ("ACKNOWLEDGED: tcWhile=%d on port %s", port->tcWhile,
					port->port_name);
#endif
			port->rcvdTcAck = False; /*引起变化的变量恢复*/
			break;
	};
}


/************************************************************************************
  函数名称:
  输入参数:
  输出参数:
  功能描述:  
  返回值     :
  备注           :  17.19.25.
  作者           :  
  日期           :
  ************************************************************************************/
Bool STP_topoch_check_conditions (STATE_MACH_T * this)
{
	register struct net_bridge_port *port = this->owner.port;

	if (BEGIN == this->State)
	{
		return STP_hop_2_state (this, INIT);
	}

	switch (this->State)
	{
		case INIT:
                    	return STP_hop_2_state (this, INACTIVE);
		case INACTIVE:
			if (port->role == RootPort || port->role == DesignatedPort)
				return STP_hop_2_state (this, TCACTIVE);
			if (port->rcvdTc || port->rcvdTcn || port->rcvdTcAck || port->tc ||
				port->tcProp)
				return STP_hop_2_state (this, INACTIVE);
			break;
		case TCACTIVE:
			if (port->role != RootPort && (port->role != DesignatedPort))
				return STP_hop_2_state (this, INIT);
			if (port->tc)
				return STP_hop_2_state (this, DETECTED);
			if (port->rcvdTcn)
				return STP_hop_2_state (this, NOTIFIED_TCN);
			if (port->rcvdTc)
				return STP_hop_2_state (this, NOTIFIED_TC);
			if (port->tcProp && !port->operEdge)
				return STP_hop_2_state (this, PROPAGATING);
			if (port->rcvdTcAck)
				return STP_hop_2_state (this, ACKNOWLEDGED);
			break;
		case DETECTED:
			return STP_hop_2_state (this, TCACTIVE);
		case NOTIFIED_TC:
			return STP_hop_2_state (this, TCACTIVE);
		case PROPAGATING:
			return STP_hop_2_state (this, TCACTIVE);
		case ACKNOWLEDGED:
			return STP_hop_2_state (this, TCACTIVE);
		case NOTIFIED_TCN:
			return STP_hop_2_state (this, NOTIFIED_TC);
	};
	return False;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -