📄 stp_appl.c
字号:
* Parameters:
* t - New max age timer value
* Returns:
* none
*/
void
stp_set_max_age(stp_id_t tree_id, uint16 t)
{
spantree_t *stp;
stp = stp_lookup_from_stp_id(tree_id);
if (stp == NULL) {
return;
}
set_max_age_api(stp, t);
if (stp_stack_ready) {
stp_send_timer_info(tree_id, t, STP_RDP_MAX_AGE);
}
}
/*
* Function:
* stp_set_forward_delay
* Purpose:
* Set forward delay vlaue
* Parameters:
* t - New forward delay vlaue
* Returns:
* none
*/
void
stp_set_forward_delay(stp_id_t tree_id, uint16 t)
{
spantree_t *stp;
stp = stp_lookup_from_stp_id(tree_id);
if (stp == NULL) {
return;
}
set_forward_delay_api(stp, t);
if (stp_stack_ready) {
stp_send_timer_info(tree_id, t, STP_RDP_FWD_DELAY);
}
}
/*
* Function:
* stp_set_bridge_priority
* Purpose:
* Set new spanning tree bridge priority
* Parameters:
* t - New spanning tree bridge priority
* Returns:
* none
*/
void
stp_set_bridge_priority(stp_id_t tree_id, uint16 t)
{
spantree_t *stp;
uint8 new_bridge_id[ID_BYTES];
stp = stp_lookup_from_stp_id(tree_id);
if (stp == NULL) {
return;
}
soc_htons_store(new_bridge_id, t);
sal_memcpy((new_bridge_id + 2), stp_bridge_mac, 6);
set_bridge_id_api(stp, new_bridge_id);
}
/*
* Function:
* stp_port_set
* Purpose:
* Force port enable/disable by CLI
* Parameters:
* pport - identify the port to be disabled
* flag - 1 for enable, 0 for disable
* Returns:
* none
*/
int
stp_port_set(stp_id_t tree_id, int unit, pbmp_t pbmp, int flag)
{
spantree_t *stp;
int port, lport;
stp = stp_lookup_from_stp_id(tree_id);
if (stp == NULL) {
return (-1);
}
if (!stp_is_running(stp)) {
trace(TRACE_STP, TR_ERROR, "STP not enabled\n");
return (-1);
}
PBMP_ITER(pbmp, port) {
lport = stp_port_p2l(stp_my_cpuid, unit, port);
/* In stacking mode, let other CPUs know */
if (stp_stack_ready) {
stp_send_port_info(tree_id, lport, STP_PORT_INFO_ENABLE, flag, 0);
}
if (flag == 1) {
stp_port_enable(stp, lport);
} else {
stp_port_disable(stp, lport);
}
}
return 0;
}
/*
* Helper function that returns state for lport
*/
static char
stp_port_state_as_char(spantree_t *stp, int lport)
{
stp_port_t *stport;
stport = stp_port_lookup_from_id(stp, lport);
if (stport == NULL) {
return ('X');
}
switch (stport->state) {
case STP_DISABLED:
if (stport->link_flags & STP_LF_TRUNKMEMBER) {
return ('T');
} else if (stport->link_flags & STP_LF_STACK) {
return ('S');
} else {
return ('D');
}
case STP_LISTENING:
return ('L');
case STP_LEARNING:
return ('I');
case STP_FORWARDING:
if (stport->link_flags & STP_LF_TRUNKROOT) {
return ('R');
}
if (stport->link_flags & STP_LF_TRUNKMEMBER) {
return ('M');
}
return ('F');
case STP_BLOCKING:
return ('B');
default:
return ('X');
}
}
/*
* Helper function that print port states for one module in the stack
*/
static void
stp_print_port_states_for_mod(spantree_t *stp, uint16 cpu)
{
int port, lport;
int unit, num_ports;
for (unit = 0; unit < stp_stk_modinfo[cpu].num_chip; unit++) {
num_ports = stp_get_num_ports(stp_stk_modinfo[cpu].chip[unit].chip_type);
for (port = 0; port < num_ports; port++) {
lport = stp_port_p2l(cpu, unit, port);
printk("%c", stp_port_state_as_char(stp, lport));
if (!((port+1) % 8)) {
printk(" ");
}
}
printk(" ");
}
printk("\n");
return;
}
/*
* Function:
* stp_print_port_states
* Purpose:
* Print port states
* Parameters:
* none
* Returns:
* none
*/
void
stp_print_port_states(stp_id_t tree_id)
{
spantree_t *stp;
int cpu, port, lport;
int unit, num_ports;
stp = stp_lookup_from_stp_id(tree_id);
if (stp == NULL) {
return;
}
if (!stp_is_running(stp)) {
printk("Spanning Tree %d not running\n", tree_id);
return;
}
printk("X=Down, D=Dis, L=Lis, I=Lrn, B=Blk, F=Fwd, T=Trunk, S=StkLk\n");
if (stp_stack_ready) {
printk("(-> this module)\n");
}
if (stp_stack_ready) {
for (cpu = 1; cpu <= stp_stk_num_cpu; cpu++) {
if (cpu == stp_my_cpuid) {
printk("->");
} else {
printk(" ");
}
stp_print_port_states_for_mod(stp, cpu);
}
} else {
for (unit = 0; unit < stp_stk_modinfo[1].num_chip; unit++) {
printk(" ");
num_ports = stp_get_num_ports(stp_stk_modinfo[1].chip[unit].chip_type);
for (port = 0; port < num_ports-1; port++) {
lport = stp_port_p2l(stp_my_cpuid, unit, port);
printk("%c", stp_port_state_as_char(stp, lport));
if (!((port+1) % 4)) {
printk(" ");
}
}
}
}
printk("\n");
}
/*
* Function:
* stp_print_root_id
* Purpose:
* Print bridge root ID and root port
* Parameters :
* none
* Returns:
* none
*/
void
stp_print_root_id(stp_id_t tree_id)
{
spantree_t *stp;
uint16 priority,vlan_id,temp_bridge_id;
char t[6];
stp = stp_lookup_from_stp_id(tree_id);
if (stp == NULL) {
return;
}
temp_bridge_id = soc_ntohs_load(stp->bridge_id);
priority = (temp_bridge_id & 0xf000)>>12 ;
vlan_id = temp_bridge_id & 0x0fff;
sal_memcpy(t, (stp->bridge_id + 2), 6);
printk("Root bridge priority - %d.%d\n", priority,vlan_id);
printk("Bridge ID - %X:%X:%X:%X:%X:%X\n", t[0], t[1], t[2], t[3], t[4], t[5]);
/* stacking mode */
if (stp_stack_ready) {
printk("(In stacking mode, Bridge ID is master CPU's address)");
printk("\nRoot Bridge - stack\n");
return;
}
if (stp->root_path_cost != 0) {
sal_memcpy(t, (stp->designated_root + 2), 6);
printk("Root Bridge - %X:%X:%X:%X:%X:%X\n",
t[0], t[1], t[2], t[3], t[4], t[5]);
printk("Root Port - %d\n", get_global_port(stp->root_port->unit,stp->root_port->port));
} else {
printk("\nRoot Bridge - self\n");
}
}
/* zgs added this for mstp begin */
/*------------------------------------------------------------------------------
* FUNCTION:get_tree_stp_by_vid
* DESCRIPTION:根据vlan ID查找stp,
*
* AUTHOR:ZHOUGUIS
-------------------------------------------------------------------------------*/
spantree_t * get_tree_stp_by_vid(vlan_id_t vid)
{
spantree_t *stp;
FOR_ALL_STP(stp) {
if (stp->external_id == vid) {
return (stp);
}
}
return NULL;
}
/*------------------------------------------------------------------------------
* FUNCTION:get_global_port
* DESCRIPTION:通过局部端口和单元号,查找全局端口。
*
* AUTHOR:ZHOUGUIS
-------------------------------------------------------------------------------*/
int get_global_port(int unit,int lcport)
{
int gport;
#if BOARD_TYPE==RHS8012GE_3T8F
gport = lcport+2 ;
return gport;
#endif
gport = unit?(lcport+13):(lcport+1);
return gport;
}
/*------------------------------------------------------------------------------
* FUNCTION:print_stp_port_info
* DESCRIPTION:打印所有STP的活动端口的信息。
*
* AUTHOR:ZHOUGUIS
-------------------------------------------------------------------------------*/
int print_stp_port_info()
{
spantree_t *stp,*stptemp;
stp_port_t *sport;
int gport;
char cs;
printk("L=Lis, I=Lrn, B=Blk, F=Fwd, R=Aggr Root, M=Aggr Member\n");
FOR_ALL_STP(stp)
{
if(stp == NULL)
{
return 0;
}
stptemp = stp;
printL("#########STP %04d: ","#########STP %04d: ",stp->external_id);
printL("\n------------------------------------------------------------\n", \
"\n------------------------------------------------------------\n");
printL("PORT STATE COST SPEED PRI\n",
"PORT STATE COST SPEED PRI\n");
sport = stp->port_list.next ;
while (sport != &stp->port_list)
{
gport = get_global_port(sport->unit,sport->port);
cs = stp_port_state_as_char(stp, sport->lport);
printL("%4d %5c %5d %10s %3d\n",\
"%4d %5c %5d %10s %3d\n",\
gport,cs,sport->path_cost,stp_port_speed_string(sport->path_cost),(sport->port_id >> 12));
sport = sport->next;
}
printL("\n","\n");
}
return 0;
}
/*------------------------------------------------------------------------------
* FUNCTION:search_stg_through_vlan
* DESCRIPTION:通过VLAN ID查找相应的STG ID.
* 因为vlan id有4096个,而stg id只有256个。因此需要做一张对应表。
* AUTHOR:ZHOUGUIS
-------------------------------------------------------------------------------*/
int search_stg_through_vlan(bcm_vlan_t vid)
{
int i;
for(i=1;i<256;i++)
{
if(vlan_stg_mapping_table[i].vlan == vid)
{
return vlan_stg_mapping_table[i].stg;
}
}
return 1;
}
/*------------------------------------------------------------------------------
* FUNCTION:decrease_stg_number
* DESCRIPTION:当删除一个stg的时候要把相应的对应信息删除。
*
* AUTHOR:ZHOUGUIS
-------------------------------------------------------------------------------*/
void decrease_stg_number(vlan_id_t vid)
{
int i=0;
for(i=1;i<256;i++)
{
if(vlan_stg_mapping_table[i].vlan == vid)
{
vlan_stg_mapping_table[i].stg = 0;
vlan_stg_mapping_table[i].vlan = 0;
return;
}
}
}
/*------------------------------------------------------------------------------
* FUNCTION:init_clear_all_mapping_table
* DESCRIPTION:在初始化STP系统的时候,初始化VLAN和STG的对应表。
*
* AUTHOR:ZHOUGUIS
-------------------------------------------------------------------------------*/
void init_clear_all_mapping_table(void)
{
int i=0;
vlan_stg_mapping_table[i].stg = 1;
vlan_stg_mapping_table[i].vlan = 1;
for(i=1;i<256;i++)
{
vlan_stg_mapping_table[i].stg = 0;
vlan_stg_mapping_table[i].vlan = 0;
}
}
/*------------------------------------------------------------------------------
* FUNCTION:find_newstg_forvlan
* DESCRIPTION:为一个新的VLAN寻找一个空表。
* AUTHOR:ZHOUGUIS 2005-12-15
-------------------------------------------------------------------------------*/
bcm_stg_t find_newstg_forvlan(vlan_id_t vid)
{
int i=0;
if(vid == 1)
{
return 1;
}
for(i=1;i<256;i++)
{
if((vlan_stg_mapping_table[i].stg == 0)&&
(vlan_stg_mapping_table[i].vlan == 0))
{
vlan_stg_mapping_table[i].stg = i+1;
vlan_stg_mapping_table[i].vlan = vid;
return (i+1);
}
}
return 1;
}
/*------------------------------------------------------------------------------
* FUNCTION:find_newstg_forvlan
* DESCRIPTION:为一个新的VLAN寻找一个空表。
*
* AUTHOR:ZHOUGUIS
-------------------------------------------------------------------------------*/
void print_vlan_stg_mapping_table(void)
{
int i=0;
for(i=0;i<256;i++){
if(vlan_stg_mapping_table[i].stg != 0){
printf("stg= %d vlan = %d \n",vlan_stg_mapping_table[i].stg,vlan_stg_mapping_table[i].vlan);
}
}
return ;
}
/*------------------------------------------------------------------------------
* FUNCTION:stp_lock_link
* DESCRIPTION:为一个新的VLAN寻找一个空表。
* AUTHOR:ZHOUGUIS
-------------------------------------------------------------------------------*/
void stp_lock_link(void)
{
STP_LOCK();
}
void stp_unlock_link(void)
{
STP_UNLOCK();
}
/* zgs added this for mstp end */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -