📄 transmit.c
字号:
register struct net_bridge_port *port = NULL;
register int port_index, vlan_id;
unsigned char role;
#ifdef STP_DBG
if (this->owner.port->skip_tx > 0)
{
if (1 == this->owner.port->skip_tx)
stp_trace ("port %s stop tx skipping", this->owner.port->port_name);
else
stp_trace ("port %s skip tx %d", this->owner.port->port_name,
this->owner.port->skip_tx);
this->owner.port->skip_tx--;
return STP_Nothing_To_Do;
}
#endif
port = this->owner.port;
if (port->admin_non_stp)
{
return 1;
}
port_index = port->port_no;
/* vlan_id = port->owner->vlan_id;*/
pkt_len =
build_bpdu_header (port, BPDU_RSTP,
sizeof (BPDU_HEADER_T) + sizeof (BPDU_BODY_T) /*+2*/);
build_config_bpdu (port, False);
switch (port->selectedRole)
{
default:
case DisabledPort:
role = RSTP_PORT_ROLE_UNKN;
break;
case AlternatePort:
role = RSTP_PORT_ROLE_ALTBACK;
break;
case BackupPort:
role = RSTP_PORT_ROLE_ALTBACK;
break;
case RootPort:
role = RSTP_PORT_ROLE_ROOT;
break;
case DesignatedPort:
role = RSTP_PORT_ROLE_DESGN;
break;
}
bpdu_packet.body.flags |= (role << PORT_ROLE_OFFS);
if (port->synced)
{
#if 0 /* def STP_DBG */
if (port->roletrns->debug)
stp_trace ("tx AGREEMENT_BIT to port %s", port->port_name);
#endif
bpdu_packet.body.flags |= AGREEMENT_BIT;
}
if (port->proposing)
{
#if 0 /* def STP_DBG */
if (port->roletrns->debug)
stp_trace ("tx PROPOSAL_BIT to port %s", port->port_name);
#endif
bpdu_packet.body.flags |= PROPOSAL_BIT;
}
#ifdef STP_DBG
if (this->debug)
stp_trace ("port %s txRstp flags=0X%lx", port->port_name,
(unsigned long) bpdu_packet.body.flags);
#endif
return STP_OUT_tx_bpdu (port_index, (unsigned char *) &bpdu_packet,
pkt_len);
}
/*
* Port Transmint 状态机负责在newInfo表明有新的信息存在时,
用sendRSTP变量所标识的格式发送BPDU。该状态机强制了发送
BPDU的一个发送率。txCount每发送一个就增加一次。当txCout增
加到txHoldCount时,就停止发送了。txCount每秒钟被Port Timers 状态
机确定。从而每秒定一个"信用",上限为TxHoldCount.
这个状态机利用了sendRSTP变量(由Port Protocol Migration 状态机管理)
确定是RST BPDU, Config BPDU,或者TCN BPDU 将被发送,实际发送的信息
将因为sendRSTP的不同而不同.
*/
/************************************************************************************
函数名称:
输入参数:
输出参数:
功能描述: Port Transmit 状态机的状态操作函数
返回值 :
备注 :
作者 :
日期 :
************************************************************************************/
void STP_transmit_enter_state (STATE_MACH_T * this)
{
register struct net_bridge_port *port = this->owner.port;
switch (this->State)
{
case BEGIN:
case TRANSMIT_INIT:
#ifdef _TRANS_DEBUG_
printf("TRANSMINT INIT\r\n");
#endif
port->newInfo = False;
port->helloWhen = 0;
port->txCount = 0;
break;
case TRANSMIT_PERIODIC:
#ifdef _TRANS_DEBUG_
printf("TRANSMINT PERIODIC\r\n");
#endif
/*port->newInfo则值在此改变。只要下面条件之一为1,
则newInfo为真
*/
port->newInfo = port->newInfo || ((port->role == DesignatedPort) ||
((port->role == RootPort) && port->tcWhile));
port->helloWhen = port->br->rootTimes.HelloTime;
break;
case IDLE:
#ifdef _TRANS_DEBUG_
printf("IDLE\r\n");
#endif
break;
case TRANSMIT_CONFIG:
#ifdef _TRANS_DEBUG_
printf("TRANSMINT CONFIG\r\n");
#endif
port->newInfo = False;
txConfig (this);
port->txCount++;
port->tcAck = False;
break;
case TRANSMIT_TCN:
#ifdef _TRANS_DEBUG_
printf("TRANSMINT TCN\r\n");
#endif
port->newInfo = False;
txTcn (this);
port->txCount++;
break;
case TRANSMIT_RSTP:
#ifdef _TRANS_DEBUG_
printf("TRANSMINT RSTP,%d\r\n",port->port_no);
#endif
port->newInfo = False;
txRstp (this);
port->txCount++;
port->tcAck = False;
break;
}
}
/************************************************************************************
函数名称: STP_transmit_check_conditions
输入参数:
输出参数:
功能描述: Port Transmit 状态机的状态转移函数
返回值 :
备注 :
作者 :
日期 :
************************************************************************************/
Bool STP_transmit_check_conditions (STATE_MACH_T * this)
{
register struct net_bridge_port*port = this->owner.port;
#ifdef _TRANS_DEBUG_
printf("\r\nTransmit Check Condition\r\n");
#endif
if (BEGIN == this->State)
return STP_hop_2_state (this, TRANSMIT_INIT);
switch (this->State)
{
case TRANSMIT_INIT:
port->helloWhen = 0;
port->txCount = 0;
port->newInfo = False;
#ifdef _TRANS_DEBUG_
printf("INIT TO IDLE\r\n");
#endif
return STP_hop_2_state (this, IDLE);
case TRANSMIT_PERIODIC:
#ifdef _TRANS_DEBUG_
printf("PERIODIC TO IDLE\r\n");
#endif
return STP_hop_2_state (this, IDLE);
case IDLE:
if (!port->helloWhen)
{
/*17.27
a) 当helloWhen定时器超期时,转到TRANSMIT_PERIODIC*/
#ifdef _TRANS_DEBUG_
printf("IDLE TO PERIODIC\r\n");
#endif
return STP_hop_2_state (this, TRANSMIT_PERIODIC);
}
if (!port->sendRSTP && port->newInfo &&
(port->txCount < TxHoldCount) && (port->role == DesignatedPort)
&& port->helloWhen)
{
/*17.27
d)
满足以下条件,则转到TRANSMIT_CONFIG状态发送
config BPDU
1) 端口RSTP为假
2) 端口newInfo为真
3) 端口txCount 未到达发BPDU包的最大速率TxHoldCount
4) 端口的角色是指定端口
5) helloWhen非0*/
#ifdef _TRANS_DEBUG_
printf("IDLE TO TRANSMIT_CONFIG\r\n");
#endif
return STP_hop_2_state (this, TRANSMIT_CONFIG);
}
if (!port->sendRSTP && port->newInfo &&
(port->txCount < TxHoldCount) && (port->role == RootPort) &&
port->helloWhen)
{
/*17.27
c)
满足以下条件,则转到TRANSMIT_TCN状态发送
TCN BPDU
1) 端口的RSTP为假
2) 端口newInfo为真
3) 端口txCount比TxHoldCount小
4) 端口的角色是根端口
5) helloWhen非0*/
#ifdef _TRANS_DEBUG_
printf("IDLE TO TRANSMIT_TCN\r\n");
#endif
return STP_hop_2_state (this, TRANSMIT_TCN);
}
if (port->sendRSTP && port->newInfo && (port->txCount < TxHoldCount)
&& ((port->role == RootPort) || (port->role == DesignatedPort))
&& port->helloWhen /*added by wl 03-18 与协议相符和*/
)
{
/*17.27
b)
满足以下条件,转到TRANSIMIT_RSTP
1) sendRSTP为真,表示发送格式为RSTP
2) newInfo为真,表示有一个BPDU包要发送
3) txCount小于TxHoldCount,未到每秒钟发BPDU包的上限
4) helloWhen不为0
5)端口角色是根端口或者指定端口
*/
#ifdef _TRANS_DEBUG_
printf("IDLE TO TRANSMIT_RSTP\r\n");
#endif
return STP_hop_2_state (this, TRANSMIT_RSTP);
}
break;
case TRANSMIT_CONFIG:
{
/*发送完数据后恢复到IDLE状态*/
#ifdef _TRANS_DEBUG_
printf("TRANSMIT_CONFIG TO IDLE\r\n");
#endif
return STP_hop_2_state (this, IDLE);
}
case TRANSMIT_TCN:
{
/*发送完数据后恢复到IDLE状态*/
#ifdef _TRANS_DEBUG_
printf("TRANSMIT_TCN TO IDLE\r\n");
#endif
return STP_hop_2_state (this, IDLE);
}
case TRANSMIT_RSTP:
{
/*发送完数据后恢复到IDLE状态*/
#ifdef _TRANS_DEBUG_
printf("TRANSMIT_RSTP TO IDLE\r\n");
#endif
return STP_hop_2_state (this, IDLE);
}
};
return False;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -