接上文:https://blog.csdn.net/zhang1806618/article/details/107268598
1.3 网络层(续)
1.3.4 底板(队列)处理
在RoutePacketAndSendToMac函数对单播、广播、组播进行了分别处理。上文分析以单播为例,通过获取单播路由,然后调用NetworkIpSendPacketToMacLayer函数,再调用NetworkIpSendPacketOnInterface函数发送数据包。而广播、组播是直接调用NetworkIpSendPacketOnInterface函数发送数据包,跳过了路由阶段。上文已介绍了NetworkIpSendPacketOnInterface,主要调用NetworkIpSendOnBackplane函数发送数据。
NetworkIpSendOnBackplane函数主要代码如下,作用:一、判断队列是否无限制;二、队列有限时判断队列是否已满。已本地发送为例,无限制则直接调用QueueUpIpFragmentForMacLayer函数发送数据,有限制且队列未满时调用NetworkIpUseBackplaneIfPossible函数尝试发送数据。
void //inline//
NetworkIpSendOnBackplane(
Node *node,
Message *msg,
int incomingInterface,
int outgoingInterface,
NodeAddress hopAddr)
{
NetworkDataIp *ip = (NetworkDataIp *) node->networkData.networkVar;
NetworkDataIcmp *icmp = (NetworkDataIcmp*) ip->icmpStruct;
IpHeaderType *ipHeader = (IpHeaderType *) MESSAGE_ReturnPacket(msg);
//判断吞吐量是否无限制
//1.无限制情况
if (ip->backplaneThroughputCapacity ==
NETWORK_IP_UNLIMITED_BACKPLANE_THROUGHPUT)
{
//本地接收,将MAC层数据包上传至网络层、传输层
if (outgoingInterface == CPU_INTERFACE)
{
DeliverPacket(node, msg, incomingInterface, hopAddr);
}
//为MAC层处理数据包
else
{
QueueUpIpFragmentForMacLayer(node,
msg,
outgoingInterface,
hopAddr,
incomingInterface);
}
}
//2.有限制情况
else
{
BOOL queueIsFull = FALSE;
//本地发送情况
if (incomingInterface == CPU_INTERFACE ||
ip->backplaneType == BACKPLANE_TYPE_CENTRAL)
{
//插入队列
NetworkIpCpuQueueInsert(node,
msg,
hopAddr,
ipHeader->ip_dst,
outgoingInterface,
NETWORK_PROTOCOL_IP,
&queueIsFull,
incomingInterface);
}
//本地接收或转发情况
else
{
//插入队列
NetworkIpInputQueueInsert(node,
incomingInterface,
msg,
hopAddr,
ipHeader->ip_dst,
outgoingInterface,
NETWORK_PROTOCOL_IP,
&queueIsFull);
}
//队列已满,丢弃并发送ICMP消息
if (queueIsFull)
{
if (ip->isIcmpEnable && icmp->sourceQuenchEnable)
{
BOOL ICMPErrorMsgCreated = NetworkIcmpCreateErrorMessage(node,
msg,
ipHeader->ip_src,
incomingInterface,
ICMP_SOURCE_QUENCH,