📄 stp_in.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.
**********************************************************************/
/* 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 + -