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

📄 stp_in.c

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

	semTake(sem_rstp,WAIT_FOREVER);


	entry->port_id = port->port_id;

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

	if (DisabledPort == port->role)
	{
		entry->state = UID_PORT_DISABLED;
	}

	else if (!port->forward && !port->learn)
	{
		entry->state = UID_PORT_DISCARDING;
	}

	else if (!port->forward && port->learn)
	{
		entry->state = UID_PORT_LEARNING;
	}

	else
	{
		entry->state = UID_PORT_FORWARDING;
	}

	entry->uptime = port->uptime;
	entry->path_cost = port->operPCost;
	_conv_br_id_2_uid (&port->portPrio.root_bridge, &entry->designated_root);
	entry->designated_cost = port->portPrio.root_path_cost;
	_conv_br_id_2_uid (&port->portPrio.design_bridge,
		&entry->designated_bridge);
	entry->designated_port = port->portPrio.design_port;

	switch (port->role)
	{
		case DisabledPort:
			entry->role = ' ';
			break;
		case AlternatePort:
			entry->role = 'A';
			break;
		case BackupPort:
			entry->role = 'B';
			break;
		case RootPort:
			entry->role = 'R';
			break;
		case DesignatedPort:
			entry->role = 'D';
			break;
		case NonStpPort:
			entry->role = '-';
			break;
		default:
			entry->role = '?';
			break;
	}

	if (DisabledPort == port->role || NonStpPort == port->role)
	{
		memset (&entry->designated_root, 0, sizeof (UID_BRIDGE_ID_T));
		memset (&entry->designated_bridge, 0, sizeof (UID_BRIDGE_ID_T));
		entry->designated_cost = 0;
		entry->designated_port = port->port_id;
	}

	if (DisabledPort == port->role)
	{
		entry->oper_point2point =
			(P2P_FORCE_FALSE == port->adminPointToPointMac) ? 0 : 1;
		entry->oper_edge = port->adminEdge;
	/*	printf("wl_debug,entry->operEdge = %d\r\n",port->operEdge);*/
		entry->oper_stp_neigb = 0;
	}
	else
	{
		entry->oper_point2point = port->operPointToPointMac ? 1 : 0;

		/*printf("wl_debug,port->operEdge = %d\r\n",port->operEdge);*/
		entry->oper_edge = port->operEdge ? 1 : 0;
		/*printf("wl_debug,entry->operEdge = %d\r\n",entry->operEdge);*/
		entry->oper_stp_neigb = port->sendRSTP ? 0 : 1;
	}
	entry->oper_port_path_cost = port->operPCost;

	entry->rx_cfg_bpdu_cnt = port->rx_cfg_bpdu_cnt;
	entry->rx_rstp_bpdu_cnt = port->rx_rstp_bpdu_cnt;
	entry->rx_tcn_bpdu_cnt = port->rx_tcn_bpdu_cnt;

	entry->fdWhile = port->fdWhile;	/* 17.15.1 */
	entry->helloWhen = port->helloWhen;	/* 17.15.2 */
	entry->mdelayWhile = port->mdelayWhile;	/* 17.15.3 */
	entry->rbWhile = port->rbWhile;	/* 17.15.4 */
	entry->rcvdInfoWhile = port->rcvdInfoWhile;	/* 17.15.5 */
	entry->rrWhile = port->rrWhile;	/* 17.15.6 */
	entry->tcWhile = port->tcWhile;	/* 17.15.7 */
	entry->txCount = port->txCount;	/* 17.18.40 */
	entry->lnkWhile = port->lnkWhile;

	entry->rcvdInfoWhile = port->rcvdInfoWhile;
	entry->top_change_ack = port->tcAck;
	entry->tc = port->tc;

	semGive(sem_rstp);
	return 0;
}

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

*****************************************************************************************/
int STP_IN_stpm_get_state (IN struct net_bridge *this, OUT UID_STP_STATE_T * entry)
{
	semTake(sem_rstp,WAIT_FOREVER);
	
	strncpy (entry->vlan_name, this->name, NAME_LEN);
	/*entry->vlan_id = this->vlan_id;*/
	
	_conv_br_id_2_uid (&this->rootPrio.root_bridge, &entry->designated_root);

	entry->root_path_cost = this->rootPrio.root_path_cost;
	entry->root_port = this->rootPortId;
	entry->max_age = this->rootTimes.MaxAge;
	entry->forward_delay = this->rootTimes.ForwardDelay;
	entry->hello_time = this->rootTimes.HelloTime;

	_conv_br_id_2_uid (&this->BrId, &entry->bridge_id);

	entry->stp_enabled = this->admin_state;
	entry->timeSince_Topo_Change = this->timeSince_Topo_Change;
	entry->Topo_Change_Count = this->Topo_Change_Count;
	entry->Topo_Change = this->Topo_Change;

	semGive(sem_rstp);
	return 0;
}

#if 0
int STP_IN_stpm_get_name_by_vlan_id (int vlan_id, char *name, size_t buffsize)
{
	register STPM_T *stpm;
	int iret = -1;

	RSTP_CRITICAL_PATH_START;
	for (stpm = STP_stpm_get_the_list (); stpm; stpm = stpm->next)
	{
		if (vlan_id == stpm->vlan_id)
		{
			if (stpm->name)
				strncpy (name, stpm->name, buffsize);
			else
				memset (name, 0, buffsize);
			iret = 0;
			break;
		}
	}
	RSTP_CRITICAL_PATH_END;
	return iret;
}



#endif

int STP_IN_enable_port (struct net_bridge_port *port, Bool enable)/* call it, when link Up/Down */
{
	register struct net_bridge *br ;

	
	br = port->br;



	semTake(sem_rstp,WAIT_FOREVER);
	
	tev = enable ? RSTP_PORT_EN_T : RSTP_PORT_DIS_T;
	/*INCR100 (nev);*/


	if (!enable)
	{
#ifdef STP_DBG
		stp_trace ("%s (p%02d, all, %s, '%s')", "clearFDB", (int) port_index,
			"this port", "disable port");
#endif
	/*	STP_OUT_flush_lt (port_index, 0, LT_FLASH_ONLY_THE_PORT,
			"disable port");
           added by wl */

	}

	
		if (STP_ENABLED != br->admin_state)
		{
			semGive(sem_rstp);
			return -1;
		}



		_stp_in_enable_port_on_stpm (br, port, enable);
		/* STP_stpm_update (stpm); */
	

	semGive(sem_rstp);
	return 0;
}



#if 0
int								/* call it, when port speed has been changed, speed in Kb/s  */
STP_IN_changed_port_speed (int port_index, long speed)
{
	register STPM_T *stpm;
	register PORT_T *port;

	RSTP_CRITICAL_PATH_START;
	tev = RSTP_PORT_SPEED_T;
	INCR100 (nev);
	for (stpm = STP_stpm_get_the_list (); stpm; stpm = stpm->next)
	{
		if (STP_ENABLED != stpm->admin_state)
			continue;

		port = _stpapi_port_find (stpm, port_index);
		if (!port)
			continue;
		port->operSpeed = speed;
#ifdef STP_DBG
		if (port->pcost->debug)
		{
			stp_trace ("changed operSpeed=%lu", port->operSpeed);
		}
#endif

		port->reselect = True;
		port->selected = False;
	}
	semGive(sem_rstp);
	return 0;
}

int								/* call it, when port duplex mode has been changed  */
STP_IN_changed_port_duplex (int port_index)
{
	register STPM_T *stpm;
	register PORT_T *port;

	RSTP_CRITICAL_PATH_START;
	tev = RSTP_PORT_DPLEX_T;
	INCR100 (nev);
	for (stpm = STP_stpm_get_the_list (); stpm; stpm = stpm->next)
	{
		if (STP_ENABLED != stpm->admin_state)
			continue;

		port = _stpapi_port_find (stpm, port_index);
		if (!port)
			continue;
#ifdef STP_DBG
		if (port->p2p->debug)
		{
			stp_trace ("STP_IN_changed_port_duplex(%s)", port->port_name);
		}
#endif
		port->p2p_recompute = True;
		port->reselect = True;
		port->selected = False;
	}
	RSTP_CRITICAL_PATH_END;
	return 0;
}

int STP_IN_check_bpdu_header (BPDU_T * bpdu, size_t len)
{
	unsigned short len8023;

	len8023 = ntohs (*(unsigned short *) bpdu->eth.len8023);
	if (len8023 > 1500)
	{	/* big len8023 format :( */
		return STP_Big_len8023_Format;
	}

	if (len8023 < MIN_BPDU)
	{	/* small len8023 format :( */
		return STP_Small_len8023_Format;
	}

	if (len8023 + 14 > len)
	{	/* len8023 format gt len :( */
		return STP_len8023_Format_Gt_Len;
	}

	if (bpdu->eth.dsap != BPDU_L_SAP || bpdu->eth.ssap != BPDU_L_SAP ||
		bpdu->eth.llc != LLC_UI)
	{
		/* this is not a proper 802.3 pkt! :( */
		return STP_Not_Proper_802_3_Packet;
	}

	if (bpdu->hdr.protocol[0] || bpdu->hdr.protocol[1])
	{
		return STP_Invalid_Protocol;
	}

#if 0
	if (bpdu->hdr.version != BPDU_VERSION_ID)
	{
		return STP_Invalid_Version;
	}
#endif
	/* see also 9.3.4: think & TBD :( */
	return 0;
}

#ifdef STP_DBG
int dbg_rstp_deny = 0;
#endif

#endif



int STP_IN_rx_bpdu (unsigned char *pkt/*,int vlan_id, BPDU_T * bpdu, size_t len*/)
{
	
	
	int iret;
	unsigned char *buf; /*LLC pkt */
	short portno;
	struct net_bridge_port *port;
	BPDU_T *bpdu;

	semTake(sem_rstp,WAIT_FOREVER);

	portno = *(short *)pkt;
	port = br_get_port_byno(portno);/*get the port's structure whose port number equal to portno*/

	if(!port)
	{

		free(pkt);
		return;		
	}

	buf = pkt + 14 ;/*DA,SA...*/
	bpdu = (BPDU_T*)buf;

	if (STP_DISABLED == port->br->admin_state)
	{	/* the stpm had not yet been enabled :( */
		semGive(sem_rstp);
		return STP_Had_Not_Yet_Been_Enabled_On_The_Vlan;
	}

	
#ifdef STP_DBG
	if (port->skip_rx > 0)
	{
		if (1 == port->skip_rx)
			stp_trace ("port %s stop rx skipping", port->port_name);
		else
			stp_trace ("port %s skip rx %d", port->port_name, port->skip_rx);
		port->skip_rx--;
		RSTP_CRITICAL_PATH_END;
		return STP_Nothing_To_Do;
	}
#endif

	if (port->operEdge && !port->lnkWhile && port->portEnabled)
	{
#ifdef STP_DBG
		if (port->topoch->debug)
		{
			stp_trace ("port %s tc=TRUE by operEdge", port->port_name);
		}
#endif
		port->tc = True;	/* IEEE 802.1y, 17.30 */
	}


#if 0
	if (!port->portEnabled)
	{	/* port link change indication will come later :( */
		_stp_in_enable_port_on_stpm (this, port->port_index, True);
	}
#endif     /*added by wl*/

#ifdef STP_DBG
	if (port->edge->debug && port->operEdge)
	{
		stp_trace ("port %s not operEdge !", port->port_name);
	}
#endif

	port->operEdge = False;
	port->wasInitBpdu = True;

	/*iret = STP_port_rx_bpdu (port, bpdu, len);*/
	STP_info_rx_bpdu(port,bpdu/*,len*/);
	
	STP_stpm_update (port->br);
	semGive(sem_rstp);
	
free(pkt);

	return iret;
}



/****************************************************************************************
	函数名称: STP_IN_one_second
	功能描述: 每秒钟进入此函数一次,主要是改变状态机
	输入参数: 
	输出参数: 所有的状态机
	返回值:      dbg_cn-进入的次数
	备注:
	作者:            wl
	日期:            2003-03-14

*****************************************************************************************/
int STP_IN_one_second (void)
{
	/*register struct net_bridge *stpm = bridge_list;*/
	register struct net_bridge *stpm = br_get_byname("default");/*modified by wl 2007-8-3*/
	register int dbg_cnt = 0;

	semTake(sem_rstp,WAIT_FOREVER);

	/*tev = RSTP_PORT_TIME_T;*/

       /*延时函数?*/
/*	INCR100 (nev);*/

	while (stpm)
	{
		if (STP_ENABLED == stpm->admin_state)
		{
			
			STP_stpm_one_second (stpm);
			dbg_cnt++;
		}
		stpm = stpm->next;
	}

	semGive(sem_rstp);

	return dbg_cnt;
}



/************************************************************************************
 * 函数名称:   STP_IN_stpm_set_cfg
 * 功能描述:
 * 输入参数:
 * 输出参数:
 * 返回值:
 * 备注:
 * 作者:
 * 日期:
 *  
 ************************************************************************************/
int STP_IN_stpm_set_cfg (IN UID_STP_CFG_T * uid_cfg,struct vty*vty)
{
	int rc = 0, prev_prio, err_code;
	Bool created_here, enabled_here;

	register struct net_bridge *this;
	UID_STP_CFG_T old;

⌨️ 快捷键说明

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