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

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

/* This file contains system dependent API
   from the RStp to a operation system (see stp_to.h) */

/* stp_to API for Linux */

#include <stddef.h>
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include <unistd.h>

#include "base.h"
#include "stpm.h"
#include "stp_in.h"
#include "stp_to.h"
#include "bitmap.h"
#include "../switch/port.h"

BITMAP_T enabled_ports;


#if 0
int DeleteMacByPort (short port_no)
{

return 1;
}
#endif/*delete by wl 2005-9-5,由wjp写一个真正的删除地址的函数*/

/*void
stp_trace (const char *format, ...)
{
	mn_fd_printf(cl_serv_console_fd,format);
}
*/

#ifdef STRONGLY_SPEC_802_1W
int STP_OUT_set_learning (int port_index, int vlan_id, int enable)
{
	stp_trace("port %d  learning");
	return STP_OK;
}

int STP_OUT_set_forwarding (int port_index, int vlan_id, int enable)
{
	stp_trace("port %d  forwarding");
	return STP_OK;
}
#else
/* 
 * In many kinds of hardware the state of ports may
 * be changed with another method
 */
int STP_OUT_set_port_state (IN struct net_bridge_port* port,IN RSTP_PORT_STATE state)
{
	int new_state;

	/*printf("STP_OUT_set_port_state %d status %d\r\n",port->port_no,state);*/
	
	
	if(!(port->flags & PortFlagEnable))
	{
              
		driver_setportstpstate(port->port_no,PortSTPDisabled);
		DeleteMacByPort(port->port_no);
		return;
	}

	/*printf("STP_OUT_set_port_state,1111111111\r\n");*/

	/*if(port->port_no == mirror.mirroredportno)
	{
		if(p->flags & PortFlagLinked)
			driver_setportstpstate(p->port_no,PortSTPForwarding);
		else
			driver_setportstpstate(p->port_no,PortSTPDisabled);
	}
	*/

	

	switch(state)
	{
		case  UID_PORT_DISABLED :
			new_state = PortSTPDisabled;
			break;
		case  UID_PORT_DISCARDING:
			new_state = PortSTPBlocking;
			break;
		case  UID_PORT_LEARNING :
			new_state = PortSTPLearning;
			break;
		case  UID_PORT_FORWARDING :
			new_state = PortSTPForwarding;
			break;
		case  UID_PORT_NON_STP :
			new_state = PortSTPForwarding;
			break;
   
	}

	#ifndef _CTC_
	if((port->br->admin_state == STP_ENABLED) && !(port->admin_non_stp))/*del by wl 2007-3-23*/
	#endif
	{
		if (new_state == PortSTPDisabled || new_state == PortSTPBlocking)
		{
			driver_setportstpstate(port->port_no,new_state);

			/*printf("br_sync_trunk_member_rstp_state %d \r\n",port->port_no,new_state);*/

			br_sync_trunk_member_rstp_state1(port);

			/*printf("Delete Mac\r\n,%d",port->port_no);*/
			DeleteMacByPort(port->port_no); /*added by wl for master-slave transition*/
			
		}
		else
		{
			
			driver_setportstpstate(port->port_no,new_state);

			/*printf("br_sync_trunk_member_rstp_state %d \r\n",port->port_no);*/
			br_sync_trunk_member_rstp_state1(port);

			if (new_state == PortSTPForwarding)
				DeleteMacByPort(port->port_no);
			
		}
	
	}
	
/*	else
	{
		driver_setportstpstate(port->port_no,PortSTPForwarding);
	}
*/
	return STP_OK;
	/*return AR_INT_STP_set_port_state (port_index, vlan_id, state);*/
}

#endif

void STP_OUT_get_port_mac (struct net_bridge_port *p, unsigned char *mac)
{
	memcpy(mac, br_get_portMacaddr(p), ETH_ALEN);
       
}


int STP_OUT_flush_lt (IN int port_index, IN int vlan_id, LT_FLASH_TYPE_T type,
	char *reason)
{

/****
  stp_trace("clearFDB (%d, %s, '%s')",
        port_index, 
        (type == LT_FLASH_ALL_PORTS_EXCLUDE_THIS) ? "Exclude" : "Only", 
        reason);
****/

	return STP_OK;
}

int STP_OUT_set_hardware_mode (int vlan_id, UID_STP_MODE_T mode)
{
	return STP_OK;
	/*return AR_INT_STP_set_mode (vlan_id, mode);*/
}

/**********************************************************************
* function: build_config_bpdu
* purpose:构建config_bpdu包
* input:    port ,set_topo_ack_flag
* output:  
* return : 
* remark:
* author:
* date:
**********************************************************************/
int STP_OUT_tx_bpdu (int port_index, unsigned char *bpdu,
	unsigned int  bpdu_len)
{
struct net_bridge_port *p;
char new_bpdu[bpdu_len+4];
int i;

bzero(new_bpdu,64);
p = br_get_port_byno(port_index);
if (!p)
	return 0;

for (i = 0;i<12;i++)
    new_bpdu[i]=*(bpdu+i);

    new_bpdu[12] = 0x81;
    new_bpdu[13] = 0x00;
    new_bpdu[14] = 0x00;
    new_bpdu[15] = 0x00;

    for (i = 16;i<bpdu_len+4;i++)
	    new_bpdu[i] = *(bpdu+i-4);
    
 br_send_MSC(p->port_no, &new_bpdu[0], 64,0);

 #if 0

 printf("----------------------bpudu---------------------------\r\n");

 for (i =0;i<64;i++)

 {
	printf("%2x ",new_bpdu[i] );

	if (i%20 ==0)
		printf("\r\n");
 }
 printf("----------------------bpdu end---------------------------\r\n");
 #endif
 
/*bpdu_bd_transmit(p,bpdu,bpdu_len);*/
/*	driver_send_bpdu(port_index,bpdu,bpdu_len);*/
}

