[qos] handle NCP messages based on the priority of the message (#3318)

This commit is contained in:
Zhanglong Xia
2018-12-19 13:55:26 -08:00
committed by Jonathan Hui
parent 4ed2c8c222
commit 19f2533aff
7 changed files with 140 additions and 30 deletions
+34 -6
View File
@@ -256,7 +256,7 @@ OTAPI const otNetifAddress *OTCALL otIp6GetUnicastAddresses(otInstance *aInstanc
* @retval OT_ERROR_ALREADY The multicast address is already subscribed.
* @retval OT_ERROR_INVALID_ARGS The IP Address indicated by @p aAddress is invalid address.
* @retval OT_ERROR_NO_BUFS The Network Interface is already storing the maximum allowed external multicast
* addresses.
* addresses.
*
*/
otError otIp6SubscribeMulticastAddress(otInstance *aInstance, const otIp6Address *aAddress);
@@ -279,6 +279,7 @@ otError otIp6UnsubscribeMulticastAddress(otInstance *aInstance, const otIp6Addre
* @param[in] aInstance A pointer to an OpenThread instance.
*
* @returns A pointer to the first Network Interface Multicast Address.
*
*/
const otNetifMulticastAddress *otIp6GetMulticastAddresses(otInstance *aInstance);
@@ -288,6 +289,7 @@ const otNetifMulticastAddress *otIp6GetMulticastAddresses(otInstance *aInstance)
* @param[in] aInstance A pointer to an OpenThread instance.
*
* @sa otIp6SetMulticastPromiscuousEnabled
*
*/
bool otIp6IsMulticastPromiscuousEnabled(otInstance *aInstance);
@@ -298,6 +300,7 @@ bool otIp6IsMulticastPromiscuousEnabled(otInstance *aInstance);
* @param[in] aEnabled TRUE to enable Multicast Promiscuous mode, FALSE otherwise.
*
* @sa otIp6IsMulticastPromiscuousEnabled
*
*/
void otIp6SetMulticastPromiscuousEnabled(otInstance *aInstance, bool aEnabled);
@@ -308,7 +311,7 @@ void otIp6SetMulticastPromiscuousEnabled(otInstance *aInstance, bool aEnabled);
* @param[inout] aAddress A pointer to structure containing IPv6 address for which IID is being created.
* @param[inout] aContext A pointer to creator-specific context.
*
* @retval OT_ERROR_NONE Created valid IID for given IPv6 address.
* @retval OT_ERROR_NONE Created valid IID for given IPv6 address.
* @retval OT_ERROR_IP6_ADDRESS_CREATION_FAILURE Creation of valid IID for given IPv6 address failed.
*
*/
@@ -361,7 +364,7 @@ otError otIp6CreateMacIid(otInstance *aInstance, otNetifAddress *aAddresses, voi
* @param[inout] aAddresses A pointer to structure containing IPv6 address for which IID is being created.
* @param[inout] aContext A pointer to a otSemanticallyOpaqueIidGeneratorData structure.
*
* @retval OT_ERROR_NONE Created valid IID for given IPv6 address.
* @retval OT_ERROR_NONE Created valid IID for given IPv6 address.
* @retval OT_ERROR_IP6_ADDRESS_CREATION_FAILURE Could not create valid IID for given IPv6 address.
*
*/
@@ -378,10 +381,33 @@ otError otIp6CreateSemanticallyOpaqueIid(otInstance *aInstance, otNetifAddress *
*
* @returns A pointer to the message buffer or NULL if no message buffers are available or parameters are invalid.
*
* @sa otFreeMessage
* @sa otMessageFree
*
*/
otMessage *otIp6NewMessage(otInstance *aInstance, const otMessageSettings *aSettings);
/**
* Allocate a new message buffer and write the IPv6 datagram to the message buffer for sending an IPv6 message.
*
* @note If @p aSettings is NULL, the link layer security is enabled and the message priority is obtained from IPv6
* message itself.
* If @p aSettings is not NULL, the @p aSetting->mPriority is ignored and obtained from IPv6 message itself.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aData A pointer to the IPv6 datagram buffer.
* @param[in] aDataLength The size of the IPv6 datagram buffer pointed by @p aData.
* @param[in] aSettings A pointer to the message settings or NULL to set default settings.
*
* @returns A pointer to the message or NULL if malformed IPv6 header or insufficient message buffers are available.
*
* @sa otMessageFree
*
*/
otMessage *otIp6NewMessageFromBuffer(otInstance * aInstance,
const uint8_t * aData,
uint16_t aDataLength,
const otMessageSettings *aSettings);
/**
* This function pointer is called when an IPv6 datagram is received.
*
@@ -485,8 +511,8 @@ otError otIp6AddUnsecurePort(otInstance *aInstance, uint16_t aPort);
* This function removes a port from the allowed unsecure port list.
*
* @note This function removes @p aPort by overwriting @p aPort with the element after @p aPort in the internal port
* list. Be careful when calling otIp6GetUnsecurePorts() followed by otIp6RemoveUnsecurePort() to remove unsecure
* ports.
* list. Be careful when calling otIp6GetUnsecurePorts() followed by otIp6RemoveUnsecurePort() to remove unsecure
* ports.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aPort The port value.
@@ -526,6 +552,7 @@ const uint16_t *otIp6GetUnsecurePorts(otInstance *aInstance, uint8_t *aNumEntrie
*
* @retval TRUE The two IPv6 addresses are the same.
* @retval FALSE The two IPv6 addresses are not the same.
*
*/
OTAPI bool OTCALL otIp6IsAddressEqual(const otIp6Address *aFirst, const otIp6Address *aSecond);
@@ -537,6 +564,7 @@ OTAPI bool OTCALL otIp6IsAddressEqual(const otIp6Address *aFirst, const otIp6Add
*
* @retval OT_ERROR_NONE Successfully parsed the string.
* @retval OT_ERROR_INVALID_ARGS Failed to parse the string.
*
*/
OTAPI otError OTCALL otIp6AddressFromString(const char *aString, otIp6Address *aAddress);
+14
View File
@@ -217,6 +217,20 @@ exit:
return message;
}
otMessage *otIp6NewMessageFromBuffer(otInstance * aInstance,
const uint8_t * aData,
uint16_t aDataLength,
const otMessageSettings *aSettings)
{
Instance &instance = *static_cast<Instance *>(aInstance);
Message * message;
VerifyOrExit((message = instance.GetIp6().NewMessage(aData, aDataLength, aSettings)) != NULL);
exit:
return message;
}
otError otIp6AddUnsecurePort(otInstance *aInstance, uint16_t aPort)
{
Instance &instance = *static_cast<Instance *>(aInstance);
+40
View File
@@ -73,6 +73,29 @@ Message *Ip6::NewMessage(uint16_t aReserved, const otMessageSettings *aSettings)
Message::kTypeIp6, sizeof(Header) + sizeof(HopByHopHeader) + sizeof(OptionMpl) + aReserved, aSettings);
}
Message *Ip6::NewMessage(const uint8_t *aData, uint16_t aDataLength, const otMessageSettings *aSettings)
{
otMessageSettings settings = {true, OT_MESSAGE_PRIORITY_NORMAL};
Message * message = NULL;
if (aSettings != NULL)
{
settings = *aSettings;
}
SuccessOrExit(GetDatagramPriority(aData, aDataLength, *reinterpret_cast<uint8_t *>(&settings.mPriority)));
VerifyOrExit((message = GetInstance().GetMessagePool().New(Message::kTypeIp6, 0, &settings)) != NULL);
if (message->Append(aData, aDataLength) != OT_ERROR_NONE)
{
message->Free();
message = NULL;
}
exit:
return message;
}
uint8_t Ip6::DscpToPriority(uint8_t aDscp)
{
uint8_t priority;
@@ -127,6 +150,23 @@ uint8_t Ip6::PriorityToDscp(uint8_t aPriority)
return dscp;
}
otError Ip6::GetDatagramPriority(const uint8_t *aData, uint16_t aDataLen, uint8_t &aPriority)
{
otError error = OT_ERROR_NONE;
const Header *header;
VerifyOrExit((aData != NULL) && (aDataLen >= sizeof(Header)), error = OT_ERROR_INVALID_ARGS);
header = reinterpret_cast<const Header *>(aData);
VerifyOrExit(header->IsValid(), error = OT_ERROR_PARSE);
VerifyOrExit(sizeof(Header) + header->GetPayloadLength() == aDataLen, error = OT_ERROR_PARSE);
aPriority = DscpToPriority(header->GetDscp());
exit:
return error;
}
uint16_t Ip6::UpdateChecksum(uint16_t aChecksum, const Address &aAddress)
{
return Message::UpdateChecksum(aChecksum, aAddress.mFields.m8, sizeof(aAddress));
+19 -1
View File
@@ -111,7 +111,7 @@ public:
* This method allocates a new message buffer from the buffer pool.
*
* @note If @p aSettings is 'NULL', the link layer security is enabled and the message priority is set to
* OT_MESSAGE_PRIORITY_NORMAL by default.
* OT_MESSAGE_PRIORITY_NORMAL by default.
*
* @param[in] aReserved The number of header bytes to reserve following the IPv6 header.
* @param[in] aSettings A pointer to the message settings or NULL to set default settings.
@@ -121,6 +121,22 @@ public:
*/
Message *NewMessage(uint16_t aReserved, const otMessageSettings *aSettings = NULL);
/**
* This method allocates a new message buffer from the buffer pool and writes the IPv6 datagram to the message.
*
* @note If @p aSettings is NULL, the link layer security is enabled and the message priority is obtained from
* IPv6 message itself.
* If @p aSettings is not NULL, the @p aSetting->mPriority is ignored and obtained from IPv6 message itself.
*
* @param[in] aData A pointer to the IPv6 datagram buffer.
* @param[in] aDataLength The size of the IPV6 datagram buffer pointed by @p aData.
* @param[in] aSettings A pointer to the message settings or NULL to set default settings.
*
* @returns A pointer to the message or NULL if malformed IPv6 header or insufficient message buffers are available.
*
*/
Message *NewMessage(const uint8_t *aData, uint16_t aDataLength, const otMessageSettings *aSettings);
/**
* This method converts the message priority level to IPv6 DSCP value.
*
@@ -411,6 +427,8 @@ private:
static void HandleSendQueue(Tasklet &aTasklet);
void HandleSendQueue(void);
static otError GetDatagramPriority(const uint8_t *aData, uint16_t aDataLen, uint8_t &aPriority);
otError ProcessReceiveCallback(const Message & aMessage,
const MessageInfo &aMessageInfo,
uint8_t aIpProto,
+17 -8
View File
@@ -40,22 +40,31 @@ namespace Ip6 {
otError Header::Init(const Message &aMessage)
{
otError error = OT_ERROR_NONE;
uint16_t length;
otError error = OT_ERROR_NONE;
// check aMessage length
VerifyOrExit(aMessage.Read(0, sizeof(*this), this) == sizeof(*this), error = OT_ERROR_PARSE);
// check Version
VerifyOrExit(IsVersion6(), error = OT_ERROR_PARSE);
// check Payload Length
length = sizeof(*this) + GetPayloadLength();
VerifyOrExit(length == aMessage.GetLength() && length <= Ip6::kMaxDatagramLength, error = OT_ERROR_PARSE);
VerifyOrExit(IsValid(), error = OT_ERROR_PARSE);
VerifyOrExit((sizeof(*this) + GetPayloadLength()) == aMessage.GetLength(), error = OT_ERROR_PARSE);
exit:
return error;
}
bool Header::IsValid(void) const
{
bool ret = true;
// check Version
VerifyOrExit(IsVersion6(), ret = false);
// check Payload Length
VerifyOrExit((sizeof(*this) + GetPayloadLength()) <= Ip6::kMaxDatagramLength, ret = false);
exit:
return ret;
}
} // namespace Ip6
} // namespace ot
+10 -1
View File
@@ -177,6 +177,15 @@ public:
*/
otError Init(const Message &aMessage);
/**
* This method indicates whether or not the header appears to be well-formed.
*
* @retval TRUE if the header appears to be well-formed.
* @retval FALSE if the header does not appear to be well-formed.
*
*/
bool IsValid(void) const;
/**
* This method indicates whether or not the IPv6 Version is set to 6.
*
@@ -216,7 +225,7 @@ public:
* @returns The IPv6 Payload Length value.
*
*/
uint16_t GetPayloadLength(void) { return HostSwap16(mPayloadLength); }
uint16_t GetPayloadLength(void) const { return HostSwap16(mPayloadLength); }
/**
* This method sets the IPv6 Payload Length value.
+6 -14
View File
@@ -1744,19 +1744,15 @@ template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_STREAM_NET>(void)
otMessage * message = NULL;
otError error = OT_ERROR_NONE;
// STREAM_NET requires layer 2 security.
message = otIp6NewMessage(mInstance, NULL);
VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);
SuccessOrExit(error = mDecoder.ReadDataWithLen(framePtr, frameLen));
SuccessOrExit(error = mDecoder.ReadData(metaPtr, metaLen));
// We ignore metadata for now.
// May later include TX power, allow retransmits, etc...
OT_UNUSED_VARIABLE(metaPtr);
OT_UNUSED_VARIABLE(metaLen);
SuccessOrExit(error = otMessageAppend(message, framePtr, frameLen));
// STREAM_NET requires layer 2 security.
message = otIp6NewMessageFromBuffer(mInstance, framePtr, frameLen, NULL);
VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);
error = otIp6Send(mInstance, message);
@@ -2588,19 +2584,15 @@ template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_STREAM_NET_INSECURE>(
otError error = OT_ERROR_NONE;
otMessageSettings msgSettings = {false, OT_MESSAGE_PRIORITY_NORMAL};
// STREAM_NET_INSECURE packets are not secured at layer 2.
message = otIp6NewMessage(mInstance, &msgSettings);
VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);
SuccessOrExit(mDecoder.ReadDataWithLen(framePtr, frameLen));
SuccessOrExit(mDecoder.ReadData(metaPtr, metaLen));
// We ignore metadata for now.
// May later include TX power, allow retransmits, etc...
OT_UNUSED_VARIABLE(metaPtr);
OT_UNUSED_VARIABLE(metaLen);
SuccessOrExit(error = otMessageAppend(message, framePtr, frameLen));
// STREAM_NET_INSECURE packets are not secured at layer 2.
message = otIp6NewMessageFromBuffer(mInstance, framePtr, frameLen, &msgSettings);
VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);
// Ensure the insecure message is forwarded using direct transmission.
otMessageSetDirectTransmission(message, true);