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

📄 macbrspn.c

📁 以太网交换机协议平台stp协议的设计与实现源代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
		stp_class.port[port_number].configuration_pending = FALSE;

		stp_printf (STP_ALGORITHM_PRINTF,"STP: start hold timer \n\r",port_number);

		set_timer (&stp_class.port[port_number].hold_time,START_TIMER);

		stp_printf (STP_ALGORITHM_PRINTF,"STP: transmit configuration %04x\n\r",port_number);
		}
}
/****************************************************************************/   /** 4.6.2 */ 
enum BOOLEAN root_bridge (void)
{
	if (compare_identifiers (&stp_class.this_bridge.root_id,&stp_class.this_bridge.bridge_id) == EQUAL_TO)
		{
		return (TRUE);
		}
	else
		{
		return (FALSE);
		}
}
/****************************************************************************/    /** 4.6.2 */ 
static void record_configuration_port_information (USHORT port_number,BRIDGE_CONFIGURATION_BPDU *sptr_bridge_configuration_BPDU)
{
	stp_class.port[port_number].designated_root_id = sptr_bridge_configuration_BPDU->root_id;

	stp_class.port[port_number].designated_root_path_cost =
		sptr_bridge_configuration_BPDU->root_path_cost;

	stp_class.port[port_number].designated_bridge_id = sptr_bridge_configuration_BPDU->bridge_id;
	stp_class.port[port_number].designated_port_id = sptr_bridge_configuration_BPDU->port_id;

	start_message_age_timer (&stp_class.port[port_number].message_age,START_TIMER,
		sptr_bridge_configuration_BPDU->message_age);
}
/****************************************************************************/   /** 4.6.3 */ 
static void record_hello_timeout_values (BRIDGE_CONFIGURATION_BPDU *sptr_bridge_configuration_BPDU)
{
	stp_class.this_bridge.max_age = sptr_bridge_configuration_BPDU->max_age;
	stp_class.this_bridge.hello_time = sptr_bridge_configuration_BPDU->hello_time;
	stp_class.this_bridge.forward_delay = sptr_bridge_configuration_BPDU->forward_delay;
	stp_class.this_bridge.topology_change = (enum BOOLEAN) sptr_bridge_configuration_BPDU->flags.topology_change;
}
/****************************************************************************/   /** 4.6.4 */ 
void configuration_BPDU_generation (void)
{
	USHORT port_number;

	stp_printf (STP_ALGORITHM_PRINTF,"STP: configuration generation \n\r");

	for (port_number = 0x0001; port_number <= stp_class.number_of_spanning_tree_ports ; ++port_number)
		{
		if (designated_port (port_number) == TRUE && stp_class.port[port_number].state != DISABLED)
			{
			transmit_configuration (port_number);
			}
		}
}
/****************************************************************************/
enum BOOLEAN designated_port (USHORT port_number)
{
	if (compare_identifiers (&stp_class.this_bridge.bridge_id,
		&stp_class.port[port_number].designated_bridge_id) == EQUAL_TO)
		{
		if (stp_class.port[port_number].designated_port_id.number ==
			stp_class.port[port_number].port_id.number)
			{
			if (stp_class.port[port_number].state != DISABLED)
				{
				return (TRUE);
				}
			}
		}

