📄 macbrspn.c
字号:
else
{
stp_printf (STP_ALGORITHM_PRINTF,"STP: blocking port %02x\n\r",port_number);
stp_class.port[port_number].configuration_pending = FALSE;
stp_class.port[port_number].topology_change_acknowledgement = FALSE;
make_blocking (port_number);
}
}
}
/****************************************************************************/
static void make_forwarding (USHORT port_number)
{
if (stp_class.port[port_number].state == BLOCKING)
{
stp_class.port[port_number].state = LISTENING;
stp_printf (STP_ALGORITHM_PRINTF,"STP: listening started %02x\n\r",port_number);
set_timer (&stp_class.port[port_number].forward_delay,START_TIMER);
}
}
/****************************************************************************/
static void make_blocking (USHORT port_number)
{
if (stp_class.port[port_number].state != DISABLED &&
stp_class.port[port_number].state != BLOCKING)
{
if (stp_class.port[port_number].state == FORWARDING || stp_class.port[port_number].state == LEARNING)
{
topology_change_detection ();
}
stp_printf (STP_ALGORITHM_PRINTF,"STP: blocking started %02x\n\r",port_number);
stp_class.port[port_number].state = BLOCKING;
set_timer (&stp_class.port[port_number].forward_delay,STOP_TIMER);
}
}
/****************************************************************************/
void topology_change_detection (void)
{
stp_printf (STP_ALGORITHM_PRINTF,"STP: topology change detection\n\r");
if (stp_class.fptr_topology_change_detection != NULL)
{
(*stp_class.fptr_topology_change_detection) ();
}
stp_class.this_bridge.aging_time_for_fd = FORWARD_DELAY_TIME / TIMER_GRANULARITY;
if (root_bridge () == TRUE)
{
stp_class.this_bridge.topology_change = TRUE;
set_timer (&stp_class.topology_change_timer,START_TIMER);
}
else if (stp_class.this_bridge.topology_change_detected == FALSE)
{
transmit_topology_change_notification ();
set_timer (&stp_class.topology_change_notification_timer,START_TIMER);
}
stp_class.this_bridge.topology_change_detected = TRUE;
/* below are for snmp */
++stp_class.this_bridge.number_of_topology_changes;
stp_class.this_bridge.timer_topology_tick = timer_ulong;
}
/****************************************************************************/
static void topology_change_acknowledgement (void)
{
stp_printf (STP_ALGORITHM_PRINTF,"STP: topology change acknowledgement \n\r");
stp_class.this_bridge.topology_change_detected = FALSE;
stp_class.this_bridge.topology_change = FALSE;
set_timer (&stp_class.topology_change_notification_timer,STOP_TIMER);
}
/****************************************************************************/
static void acknowledge_topology_change (USHORT port_number)
{
stp_printf (STP_ALGORITHM_PRINTF,"STP: acknowledgement topology change %02x\n\r",port_number);
stp_class.port[port_number].topology_change_acknowledgement = TRUE;
transmit_configuration (port_number);
}
/****************************************************************************/
void bridge_protocol_message_received (USHORT port_number,BRIDGE_CONFIGURATION_BPDU *sptr_bridge_configuration_BPDU)
{
enum BOOLEAN previous_bridge_state;
/* BPDUs with invalid values for protocol ID, version ID, type, and flags are ignored.
ANSI/IEEE Std. 802.1d, section 5.3.1 */
if (check_for_invalid_bpdu_parameters (sptr_bridge_configuration_BPDU) == TRUE)
{
return;
}
previous_bridge_state = root_bridge ();
if (sptr_bridge_configuration_BPDU->type == CONFIGURATION)
{
if (stp_class.port[port_number].state != DISABLED)
{
stp_printf (STP_ALGORITHM_PRINTF,"STP: Hello message received %02x\n\r",port_number);
if (supercedes_port_info (port_number,sptr_bridge_configuration_BPDU) == TRUE)
{
record_configuration_port_information (port_number,sptr_bridge_configuration_BPDU);
configuration_update ();
port_state_selection ();
if ((root_bridge () == FALSE) && previous_bridge_state)
{
set_timer (&stp_class.hello_timer,STOP_TIMER);
if (stp_class.this_bridge.topology_change_detected == TRUE)
{
set_timer (&stp_class.topology_change_timer,STOP_TIMER);
transmit_topology_change_notification ();
set_timer (&stp_class.topology_change_notification_timer,START_TIMER);
}
}
if (port_number == stp_class.this_bridge.root_port_id.number)
{
record_hello_timeout_values (sptr_bridge_configuration_BPDU);
configuration_BPDU_generation ();
if (sptr_bridge_configuration_BPDU->flags.topology_change_acknowledgement == TRUE)
topology_change_acknowledgement ();
}
}
else if (designated_port (port_number) == TRUE)
{
reply (port_number);
}
}
}
else if (sptr_bridge_configuration_BPDU->type == (enum BPDU_TYPE) TOPOLOGY_CHANGE)
{
stp_printf (STP_ALGORITHM_PRINTF,"STP: topology change received %02x\n\r",port_number);
if (stp_class.port[port_number].state != DISABLED)
{
if (designated_port (port_number) == TRUE)
{
topology_change_detection ();
acknowledge_topology_change (port_number);
}
}
}
}
/****************************************************************************/
static enum BOOLEAN supercedes_port_info (USHORT port_number,BRIDGE_CONFIGURATION_BPDU *sptr_bridge_configuration_BPDU)
{
enum SORT_RETURN sort_return_value;
/* all return (TRUE)s cause the configuration bpdu received to update the current root bridge information in
stp_class.port[port_number] */
/* check the designated root */
sort_return_value = compare_identifiers (&sptr_bridge_configuration_BPDU->root_id,
&stp_class.port[port_number].designated_root_id);
if (sort_return_value == LESS_THAN)
{
return (TRUE); /* root value is better in new config bpdu */
}
else if (sort_return_value == GREATER_THAN)
{
return (FALSE); /* root value is worse in new config bpdu */
}
if (sptr_bridge_configuration_BPDU->root_path_cost < stp_class.port[port_number].designated_root_path_cost)
{
return (TRUE); /* root path cost is better in new config bpdu */
}
else if (sptr_bridge_configuration_BPDU->root_path_cost > stp_class.port[port_number].designated_root_path_cost)
{
return (FALSE); /* root path cost is worse in new config bpdu */
}
/* check the designated bridge for the port */
sort_return_value = compare_identifiers (&sptr_bridge_configuration_BPDU->bridge_id,
&stp_class.port[port_number].designated_bridge_id);
if (sort_return_value == LESS_THAN)
{
return (TRUE); /* bridge value is better in new config bpdu */
}
else if (sort_return_value == GREATER_THAN)
{
return (FALSE); /* bridge value is worse in new config bpdu */
}
/* check to see if I am not the designated bridge for the port */
if (compare_identifiers (&sptr_bridge_configuration_BPDU->bridge_id,&stp_class.this_bridge.bridge_id) != EQUAL_TO)
{
return (TRUE); /* bridge (myself) receiving the BPDU is not the designated bridge for the port */
}
if (sptr_bridge_configuration_BPDU->port_id.number <= stp_class.port[port_number].designated_port_id.number)
{
return (TRUE); /* port id is the same or better in new config bpdu */
}
else
{
return (FALSE);
}
}
/****************************************************************************/
static enum BOOLEAN check_for_invalid_bpdu_parameters (BRIDGE_CONFIGURATION_BPDU *sptr_bridge_configuration_BPDU)
{
/*Check BPDU for invalid values in protocol ID, version ID, type, and flags.*/
USHORT protocol_ID_value;
BYTE version_or_type_or_flags_value;
BYTE invalid_version_or_type_or_flags_minimum_value;
BYTE invalid_version_or_type_or_flags_maximum_value;
protocol_ID_value = sptr_bridge_configuration_BPDU->protocol_ID;
if ((protocol_ID_value == swap (0x0001) ) || ( protocol_ID_value == 0xFFFF ) )
{
return (TRUE);
}
version_or_type_or_flags_value = sptr_bridge_configuration_BPDU->protocol_version_ID;
invalid_version_or_type_or_flags_minimum_value = 0x01;
invalid_version_or_type_or_flags_maximum_value = 0xFF;
if ((version_or_type_or_flags_value == invalid_version_or_type_or_flags_minimum_value) ||
(version_or_type_or_flags_value == invalid_version_or_type_or_flags_maximum_value) )
{
return (TRUE);
}
version_or_type_or_flags_value = sptr_bridge_configuration_BPDU->type;
if ((version_or_type_or_flags_value == invalid_version_or_type_or_flags_minimum_value) ||
(version_or_type_or_flags_value == invalid_version_or_type_or_flags_maximum_value) )
{
return (TRUE);
}
version_or_type_or_flags_value = sptr_bridge_configuration_BPDU->flags.not_used;
invalid_version_or_type_or_flags_maximum_value = 0x00;
if ((version_or_type_or_flags_value != invalid_version_or_type_or_flags_maximum_value))
{
return (TRUE);
}
return (FALSE);
}
/****************************************************************************/
static void set_stp_port_default_values (USHORT port_number)
{
if (stp_class.port[port_number].maximum_packet_size == 0x0000 )
{
stp_class.port[port_number].maximum_packet_size = DEFAULT_PORT_MAXIMUM_FRAME_SIZE;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -