📄 zl5011xpacketrx.c
字号:
break;
default:
l2tpHeaderPos = 0;
cookieOffset = 0;
break;
}
/* if using non-IP protocol, then set the IPv4 flag to true to force using templates
from just one part of the table */
switch (par->protocolType)
{
case ZL5011X_CD :
case ZL5011X_PW :
case ZL5011X_MPLS :
case ZL5011X_MPLS_PW :
case ZL5011X_MPLS_MPLS_PW :
case ZL5011X_MPLS_PW_RTP :
case ZL5011X_MPLS_RTCP_CTRL :
case ZL5011X_ETHERNET :
case ZL5011X_CUSTOM8_PW :
case ZL5011X_CUSTOM8_RTP_PW :
case ZL5011X_CUSTOM8_PW_RTP :
/* all of the non IP protocols */
par->ipVer4 = ZL5011X_TRUE;
ipv4Header = ZL5011X_FALSE;
udpHeader = ZL5011X_FALSE;
break;
case ZL5011X_IP_UDP :
case ZL5011X_IP_UDP_PW :
case ZL5011X_IP_UDP_CD :
case ZL5011X_IP_UDP_RTP :
case ZL5011X_IP_UDP_RTP_PW :
case ZL5011X_IP_UDP_RTP_PW_ALT :
case ZL5011X_IP_UDP_L2TPV2_PW :
case ZL5011X_IP_UDP_RTCP_CTRL :
case ZL5011X_IP_UDP_L2TPV2_CTRL :
/* all of the IP->UDP protocols */
ipv4Header = par->ipVer4;
udpHeader = ZL5011X_TRUE;
if (ipv4Header == ZL5011X_TRUE)
{
udpPos = ZL5011X_PKT_ETHERNET_HDR_LEN + ZL5011X_PKT_IPV4_HDR_LEN;
}
else
{
udpPos = ZL5011X_PKT_ETHERNET_HDR_LEN + ZL5011X_PKT_IPV6_HDR_LEN;
}
break;
default:
/* all of the IP protocols */
ipv4Header = par->ipVer4;
udpHeader = ZL5011X_FALSE;
break;
}
/* Check to see if this protocol stack is already in use for this device. First try to find the device in the list
by matching the device structure pointer */
for (deviceIndex = 0; deviceIndex < ZL5011X_MAX_NUMBER_DEVICES; deviceIndex++)
{
if (Zl5011xProtocolTable[deviceIndex].paramStructPointer == zl5011xParams)
{
break;
}
}
/* If it got to the end of the list and didn't match one, then create one
with the first available null pointer in the list */
if (deviceIndex == ZL5011X_MAX_NUMBER_DEVICES)
{
for (deviceIndex = 0; deviceIndex < ZL5011X_MAX_NUMBER_DEVICES; deviceIndex++)
{
if (Zl5011xProtocolTable[deviceIndex].paramStructPointer == NULL)
{
Zl5011xProtocolTable[deviceIndex].paramStructPointer = zl5011xParams;
for (n = 0; n < ZL5011X_PKT_NUM_PROTOCOL_STACKS; n++)
{
Zl5011xProtocolTable[deviceIndex].protocol[n].matchNum[0][0] = (Uint32T)ZL5011X_INVALID;
Zl5011xProtocolTable[deviceIndex].protocol[n].matchNum[0][1] = (Uint32T)ZL5011X_INVALID;
Zl5011xProtocolTable[deviceIndex].protocol[n].matchNum[1][0] = (Uint32T)ZL5011X_INVALID;
Zl5011xProtocolTable[deviceIndex].protocol[n].matchNum[1][1] = (Uint32T)ZL5011X_INVALID;
}
for (n = 0; n < ZL5011X_PKC_NUM_PROTOCOL_ENTRIES; n++)
{
Zl5011xProtocolTable[deviceIndex].entry[n].contextDescriptorOffset = (Uint16T)ZL5011X_INVALID;
Zl5011xProtocolTable[deviceIndex].entry[n].protocol = ZL5011X_INVALID_PROTOCOL;
}
break;
}
}
if (deviceIndex == ZL5011X_MAX_NUMBER_DEVICES)
{
/* No free slot was found for the new device */
return(ZL5011X_ERROR);
}
}
/* Have a look to see if this protocol stack has been set up already */
if ((par->protocolType == ZL5011X_CD) || (par->protocolType == ZL5011X_IP_CD) ||
(par->protocolType == ZL5011X_IP_UDP_CD))
{
/* Prevent use of conficting protocol stacks simultaneously */
if (Zl5011xProtocolTable[deviceIndex].protocol[par->protocolType].matchNum[par->enableVlan][par->ipVer4] == ZL5011X_PKT_INCOMPATIBLE_HEADER)
{
/* this header cannot be setup, due to a conflicting protocol that has already been set */
return(ZL5011X_PKT_INCOMPATIBLE_HEADER_ERROR);
}
/* CD Protocol stacks are a special case because they may be setup but with different pre-classification data - this will
depend on the offset of the CD header. If there is a pre-classification entry of the same protocol stack and the CD
offset is the same then this match can be used. */
if (Zl5011xProtocolTable[deviceIndex].protocol[par->protocolType].matchNum[par->enableVlan][par->ipVer4] < ZL5011X_PKC_NUM_PROTOCOL_ENTRIES)
{
/* This means that the wanted CD stack has been used at least once. Now check the per pre-classification CD offset array
to see if any of them have matches. */
for (n = 0; n < ZL5011X_PKC_NUM_PROTOCOL_ENTRIES; n++)
{
if ((Uint8T)par->contextDescriptorOffset > (par->headerLength - ZL5011X_PKT_CD_HDR_LEN))
{
realContextDescriptorOffset = (par->headerLength - ZL5011X_PKT_CD_HDR_LEN);
}
else
{
realContextDescriptorOffset = par->contextDescriptorOffset;
}
realContextDescriptorOffset -= snapOffset;
/* check if the protocol has already been setup with this CD offset */
if ((Zl5011xProtocolTable[deviceIndex].entry[n].protocol == par->protocolType) &&
(Zl5011xProtocolTable[deviceIndex].entry[n].enableVlan == par->enableVlan) &&
(Zl5011xProtocolTable[deviceIndex].entry[n].contextDescriptorOffset == realContextDescriptorOffset))
{
if ((par->protocolType == ZL5011X_CD) || (Zl5011xProtocolTable[deviceIndex].entry[n].ipVer4 == par->ipVer4))
{
if (par->enableSnap == ZL5011X_TRUE)
{
par->contextDescriptorOffset = realContextDescriptorOffset + ZL5011X_PKT_SNAP_FIELD_LEN;
}
else
{
par->contextDescriptorOffset = realContextDescriptorOffset;
}
par->protocolMatchNumber = n;
return(ZL5011X_OK);
}
}
}
}
}
else
{
if (Zl5011xProtocolTable[deviceIndex].protocol[par->protocolType].matchNum[par->enableVlan][par->ipVer4] == ZL5011X_PKT_INCOMPATIBLE_HEADER)
{
/* this header cannot be setup, due to a conflicting protocol that has already been set */
return(ZL5011X_PKT_INCOMPATIBLE_HEADER_ERROR);
}
else
{
if (Zl5011xProtocolTable[deviceIndex].protocol[par->protocolType].matchNum[par->enableVlan][par->ipVer4] < ZL5011X_PKC_NUM_PROTOCOL_ENTRIES)
{
par->protocolMatchNumber = Zl5011xProtocolTable[deviceIndex].protocol[par->protocolType].matchNum[par->enableVlan][par->ipVer4];
if ((par->protocolType == ZL5011X_IP_L2TPV3_RTP_PW) || (par->protocolType == ZL5011X_IP_L2TPV3_RTCP_CTRL))
{
if (Zl5011xProtocolTable[deviceIndex].entry[par->protocolMatchNumber].enableL2TPCookie != par->enableL2TPCookie)
{
/* the protocol has already been setup, but with a different setting for
the cookie so return an error */
return(ZL5011X_PKT_INCOMPATIBLE_HEADER_ERROR);
}
}
if ((par->protocolType == ZL5011X_IP_UDP_RTP_PW) ||
(par->protocolType == ZL5011X_IP_L2TPV3_RTP_PW) ||
(par->protocolType == ZL5011X_MPLS_PW_RTP) ||
(par->protocolType == ZL5011X_IP_UDP_RTP_PW_ALT))
{
if (Zl5011xProtocolTable[deviceIndex].entry[par->protocolMatchNumber].rtpForceSeqNumber != par->rtpForceSeqNumber)
{
/* the protocol has already been setup, but with a different setting for
the RTP sequence number, so return an error */
return(ZL5011X_PKT_INCOMPATIBLE_HEADER_ERROR);
}
}
/* found the protocol already defined, return OK */
return(ZL5011X_OK);
}
}
}
/* Some of the protocol stacks have specific requirements. These are checked here. */
/* ZL5011X_PW can only be used if VLAN is enabled. This is because the ethernet and PW fields do not provide
for any classification tags. This is not a recoverable error, so return a failure. */
if ((par->protocolType == ZL5011X_PW) && (par->enableVlan != ZL5011X_TRUE))
{
ZL5011X_TRACE(ZL5011X_PACKET_FN_ID,"zl5011xPacketRxSetProtocol: Protocol Stack ZL5011X_PW requires VLAN to be enabled.",0,0,0,0,0,0);
return(ZL5011X_PARAMETER_INVALID);
}
/* if setting up an IP->L2TPv3->RTP header, then need to check that the cookie
setting is the same for both the data and control setups */
if ((par->protocolType == ZL5011X_IP_L2TPV3_RTP_PW) || (par->protocolType == ZL5011X_IP_L2TPV3_RTCP_CTRL))
{
if (par->protocolType == ZL5011X_IP_L2TPV3_RTP_PW)
{
temp = Zl5011xProtocolTable[deviceIndex].protocol[ZL5011X_IP_L2TPV3_RTCP_CTRL].matchNum[par->enableVlan][par->ipVer4];
}
else
{
temp = Zl5011xProtocolTable[deviceIndex].protocol[ZL5011X_IP_L2TPV3_RTP_PW].matchNum[par->enableVlan][par->ipVer4];
}
if (temp < (Sint32T)ZL5011X_PKC_NUM_PROTOCOL_ENTRIES)
{
/* the other type has already been setup, so check the cookie setting */
if (Zl5011xProtocolTable[deviceIndex].entry[temp].enableL2TPCookie != par->enableL2TPCookie)
{
/* Return the protocol match this conflicted with in the structure referenced */
par->protocolMatchNumber = temp;
return(ZL5011X_PKT_INCOMPATIBLE_HEADER_ERROR);
}
}
}
/* The header length should be a determinable value which can be checked - for non-CD
headers (arbitrary padding may be present for CD header). If headerLength does differ,
then use the local value. */
headerLength = zl5011xGetHeaderLength(par);
if ((par->protocolType != ZL5011X_CD) && (par->protocolType != ZL5011X_IP_CD) &&
(par->protocolType != ZL5011X_IP_UDP_CD))
{
if (headerLength != par->headerLength)
{
ZL5011X_TRACE(ZL5011X_PACKET_FN_ID,"zl5011xPacketRxSetProtocol: protocol header length should be %ld, not %ld.",
headerLength, par->headerLength, 0, 0, 0, 0);
ZL5011X_TRACE(ZL5011X_PACKET_FN_ID,"zl5011xPacketRxSetProtocol: Warning, using calculated header length.",0,0,0,0,0,0);
par->headerLength = (Uint8T)headerLength;
}
}
lanRxSetProtocolMatch = (zl5011xLanRxSetProtocolMatchS *)OS_CALLOC(1,sizeof(zl5011xLanRxSetProtocolMatchS));
if (lanRxSetProtocolMatch == NULL)
{
return(ZL5011X_RTOS_MEMORY_FAIL);
}
/* Initialise the structure. */
status = zl5011xLanRxSetProtocolMatchStructInit(zl5011xParams, lanRxSetProtocolMatch);
lanRxSetProtocolMatch->osExclusionEnable = par->osExclusionEnable;
if (status != ZL5011X_OK)
{
OS_FREE(lanRxSetProtocolMatch);
return(status);
}
/* Take account of IP version */
if (par->ipVer4 == ZL5011X_TRUE)
{
templateInUse = &(zl5011xPacketRxTemplatesIPv4[par->protocolType]);
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -