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

📄 stp_in.c

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

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

/* This file contains API from an operation system to the RSTP library */

#include "base.h"
#include "stpm.h"
#include "stp_in.h"
#include "stp_to.h"
#include "uid_stp.h"

int max_port = 1024;

#define INCR100(nev) { nev++; if (nev > 99) nev = 0;}

RSTP_EVENT_T tev = RSTP_EVENT_LAST_DUMMY;
int nev = 0;


typedef struct {
  /* service data */
  unsigned long field_mask; /* which fields to change */
 /* BITMAP_T      port_bmp;   */
  char          vlan_name[NAME_LEN]; /* name of the VLAN, key of the bridge */

  /* protocol data */
  int           port_priority;
  unsigned long admin_port_path_cost; /* ADMIN_PORT_PATH_COST_AUTO - auto sence */
  ADMIN_P2P_T   admin_point2point;
  unsigned char admin_edge;
  unsigned char admin_non_stp; /* 1- doesn't participate in STP, 1 - regular */
#ifdef STP_DBG
  unsigned int	skip_rx;
  unsigned int	skip_tx;
#endif

} UID_STP_PORT_CFG_T;

#if 0
/************************************************************************************
  函数名称:
  输入参数:
  输出参数:
  功能描述: 创建RSTP的状态机
  返回值:
  备注           : 
  作者           :
  日期           :
  ************************************************************************************/
void *stp_in_stpm_create (int vlan_id, char *name, BITMAP_T * port_bmp,
	int *err_code)
{
	int port_index;
	register struct net_bridge *this;

	/* stp_trace ("stp_in_stpm_create(%s)", name); */
	this = stpapi_stpm_find (vlan_id);
	if (this)
	{	/* it had just been created :( */
		*err_code = STP_Nothing_To_Do;
		return this;
	}

	this = STP_stpm_create (vlan_id, name);
	if (!this)
	{	/* can't create stpm :( */
		*err_code = STP_Cannot_Create_Instance_For_Vlan;
		return NULL;
	}

	for (port_index = 1; port_index <= max_port; port_index++)
	{
		if (BitmapGetBit (port_bmp, (port_index - 1)))
		{
			if (!STP_port_create (this, port_index))
			{
				/* can't add port :( */
				stp_trace ("can't create port %d", (int) port_index);
				STP_stpm_delete (this);
				*err_code = STP_Cannot_Create_Instance_For_Port;
				return NULL;
			}
		}
	}

	*err_code = STP_OK;
	return this;
}


#endif


/************************************************************************************
  函数名称:
  输入参数:
  输出参数:
  功能描述: 
  返回值:
  备注           : 
  作者           :
  日期           :
  ************************************************************************************/
int _stp_in_stpm_enable (UID_STP_MODE_T admin_state)
{
	register struct net_bridge *this;
	Bool created_here = False;
	int rc, err_code;

	/*printf("wl_debug:_stp_in_stpm_enable(%d)\r\n",admin_state);*/

	/*this = bridge_list;*/
	this = br_get_byname("default");/*modified by wl 2007-8-3*/

	if (this->admin_state == admin_state)
	{	
		return 0;
	}

	if (STP_ENABLED == admin_state)           /*rstp enable*/
	{
             /*如果配置状态为RSTP enable */

	
		rc = STP_stpm_enable(this,STP_ENABLED);
		
	}

	else
	{
		rc = STP_stpm_enable (this, STP_DISABLED);

	}


	return rc;
}


int _stp_in_stpm_disable ()
{
	register struct net_bridge *this;
	Bool created_here = False;
	int rc, err_code;

	/*printf ("_stp_in_stpm_disable.\r\n"); */
	/*this = bridge_list;*/
	this = br_get_byname("default");/*modified by wl 2007-8-3*/

	if (this->admin_state == STP_DISABLED)
	{
		return 0;
	}

	rc = STP_stpm_enable (this, STP_DISABLED);

	if (!rc)
	{
	/*	STP_OUT_set_hardware_mode (vlan_id, admin_state);*/
	}

	return rc;
}

#if 0

/***********************************************************************************
 *根据vlan id 在bridges链表中找到STPM_T项
 *
 ***********************************************************************************/
/*STPM_T *stpapi_stpm_find (int vlan_id)
{
	register STPM_T *this;

	for (this = STP_stpm_get_the_list (); this; this = this->next)
		if (vlan_id == this->vlan_id)
			return this;

	return NULL;
}
*/

static PORT_T *_stpapi_port_find (STPM_T * this, int port_index)
{
	register PORT_T *port;

	for (port = this->ports; port; port = port->next)
	{
		if (port_index == port->port_index)
		{
			return port;
		}
	}

	return NULL;
}

#endif

static void _conv_br_id_2_uid (IN BRIDGE_ID * f, OUT UID_BRIDGE_ID_T * t)
{
	memcpy (t, f, sizeof (UID_BRIDGE_ID_T));
}



/***********************************************************************************
 *
 * purpose : 检查参数的有效性
 * return:    
 ***********************************************************************************/
static int _check_stpm_config (IN UID_STP_CFG_T * uid_cfg,struct vty* vty)
{
	if (uid_cfg->bridge_priority < MIN_BR_PRIO)
	{
		vty_out(vty,"%d bridge_priority small", (int) uid_cfg->bridge_priority);
		return /*STP_Small_Bridge_Priority*/0;
	}

	if (uid_cfg->bridge_priority > MAX_BR_PRIO)
	{
		vty_out (vty,"%d bridge_priority large", (int) uid_cfg->bridge_priority);
		return /*STP_Large_Bridge_Priority*/0;
	}

	if (uid_cfg->hello_time < MIN_BR_HELLOT)
	{
		vty_out (vty,"%d hello_time small", (int) uid_cfg->hello_time);
		return STP_Small_Hello_Time;
	}

	if (uid_cfg->hello_time > MAX_BR_HELLOT)
	{
		vty_out(vty,"%d hello_time large", (int) uid_cfg->hello_time);
		return STP_Large_Hello_Time;
	}

	if (uid_cfg->max_age < MIN_BR_MAXAGE)
	{
		vty_out(vty,"%d max_age small", (int) uid_cfg->max_age);
		return STP_Small_Max_Age;
	}

	if (uid_cfg->max_age > MAX_BR_MAXAGE)
	{
		vty_out (vty,"%d max_age large", (int) uid_cfg->max_age);
		return STP_Large_Max_Age;
	}

	if (uid_cfg->forward_delay < MIN_BR_FWDELAY)
	{
		vty_out (vty,"%d forward_delay small", (int) uid_cfg->forward_delay);
		return STP_Small_Forward_Delay;
	}

	if (uid_cfg->forward_delay > MAX_BR_FWDELAY)
	{
		vty_out (vty,"%d forward_delay large", (int) uid_cfg->forward_delay);
		return STP_Large_Forward_Delay;
	}

	if (2 * (uid_cfg->forward_delay - 1) < uid_cfg->max_age)
	{
		vty_out(vty,"The parameter is not correct\r\n");
		return STP_Forward_Delay_And_Max_Age_Are_Inconsistent;
	}

	if (uid_cfg->max_age < 2 * (uid_cfg->hello_time + 1))
	{
		vty_out(vty,"The parameter is not correct\r\n");
		return STP_Hello_Time_And_Max_Age_Are_Inconsistent;
	}

	return 0;
}



static void _stp_in_enable_port_on_stpm (struct net_bridge_port * stpm, struct net_bridge_port *port,
	Bool enable)
{
	
	if (port->portEnabled == enable)
	{	/* nothing to do :) */
		return;
	}

	port->uptime = 0;

	if (enable)
	{	/* clear port statistics */
		port->rx_cfg_bpdu_cnt = port->rx_rstp_bpdu_cnt = port->rx_tcn_bpdu_cnt =
			0;
	}

#ifdef STP_DBG
	if (port->edge->debug)
	{
		stp_trace ("Port %s became '%s' adminEdge=%c", port->port_name,
			enable ? "enable" : "disable", port->adminEdge ? 'Y' : 'N');
	}
#endif

	port->adminEnable = enable;
	STP_port_init (port, stpm, False);

	port->reselect = True;
	port->selected = False;
}



#if 0
void STP_IN_init (int max_port_index)
{
	max_port = max_port_index;
	RSTP_INIT_CRITICAL_PATH_PROTECTIO;
}
#endif



/************************************************************************************
  * 函数名称:  STP_IN_stpm_get_cfg
  * 功能描述:  如果桥若干参数的配置与默认 配置不一样,则把
                               fieldmask相应的位置。并将参数值赋值给uid_cfg
     输入参数:  
     输出参数:
     返回值:
     备注:
     修改记录: 去掉stpapi_stpm_find ,不需要根据vlan_id寻找网桥
     
  *
  ************************************************************************************/
int STP_IN_stpm_get_cfg ( OUT UID_STP_CFG_T * uid_cfg)
{
	register struct net_bridge *this;

	uid_cfg->field_mask = 0;

	semTake(sem_rstp,WAIT_FOREVER);

	/*this = bridge_list;*/
	this = br_get_byname("default");/*modified by wl 2007-8-3*/

	if (this->admin_state != STP_DISABLED)
	{
		uid_cfg->field_mask |= BR_CFG_STATE;
	}
	uid_cfg->stp_enabled = this->admin_state;

	if (this->ForceVersion != 2)
	{
		uid_cfg->field_mask |= BR_CFG_FORCE_VER;
	}
	uid_cfg->force_version = this->ForceVersion;

	if (this->BrId.prio != DEF_BR_PRIO)
	{
		uid_cfg->field_mask |= BR_CFG_PRIO;
	}
	uid_cfg->bridge_priority = this->BrId.prio;

	if (this->BrTimes.MaxAge != DEF_BR_MAXAGE)
	{
		uid_cfg->field_mask |= BR_CFG_AGE;
	}
	uid_cfg->max_age = this->BrTimes.MaxAge;

	if (this->BrTimes.HelloTime != DEF_BR_HELLOT)
	{
		uid_cfg->field_mask |= BR_CFG_HELLO;
	}
	uid_cfg->hello_time = this->BrTimes.HelloTime;

	if (this->BrTimes.ForwardDelay != DEF_BR_FWDELAY)
	{
		uid_cfg->field_mask |= BR_CFG_DELAY;
	}
	uid_cfg->forward_delay = this->BrTimes.ForwardDelay;

	uid_cfg->hold_time = TxHoldCount;

	semGive(sem_rstp);
	return 0;
}



/****************************************************************************************
	函数名称: STP_IN_port_get_cfg
	功能描述: 获取端口的配置信息,写入uid_cfg
	输入参数: port
	输出参数: uid_cfg
	返回值:      0            -成功返回
	                        不为0 -遇错返回
	备注:
	作者:            wl
	日期:            2003-03-14

*****************************************************************************************/
int STP_IN_port_get_cfg (struct net_bridge_port *port,UID_STP_PORT_CFG_T * uid_cfg)
{
	

	if (!port)
	{	
		return STP_Port_Is_Absent_In_The_Vlan;
	}
	

	
	semTake(sem_rstp,WAIT_FOREVER);

		
	uid_cfg->field_mask = 0;

	uid_cfg->port_priority = port->port_id >> 8;
	if (uid_cfg->port_priority != DEF_PORT_PRIO)
	{
		uid_cfg->field_mask |= PT_CFG_PRIO;
	}

	uid_cfg->admin_port_path_cost = port->adminPCost;
	if (uid_cfg->admin_port_path_cost != ADMIN_PORT_PATH_COST_AUTO)
	{
		uid_cfg->field_mask |= PT_CFG_COST;
	}

	uid_cfg->admin_point2point = port->adminPointToPointMac;
	if (uid_cfg->admin_point2point != DEF_P2P)
	{
		uid_cfg->field_mask |= PT_CFG_P2P;
	}

	uid_cfg->admin_edge = port->adminEdge;
	if (uid_cfg->admin_edge != DEF_ADMIN_EDGE)
	{	
		uid_cfg->field_mask |= PT_CFG_EDGE;
	}

	semGive(sem_rstp);
	return 0;
}


/****************************************************************************************
	函数名称: STP_IN_port_get_state
	功能描述: 获取端口的状态信息,写入entry
	输入参数: port
	输出参数: entry
	返回值:      0            -成功返回
	                        不为0 -遇错返回
	备注:
	作者:            wl
	日期:            2003-03-14

*****************************************************************************************/
int STP_IN_port_get_state (IN struct net_bridge_port *port, INOUT UID_STP_PORT_STATE_T * entry)
{
	
	if (!port)
	{
		return STP_Port_Is_Absent_In_The_Vlan;

⌨️ 快捷键说明

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