📄 stp_api.c
字号:
(bpdu.max_age > STP_MAX_MAX_AGE)) {
bpdu.max_age = STP_DEF_MAX_AGE;
}
if ((bpdu.hello_time < STP_MIN_HELLO_TIME) ||
(bpdu.hello_time > STP_MAX_HELLO_TIME)) {
bpdu.hello_time = STP_DEF_HELLO_TIME;
}
if ((bpdu.forward_delay < STP_MIN_FWD_DELAY) ||
(bpdu.forward_delay > STP_MAX_FWD_DELAY)) {
bpdu.forward_delay = STP_DEF_FWD_DELAY;
}
trace(TRACE_STP, TR_VERBOSE, "Config BPDU received on Port %d\n", stport->lport);
trace(TRACE_STP, TR_VERBOSE,
"Type %x RootId:%08x%08x PathCost:%d BridgeId:%08x%08x\n",
bpdu.type, soc_ntohl_load(bpdu.root_id),
soc_ntohl_load(bpdu.root_id + 4),
bpdu.root_path_cost, soc_ntohl_load(bpdu.bridge_id),
soc_ntohl_load(bpdu.bridge_id + 4));
trace(TRACE_STP, TR_VERBOSE,
"PortId %04x MsgAge %d MaxAge %d HelloTime %d, FwdDelay %d",
bpdu.port_id, bpdu.message_age, bpdu.max_age, bpdu.hello_time,
bpdu.forward_delay);
trace(TRACE_STP, TR_VERBOSE, " ACK %d top %d\n",
bpdu.tc_acknowledgment, bpdu.topology_change);
stport->bpdu_in++;
/*
* now call config BPDU receive (stp.c)
*/
received_config_bpdu(stp, stport, &bpdu);
}
/*
* Function:
* stp_rcv_tcn
* Purpose:
* Handles incoming TCN BPDU packets
* Parameters:
* bpdu_msg - the TCN message received
* port - the port on which this is received
* Returns:
* none
*/
void
stp_rcv_tcn(spantree_t *stp, bpdu_config_t *bpdu_msg, stp_port_t *stport)
{
Tcn_bpdu stp_tcn_bpdu;
stp_tcn_bpdu.type = bpdu_msg->msg_type;
stport->bpdu_in++;
/* now call topology change BPDU receive(from stp.c) */
received_tcn_bpdu(stp, stport, &stp_tcn_bpdu);
}
/*
* Function:
* stp_handle_bpdu_packet
* Purpose:
* Handles STP BPDU packets
* Parameters:
* bpdu_msg - BPDU
* port - port where packets comes in
* Returns:
* none
*/
void
stp_handle_bpdu_packet(stp_id_t tree_id, uint8 *bpdu_buf, int lport)
{
spantree_t *stp;
stp_port_t *stport;
bpdu_config_t *bpdu_msg;
uint16 protocol_id;
uint8 version;
uint16 vlan_id;
/* zhouguis added this 2005-12-15 for trunk */
bpdu_msg = (bpdu_config_t *)bpdu_buf;
vlan_id = soc_ntohs_load((uint16 *)&bpdu_msg->bridge_id);
vlan_id = vlan_id & 0x0fff;
debugk(DK_STP,"packet send to vlan_id = %d\n",vlan_id);
protocol_id = soc_ntohs_load(bpdu_msg->identifier);
version = bpdu_msg->version;
if (version == 0) {
stp = stp_lookup_from_stp_id(vlan_id);
if (stp == NULL) {
return;
}
stport = stp_port_lookup_from_id(stp, lport);
if (stport == NULL) {
return;
}
/* check protocol ID and version */
protocol_id = soc_ntohs_load(bpdu_msg->identifier);
version = bpdu_msg->version;
if (protocol_id != 0) {
trace(TRACE_STP, TR_ERROR,
"invalid BPDU protocol id %d\n", protocol_id);
return;
}
if (bpdu_msg->msg_type == BPDU_TYPE_CONFIG) {
/* check flags */
if ((bpdu_msg->flags & ~0x81) != 0) {
trace(TRACE_STP, TR_ERROR, "Invalid flags 0x%x\n", bpdu_msg->flags);
return;
}
stp_rcv_bpdu_config(stp, bpdu_msg, stport);
} else if (bpdu_msg->msg_type == BPDU_TYPE_TCN) {
stp_rcv_tcn(stp, bpdu_msg, stport);
} else {
trace(TRACE_STP, TR_ERROR,
"invalid bpdu type %d\n", bpdu_msg->msg_type);
return;
}
}
}
/*
* Function:
* stp_port_enable
* Purpose:
* Enable port for example by CLI
* Parameters:
* lport - identify the port to be disabled
* Returns:
* none
*/
int
stp_port_enable(spantree_t *stp, int lport)
{
stp_port_t *stport;
if (!stp_is_running(stp)) {
trace(TRACE_STP, TR_ERROR, "STP not enabled\n");
return (-1);
}
stport = stp_port_lookup_from_id(stp, lport);
if (stport == NULL) {
return -1;
}
/* This is a hard enable */
trace(TRACE_STP, TR_VERBOSE, "STP: Enabling port %d\n", lport);
if (stport->link_flags & STP_LF_LINKDISABLED) {
stport->link_flags &= ~STP_LF_LINKDISABLED;
enable_port(stp, stport);
}
return (0);
}
/*
* Function:
* stp_port_disable
* Purpose:
* Disable port for example by CLI
* Parameters:
* lport - identify the port to be disabled
* Returns:
* none
*/
int
stp_port_disable(spantree_t *stp, int lport)
{
stp_port_t *stport;
if (!stp_is_running(stp)) {
trace(TRACE_STP, TR_ERROR, "STP not enabled\n");
return (-1);
}
stport = stp_port_lookup_from_id(stp, lport);
if (stport == NULL) {
return -1;
}
/* This is a hard disable */
trace(TRACE_STP, TR_VERBOSE, "STP: Disabling port %d\n", lport);
if (!(stport->link_flags & STP_LF_LINKDISABLED)) {
stport->link_flags |= STP_LF_LINKDISABLED;
if (stport->state != STP_DISABLED) {
disable_port(stp, stport);
}
}
return (0);
}
/*
* Mark this port as stack link
*/
void
stp_mark_stack_port(spantree_t *stp, int lport)
{
stp_port_t *stport;
stp_create_stp_port(&stport, stp, lport, "stack port");
/* stack ports does not participate in STP calculation */
stport->link_flags |= STP_LF_STACK;
stport->link_flags |= STP_LF_LINKDISABLED;
stport->state = STP_DISABLED;
}
/*
* Function:
* stp_link_up
* Purpose:
* Called when port state changes to UP
* Parameters:
* lport - identify the port(logical number)
* Returns:
* none
*/
int
stp_link_up(spantree_t *stp, stp_port_t *stport, int speed)
{
/* 为了聚合端口添加 */
int lport;
if (speed == 1000) {
stport->path_cost = STP_PATH_COST_1GB;
} else if (speed == 100) {
stport->path_cost = STP_PATH_COST_100MB;
} else {
stport->path_cost = STP_PATH_COST_10MB;
}
if (!(stport->link_flags & STP_LF_LINKDISABLED)) {
enable_port(stp, stport);
}
/* 为了聚合端口添加 */
lport = stp_port_p2l(stp_my_cpuid, stport->unit, stport->port);
if (stp_trunk_running()) {
stp_trunk_link_up(stp, lport);
}
return (0);
}
/*
* Function:
* stp_link_down
* Purpose:
* Called when port state changes to DOWN
* Parameters:
* lport - identify the port(logical number)
* Returns:
* none
*/
int
stp_link_down(spantree_t *stp, int lport)
{
stp_port_t *stport;
/* Trunk member going down */
if (stp_trunk_running()) {
stp_trunk_link_down(stp, lport);
}
stport = stp_port_lookup_from_id(stp, lport);
if (stport != NULL) {
stp_delete_stp_port(stport);
}
return (0);
}
/*
* Function:
* stp_port_state_string
* Purpose:
* Returns the port states string
* Parameters:
* state - port state
* Returns:
* none
*/
static char *
stp_port_state_string(int state)
{
switch (state) {
case STP_DISABLED:
return ("Disabled");
case STP_LISTENING:
return ("Listening");
case STP_LEARNING:
return ("Learning");
case STP_FORWARDING:
return ("Forwarding");
case STP_BLOCKING:
return ("Blocking");
default:
return ("Unkown");
}
}
/*
* Function:
* stp_port_state_set
* Purpose:
* Set the port state to chip
* Parameters:
* lport - logical port number
* state - new state
* Returns:
* none
*/
void
stp_port_state_set(spantree_t *stp, stp_port_t *stport, stp_portstate_t state)
{
int clear_arl = 0;
int stg;
pbmp_t pbm;
/* debugk(DK_STP,
"Tree %d, lport %d(%d %d %d) -> %s\n",
stp->external_id, stport->lport,
stp_port_l2cpu(stport->lport), stp_port_l2unit(stport->lport),
stp_port_l2p(stport->lport), stp_port_state_string(state));
*/
/* Only set hardware for local ports */
if (!(stport->link_flags & STP_LF_LOCAL)) {
return;
}
switch (state) {
case STP_DISABLED:
state = BCM_STG_STP_DISABLE;
clear_arl = 1;
break;
case STP_LISTENING:
state = BCM_STG_STP_LISTEN;
break;
case STP_LEARNING:
state = BCM_STG_STP_LEARN;
break;
case STP_FORWARDING:
state = BCM_STG_STP_FORWARD;
clear_arl = 1;
break;
case STP_BLOCKING:
state = BCM_STG_STP_BLOCK;
clear_arl = 1;
break;
default:
trace(TRACE_STP, TR_VERBOSE, "Bad STP port state %d\n", state);
}
/* bcm_port_stp_set(stport->unit, stport->port, state);*/
/* zhouguis changed this 2005-12-15 */
stg = search_stg_through_vlan(stp->external_id);
bcm_stg_stp_set(stport->unit, stg, stport->port, state);
#if 0
bcm_stg_stp_set(stport->unit, stp->external_id, stport->port, state);
#endif
/*
* What about all addresses on the port ?
*/
if (clear_arl == 1) {
SOC_PBMP_CLEAR(pbm);
SOC_PBMP_PORT_ADD(pbm, stport->port);
bcm_l2_addr_remove_by_port(stport->unit, pbm, 0);
}
/* 同步聚合端口ROOT和MEMBER之间的状态 zhouguis added 2005-12-14 */
if (stp_trunk_running()) {
stp_trunk_state_update(stp, stport, state);
}
}
/*
* Function:
* stp_port_bpdu_enable
* Purpose:
* Enable/Disable BPDUs on the specified port
* Parameters:
* lport - logical port number
* enable - True to enable, False to disable (reject bpdu).
* Returns:
* none
*/
void
stp_port_bpdu_enable(spantree_t *stp, int lport, int enable)
{
stp_port_t *stport;
stport = stp_port_lookup_from_id(stp, lport);
if (stport == NULL) {
return;
}
if (!(stport->link_flags & STP_LF_LOCAL)) {
return;
}
bcm_port_bpdu_enable_set(stport->unit, stport->port, enable);
}
/*
* Function:
* stp_port_is_disabled
* Purpose:
* return 1 if disabled 0 otherwise
* Parameters:
* none
* Returns:
* none
*/
int
stp_port_is_disabled(spantree_t *stp, stp_port_t *stport)
{
return (stport->link_flags & STP_LF_LINKDISABLED);
}
/*
* returns string for port type
*/
STATIC char *
stp_port_type_string(int type)
{
switch (type) {
case STP_PORT_TYPE_GE:
return ("GigEthernet");
case STP_PORT_TYPE_FE:
return ("FastEthernet");
default:
return ("Ethernet");
}
}
/*
* Return speed for port
*/
STATIC char *
stp_port_speed_string(int cost)
{
switch (cost) {
case STP_PATH_COST_1GB:
return ("1000 mbps");
case STP_PATH_COST_100MB:
return ("100 mbps");
default:
return ("10 mbps");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -