mirror of
https://github.com/espressif/openthread.git
synced 2026-08-08 03:37:46 +00:00
[qos] process IPv6 packet priority (#3201)
This commit is contained in:
committed by
Jonathan Hui
parent
cf5352fb43
commit
4693638f77
@@ -73,6 +73,60 @@ Message *Ip6::NewMessage(uint16_t aReserved, const otMessageSettings *aSettings)
|
||||
Message::kTypeIp6, sizeof(Header) + sizeof(HopByHopHeader) + sizeof(OptionMpl) + aReserved, aSettings);
|
||||
}
|
||||
|
||||
uint8_t Ip6::DscpToPriority(uint8_t aDscp)
|
||||
{
|
||||
uint8_t priority;
|
||||
uint8_t cs = aDscp & kDscpCsMask;
|
||||
|
||||
switch (cs)
|
||||
{
|
||||
case kDscpCs1:
|
||||
case kDscpCs2:
|
||||
priority = Message::kPriorityLow;
|
||||
break;
|
||||
|
||||
case kDscpCs0:
|
||||
case kDscpCs3:
|
||||
priority = Message::kPriorityNormal;
|
||||
break;
|
||||
|
||||
case kDscpCs4:
|
||||
case kDscpCs5:
|
||||
case kDscpCs6:
|
||||
case kDscpCs7:
|
||||
priority = Message::kPriorityHigh;
|
||||
break;
|
||||
|
||||
default:
|
||||
priority = Message::kPriorityNormal;
|
||||
break;
|
||||
}
|
||||
|
||||
return priority;
|
||||
}
|
||||
|
||||
uint8_t Ip6::PriorityToDscp(uint8_t aPriority)
|
||||
{
|
||||
uint8_t dscp = kDscpCs0;
|
||||
|
||||
switch (aPriority)
|
||||
{
|
||||
case Message::kPriorityLow:
|
||||
dscp = kDscpCs1;
|
||||
break;
|
||||
|
||||
case Message::kPriorityNormal:
|
||||
dscp = kDscpCs0;
|
||||
break;
|
||||
|
||||
case Message::kPriorityHigh:
|
||||
dscp = kDscpCs4;
|
||||
break;
|
||||
}
|
||||
|
||||
return dscp;
|
||||
}
|
||||
|
||||
uint16_t Ip6::UpdateChecksum(uint16_t aChecksum, const Address &aAddress)
|
||||
{
|
||||
return Message::UpdateChecksum(aChecksum, aAddress.mFields.m8, sizeof(aAddress));
|
||||
@@ -358,6 +412,7 @@ otError Ip6::SendDatagram(Message &aMessage, MessageInfo &aMessageInfo, IpProto
|
||||
const NetifUnicastAddress *source;
|
||||
|
||||
header.Init();
|
||||
header.SetDscp(PriorityToDscp(aMessage.GetPriority()));
|
||||
header.SetPayloadLength(payloadLength);
|
||||
header.SetNextHeader(aIpProto);
|
||||
header.SetHopLimit(aMessageInfo.mHopLimit ? aMessageInfo.mHopLimit : static_cast<uint8_t>(kDefaultHopLimit));
|
||||
|
||||
@@ -121,6 +121,26 @@ public:
|
||||
*/
|
||||
Message *NewMessage(uint16_t aReserved, const otMessageSettings *aSettings = NULL);
|
||||
|
||||
/**
|
||||
* This method converts the message priority level to IPv6 DSCP value.
|
||||
*
|
||||
* @param[in] aPriority The message priority level.
|
||||
*
|
||||
* @returns The IPv6 DSCP value.
|
||||
*
|
||||
*/
|
||||
static uint8_t PriorityToDscp(uint8_t aPriority);
|
||||
|
||||
/**
|
||||
* This method converts the IPv6 DSCP value to message priority level.
|
||||
*
|
||||
* @param[in] aDscp The IPv6 DSCP value.
|
||||
*
|
||||
* @returns The message priority level.
|
||||
*
|
||||
*/
|
||||
static uint8_t DscpToPriority(uint8_t aDscp);
|
||||
|
||||
/**
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
|
||||
@@ -101,6 +101,22 @@ enum IpProto
|
||||
kProtoDstOpts = 60, ///< Destination Options for IPv6
|
||||
};
|
||||
|
||||
/**
|
||||
* Class Selectors
|
||||
*/
|
||||
enum IpDscpCs
|
||||
{
|
||||
kDscpCs0 = 0, ///< Class selector codepoint 0
|
||||
kDscpCs1 = 8, ///< Class selector codepoint 8
|
||||
kDscpCs2 = 16, ///< Class selector codepoint 16
|
||||
kDscpCs3 = 24, ///< Class selector codepoint 24
|
||||
kDscpCs4 = 32, ///< Class selector codepoint 32
|
||||
kDscpCs5 = 40, ///< Class selector codepoint 40
|
||||
kDscpCs6 = 48, ///< Class selector codepoint 48
|
||||
kDscpCs7 = 56, ///< Class selector codepoint 56
|
||||
kDscpCsMask = 0x38, ///< Class selector mask
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kVersionClassFlowSize = 4, ///< Combined size of Version, Class, Flow Label in bytes.
|
||||
@@ -170,6 +186,30 @@ public:
|
||||
*/
|
||||
bool IsVersion6(void) const { return (mVersionClassFlow.m8[0] & kVersionMask) == kVersion6; }
|
||||
|
||||
/**
|
||||
* This method returns the IPv6 DSCP value.
|
||||
*
|
||||
* @returns The IPv6 DSCP value.
|
||||
*
|
||||
*/
|
||||
uint8_t GetDscp(void) const
|
||||
{
|
||||
return static_cast<uint8_t>((HostSwap32(mVersionClassFlow.m32[0]) & kDscpMask) >> kDscpOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 DSCP value.
|
||||
*
|
||||
* @param[in] aDscp The IPv6 DSCP value.
|
||||
*
|
||||
*/
|
||||
void SetDscp(uint8_t aDscp)
|
||||
{
|
||||
uint32_t tmp = HostSwap32(mVersionClassFlow.m32[0]);
|
||||
tmp = (tmp & static_cast<uint32_t>(~kDscpMask)) | ((static_cast<uint32_t>(aDscp) << kDscpOffset) & kDscpMask);
|
||||
mVersionClassFlow.m32[0] = HostSwap32(tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the IPv6 Payload Length value.
|
||||
*
|
||||
@@ -287,6 +327,8 @@ private:
|
||||
{
|
||||
kVersion6 = 0x60,
|
||||
kVersionMask = 0xf0,
|
||||
kDscpOffset = 22,
|
||||
kDscpMask = 0xfc00000,
|
||||
};
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
|
||||
@@ -1317,7 +1317,10 @@ void MeshForwarder::HandleFragment(uint8_t * aFrame,
|
||||
|
||||
if (fragmentHeader.GetDatagramOffset() == 0)
|
||||
{
|
||||
VerifyOrExit((message = GetInstance().GetMessagePool().New(Message::kTypeIp6, 0)) != NULL,
|
||||
uint8_t priority;
|
||||
|
||||
SuccessOrExit(error = GetFramePriority(aFrame, aFrameLength, aMacSource, aMacDest, priority));
|
||||
VerifyOrExit((message = GetInstance().GetMessagePool().New(Message::kTypeIp6, 0, priority)) != NULL,
|
||||
error = OT_ERROR_NO_BUFS);
|
||||
message->SetLinkSecurityEnabled(aLinkInfo.mLinkSecurity);
|
||||
message->SetPanId(aLinkInfo.mPanId);
|
||||
@@ -1492,12 +1495,14 @@ void MeshForwarder::HandleLowpanHC(uint8_t * aFrame,
|
||||
otError error = OT_ERROR_NONE;
|
||||
Message * message = NULL;
|
||||
int headerLength;
|
||||
uint8_t priority;
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
UpdateRoutes(aFrame, aFrameLength, aMacSource, aMacDest);
|
||||
#endif
|
||||
|
||||
VerifyOrExit((message = GetInstance().GetMessagePool().New(Message::kTypeIp6, 0)) != NULL,
|
||||
SuccessOrExit(error = GetFramePriority(aFrame, aFrameLength, aMacSource, aMacDest, priority));
|
||||
VerifyOrExit((message = GetInstance().GetMessagePool().New(Message::kTypeIp6, 0, priority)) != NULL,
|
||||
error = OT_ERROR_NO_BUFS);
|
||||
message->SetLinkSecurityEnabled(aLinkInfo.mLinkSecurity);
|
||||
message->SetPanId(aLinkInfo.mPanId);
|
||||
@@ -1552,6 +1557,44 @@ otError MeshForwarder::HandleDatagram(Message & aMessage,
|
||||
return netif.GetIp6().HandleDatagram(aMessage, &netif, netif.GetInterfaceId(), &aLinkInfo, false);
|
||||
}
|
||||
|
||||
otError MeshForwarder::GetFramePriority(uint8_t * aFrame,
|
||||
uint8_t aFrameLength,
|
||||
const Mac::Address &aMacSource,
|
||||
const Mac::Address &aMacDest,
|
||||
uint8_t & aPriority)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
Ip6::Header ip6Header;
|
||||
Ip6::UdpHeader udpHeader;
|
||||
uint8_t headerLength;
|
||||
bool nextHeaderCompressed;
|
||||
|
||||
SuccessOrExit(error = DecompressIp6Header(aFrame, aFrameLength, aMacSource, aMacDest, ip6Header, headerLength,
|
||||
nextHeaderCompressed));
|
||||
aPriority = GetNetif().GetIp6().DscpToPriority(ip6Header.GetDscp());
|
||||
VerifyOrExit(ip6Header.GetNextHeader() == Ip6::kProtoUdp);
|
||||
|
||||
aFrame += headerLength;
|
||||
aFrameLength -= headerLength;
|
||||
|
||||
if (nextHeaderCompressed)
|
||||
{
|
||||
VerifyOrExit(GetNetif().GetLowpan().DecompressUdpHeader(udpHeader, aFrame, aFrameLength) >= 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&udpHeader, aFrame, sizeof(Ip6::UdpHeader));
|
||||
}
|
||||
|
||||
if (udpHeader.GetDestinationPort() == Mle::kUdpPort || udpHeader.GetDestinationPort() == kCoapUdpPort)
|
||||
{
|
||||
aPriority = Message::kPriorityNet;
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_NOTE) && (OPENTHREAD_CONFIG_LOG_MAC == 1)
|
||||
|
||||
otError MeshForwarder::ParseIp6UdpTcpHeader(const Message &aMessage,
|
||||
|
||||
@@ -336,6 +336,12 @@ private:
|
||||
static void ScheduleTransmissionTask(Tasklet &aTasklet);
|
||||
void ScheduleTransmissionTask(void);
|
||||
|
||||
otError GetFramePriority(uint8_t * aFrame,
|
||||
uint8_t aFrameLength,
|
||||
const Mac::Address &aMacSource,
|
||||
const Mac::Address &aMacDest,
|
||||
uint8_t & aPriority);
|
||||
|
||||
otError GetDestinationRlocByServiceAloc(uint16_t aServiceAloc, uint16_t &aMeshDest);
|
||||
|
||||
void LogMessage(MessageAction aAction, const Message &aMessage, const Mac::Address *aAddress, otError aError);
|
||||
|
||||
Reference in New Issue
Block a user