	return (FALSE);
}
/****************************************************************************/
static void reply (USHORT port_number)
{
	stp_printf (STP_ALGORITHM_PRINTF,"STP: reply %02x\n\r",port_number);

	transmit_configuration (port_number);
}
/****************************************************************************/
void transmit_topology_change_notification (void)
{
	stp_printf (STP_ALGORITHM_PRINTF,"STP: transmit topology change notification  \n\r");

 	send_mac_bridge_PDU (stp_class.this_bridge.root_port_id.number,
		(BRIDGE_CONFIGURATION_BPDU *) &stp_class.bridge_topology_change_notification[stp_class.this_bridge.root_port_id.number],
			sizeof (BRIDGE_TOPOLOGY_CHANGE_NOTIFICATION));
}
/****************************************************************************/
void configuration_update (void)
{
	stp_printf (STP_ALGORITHM_PRINTF,"STP: configuration update  \n\r");

	root_selection ();

	designated_port_selection ();
}
/****************************************************************************/
static void root_selection (void)
{
	USHORT port_number;
	BYTE root_port;

	root_port = NO_PORT;

	for (port_number = 0x0001; port_number <= stp_class.number_of_spanning_tree_ports ; ++port_number)
		{
		/* 4.6.8.3.1 */
		if ((designated_port (port_number) == FALSE) && 
			stp_class.port[port_number].state != DISABLED &&
			(compare_identifiers (&stp_class.port[port_number].designated_root_id,
			&stp_class.this_bridge.bridge_id) == LESS_THAN)) /* select a new root! */
			{
			/* 4.6.8.3.1 (1) */
			if (root_port == NO_PORT ||
				compare_identifiers (&stp_class.port[port_number].designated_root_id,
					&stp_class.port[root_port].designated_root_id) == LESS_THAN)
				{
				root_port = (BYTE) port_number;
				}
			/* 4.6.8.3.1 (2) */
			else if (compare_identifiers (&stp_class.port[port_number].designated_root_id,
				&stp_class.port[root_port].designated_root_id) == EQUAL_TO &&
				stp_class.port[port_number].path_cost +
				stp_class.port[port_number].designated_root_path_cost <
				stp_class.port[root_port].path_cost +
				stp_class.port[root_port].designated_root_path_cost)
				{
				root_port = (BYTE) port_number;
				}
			/* 4.6.8.3.1 (3) */
			else if (compare_identifiers (&stp_class.port[port_number].designated_root_id,
				&stp_class.port[root_port].designated_root_id) == EQUAL_TO &&
				stp_class.port[port_number].path_cost +
				stp_class.port[port_number].designated_root_path_cost ==
				stp_class.port[root_port].path_cost +
				stp_class.port[root_port].designated_root_path_cost &&
				compare_identifiers (&stp_class.port[port_number].designated_bridge_id,
				&stp_class.port[root_port].designated_bridge_id) == LESS_THAN)
				{
				root_port = (BYTE) port_number;
				}
			/* 4.6.8.3.1 (4) */
			else if (compare_identifiers (&stp_class.port[port_number].designated_root_id,
				&stp_class.port[root_port].designated_root_id) == EQUAL_TO &&
				stp_class.port[port_number].path_cost +
				stp_class.port[port_number].designated_root_path_cost ==
				stp_class.port[root_port].path_cost +
				stp_class.port[root_port].designated_root_path_cost &&
				compare_identifiers (&stp_class.port[port_number].designated_bridge_id,
				&stp_class.port[root_port].designated_bridge_id) == EQUAL_TO &&
				compare_port_identifiers (&stp_class.port[port_number].designated_port_id,
				&stp_class.port[root_port].designated_port_id) == LESS_THAN)
					{
					root_port = (BYTE) port_number;
					}
			/* 4.6.8.3.1 (5) */
			else if (compare_identifiers (&stp_class.port[port_number].designated_root_id,
				&stp_class.port[root_port].designated_root_id) == EQUAL_TO &&
				stp_class.port[port_number].path_cost +
				stp_class.port[port_number].designated_root_path_cost ==
				stp_class.port[root_port].path_cost +
				stp_class.port[root_port].designated_root_path_cost &&
				compare_identifiers (&stp_class.port[port_number].designated_bridge_id,
				&stp_class.port[root_port].designated_bridge_id) == EQUAL_TO &&
				compare_port_identifiers (&stp_class.port[port_number].designated_port_id,
				&stp_class.port[root_port].designated_port_id) == EQUAL_TO &&
				compare_port_identifiers (&stp_class.port[port_number].port_id,
				&stp_class.port[root_port].port_id) == LESS_THAN)
				{
				root_port = (BYTE) port_number;
				}
			}

		stp_class.this_bridge.root_port_id.number = root_port;

		if (root_port == NO_PORT) /* I am the root */
			{
			if (compare_identifiers (&stp_class.this_bridge.root_id,&stp_class.this_bridge.bridge_id) != EQUAL_TO)
				{
				if (stp_class.fptr_new_root != NULL)
					{
					(*stp_class.fptr_new_root) ();
					}
				}

			stp_class.this_bridge.root_id = stp_class.this_bridge.bridge_id;
			stp_class.this_bridge.root_path_cost = 0x00000000L;

			/* in record_hello_timeout_values we may overwritten these so reset them to bridge management initial values */

			stp_class.this_bridge.max_age = stp_class.this_bridge.bridge_max_age; 
			stp_class.this_bridge.hello_time = stp_class.this_bridge.bridge_hello_time; 
			stp_class.this_bridge.forward_delay = stp_class.this_bridge.bridge_forward_delay; 
			}
		else /* somebody else is the root */
			{
			if (compare_identifiers (&stp_class.this_bridge.root_id,
				&stp_class.port[root_port].designated_root_id) != EQUAL_TO)
				{
				if (stp_class.fptr_new_root != NULL)
					{
					(*stp_class.fptr_new_root) ();
					}
				}

			stp_class.this_bridge.root_id = stp_class.port[root_port].designated_root_id;
			stp_class.this_bridge.root_path_cost = (USHORT) (stp_class.port[root_port].designated_root_path_cost +
				stp_class.port[root_port].path_cost);
			}
		}
}
/****************************************************************************/
static void designated_port_selection (void)
{
	USHORT port_number;

	for (port_number = 0x0001; port_number <= stp_class.number_of_spanning_tree_ports ; ++port_number)
		{
		/* remember that the designated port can contain anybodys bridge address for the designated bridge including my own */

		if (stp_class.port[port_number].state != DISABLED)
			{
			if (designated_port (port_number) == TRUE || /* 4.6.9.3.1 */
				(compare_identifiers (&stp_class.port[port_number].designated_root_id,
				&stp_class.this_bridge.root_id) != EQUAL_TO) || /* 4.6.9.3.2 */
				(stp_class.this_bridge.root_path_cost < stp_class.port[port_number].designated_root_path_cost)) /* 4.6.9.3.3 */
				{
				become_designated_port (port_number);
				}
			else if (stp_class.this_bridge.root_path_cost ==
				stp_class.port[port_number].designated_root_path_cost &&	/* 4.6.9.3.4 */
				compare_identifiers (&stp_class.this_bridge.bridge_id,
				&stp_class.port[port_number].designated_bridge_id) == LESS_THAN)
				{
				become_designated_port (port_number);
				}
			else if (stp_class.this_bridge.root_path_cost ==
				stp_class.port[port_number].designated_root_path_cost && /* 4.6.9.3.5 */
				compare_identifiers (&stp_class.this_bridge.bridge_id,
				&stp_class.port[port_number].designated_bridge_id) == EQUAL_TO &&
				compare_port_identifiers (&stp_class.port[port_number].port_id,
				&stp_class.port[port_number].designated_port_id) != GREATER_THAN)
				{
				become_designated_port (port_number);
				}
			}
		}
}
/****************************************************************************/
void become_designated_port (USHORT port_number)
{
	stp_printf (STP_ALGORITHM_PRINTF,"STP: become designated port %02x\n\r",port_number);

	stp_class.port[port_number].designated_root_id = stp_class.this_bridge.root_id;
	stp_class.port[port_number].designated_root_path_cost = stp_class.this_bridge.root_path_cost;
	stp_class.port[port_number].designated_bridge_id = stp_class.this_bridge.bridge_id;
	stp_class.port[port_number].designated_port_id = stp_class.port[port_number].port_id;
}
/****************************************************************************/  /** 4.6.11 */ 
void port_state_selection (void)
{
	BYTE	port_number;

	for (port_number = 0x0001; port_number <= stp_class.number_of_spanning_tree_ports ; port_number += (BYTE) 1)
		{
		if (port_number == stp_class.this_bridge.root_port_id.number)
			{
			stp_class.port[port_number].configuration_pending = FALSE;
			stp_class.port[port_number].topology_change_acknowledgement = FALSE;

			stp_printf (STP_ALGORITHM_PRINTF,"STP: root port %02x\n\r",port_number);

			make_forwarding (port_number);
			}
		else if (designated_port (port_number) == TRUE)
			{
			stp_printf (STP_ALGORITHM_PRINTF,"STP: designated port %02x\n\r",port_number);

			set_timer (&stp_class.port[port_number].message_age,STOP_TIMER);

			make_forwarding (port_number);
			}

⌨️ 快捷键说明

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