[qos] process IPv6 packet priority (#3201)

This commit is contained in:
Zhanglong Xia
2018-11-07 23:16:34 -08:00
committed by Jonathan Hui
parent cf5352fb43
commit 4693638f77
5 changed files with 168 additions and 2 deletions
+55
View File
@@ -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));
+20
View File
@@ -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.
*
+42
View File
@@ -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;
+45 -2
View File
@@ -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,
+6
View File
@@ -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);