const char *STP_OUT_get_port_name (IN int port_index)
{
	static char tmp[4];

	sprintf (tmp, "p%02d", (int) port_index);
	return tmp;
	/*return port2str (port_index, &sys_config);*/
}

unsigned long STP_OUT_get_deafult_port_path_cost (IN unsigned int portNo)
{
	return 20000;
}


/*************************************************************************************
 *  此函数应该是作者做试验所用,1,2端口是一种,3,4端口又【
    是一种
 **************************************************************************************/
unsigned long STP_OUT_get_port_oper_speed (unsigned int portNo)
{
/*	if (portNo <= 2)
		return 1000000L;
	else
		return 1000L;
		*/
	struct net_bridge_port * port = NULL;
	unsigned long speed;
	port = br_get_port_byno(portNo);

	if (!port )
	{
		return;
	}

	switch(port->type)
	{
		case PortType10M:
			speed = 10L;
			break;
		case PortType100MLX:
		case PortType100MSX:
		case PortType100MTX:
			speed = 100L;
			break;
		case PortType1000MLX:
		case PortType1000MSX:
			speed = 1000L;
			break;
		default:
			speed = 100L;
			break;
	
	}
	return speed;
}

/*
  *  此函数需改写,根据duplex情况来确定p2p
  */

int								/* 1- Full, 0- Half */
STP_OUT_get_duplex (IN int port_index)
{
	return 1;
}


/***********************************************************************************
 * function:
 * purpose:配置桥一级参数和force_version
 * 
 *
 ***********************************************************************************/

int STP_OUT_get_init_stpm_cfg (IN int vlan_id, INOUT UID_STP_CFG_T * cfg)
{
	cfg->bridge_priority = DEF_BR_PRIO;
	cfg->max_age = DEF_BR_MAXAGE;
	cfg->hello_time = DEF_BR_HELLOT;
	cfg->forward_delay = DEF_BR_FWDELAY;
	cfg->force_version = NORMAL_RSTP;

	return STP_OK;
}

/*int STP_OUT_get_init_port_cfg (IN int vlan_id, IN int port_index,
	INOUT UID_STP_PORT_CFG_T * cfg)
{
	cfg->port_priority = DEF_PORT_PRIO;
	cfg->admin_non_stp = DEF_ADMIN_NON_STP;
	cfg->admin_edge = DEF_ADMIN_EDGE;
	cfg->admin_port_path_cost = ADMIN_PORT_PATH_COST_AUTO;
	cfg->admin_point2point = DEF_P2P;

	return STP_OK;
}
*/

#if 0/*del by wl 2005-7-25 for debug*/
int test_rstp_fdb1(short port_no)
{
		DeleteMacByPort(port_no); /*added by wl for master-slave transition*/
		driver_setportstpstate(port_no,PortSTPBlocking);
  
}


int test_rstp_fdb2(short port_no)
{
		driver_setportstpstate(port_no,PortSTPForwarding);
  
}
#endif


void br_sync_trunk_member_rstp_state (struct net_bridge_port *p)
{

	
	if ((p->flags & PortFlagTrunkMaster) && (p->trunkgroupindex >= 0) &&
		(p->trunkgroupindex < MaxPortTrunkNum))
	{
		struct net_bridge_port *sp;
		int i;

		for (i = 0; i < trunk[p->trunkgroupindex].memnum; i++)
		{
			sp = br_get_port_byno (trunk[p->trunkgroupindex].member[i]);

			if ((sp) && (sp->flags & PortFlagTrunked) &&
				(!(sp->flags & PortFlagTrunkMaster)))
			{
				/* martin 2001/02/20 */
				if (sp->adminEnable == STP_ENABLED)
				{	
				
					driver_setportstpstate (sp->port_no, p->state);
					sp->state = PortSTPDisabled;
				}

				
			}
		}
	}
}


	void br_sync_trunk_member_rstp_state1 (struct net_bridge_port *p)
{



	int rc;

	int state;
	UID_STP_PORT_STATE_T uid_port;
	/*printf("br_sync_trunk_member_rstp_state,%d,role = %d\r\n",p->port_no,p->role);*/

	switch(p->role)
	{
		case DisabledPort:
			state = PortSTPDisabled;
			break;
		case AlternatePort:
		case BackupPort:
			state = PortSTPBlocking;
			break;
		case RootPort:
		case DesignatedPort:
		case NonStpPort:
			state = PortSTPForwarding;
			break;
		default:
			state =PortSTPForwarding;
			break;

	}

	
	
	if ((p->flags & PortFlagTrunkMaster) && (p->trunkgroupindex >= 0) &&
		(p->trunkgroupindex < MaxPortTrunkNum))
	{
		struct net_bridge_port *sp;
		int i;

		for (i = 0; i < trunk[p->trunkgroupindex].memnum; i++)
		{
			sp = br_get_port_byno (trunk[p->trunkgroupindex].member[i]);

			if ((sp) && (sp->flags & PortFlagTrunked) &&
				(!(sp->flags & PortFlagTrunkMaster)))
			{
				/* martin 2001/02/20 */
				if (sp->adminEnable == STP_ENABLED)
				{	
					/*printf("br_sync_trunk_member_rstp_state,driver_set_portstate_port %d,%d\r\n",sp->port_no,state);*/
					/*driver_setportstpstate (sp->port_no, p->state);*/
					driver_setportstpstate (sp->port_no, state);
					/*sp->state = PortSTPDisabled;*/
				}

				
			}
		}
	}
}
	

⌨️ 快捷键说明

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