📄 macbrspn.c
字号:
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 + -