[network-data] optimize network data update via MLE (#2612)

This commit reduces stack usage when receiving/updating network data via MLE
by copying the network data directly out of the message and skipping the TLV
read.
This commit is contained in:
Jonathan Hui
2018-03-12 18:27:07 +00:00
committed by GitHub
parent 8ad0e8e0c9
commit 51c62a29d0
5 changed files with 49 additions and 36 deletions
+11 -12
View File
@@ -2554,9 +2554,9 @@ otError Mle::HandleLeaderData(const Message &aMessage, const Ip6::MessageInfo &a
ThreadNetif & netif = GetNetif();
otError error = OT_ERROR_NONE;
LeaderDataTlv leaderData;
NetworkDataTlv networkData;
ActiveTimestampTlv activeTimestamp;
PendingTimestampTlv pendingTimestamp;
uint16_t networkDataOffset = 0;
uint16_t activeDatasetOffset = 0;
uint16_t pendingDatasetOffset = 0;
bool dataRequest = false;
@@ -2638,13 +2638,12 @@ otError Mle::HandleLeaderData(const Message &aMessage, const Ip6::MessageInfo &a
pendingTimestamp.SetLength(0);
}
if (Tlv::GetTlv(aMessage, Tlv::kNetworkData, sizeof(networkData), networkData) == OT_ERROR_NONE)
if (Tlv::GetOffset(aMessage, Tlv::kNetworkData, networkDataOffset) == OT_ERROR_NONE)
{
VerifyOrExit(networkData.IsValid(), error = OT_ERROR_PARSE);
netif.GetNetworkDataLeader().SetNetworkData(leaderData.GetDataVersion(), leaderData.GetStableDataVersion(),
(mDeviceMode & ModeTlv::kModeFullNetworkData) == 0,
networkData.GetNetworkData(), networkData.GetLength());
error = netif.GetNetworkDataLeader().SetNetworkData(
leaderData.GetDataVersion(), leaderData.GetStableDataVersion(),
(mDeviceMode & ModeTlv::kModeFullNetworkData) == 0, aMessage, networkDataOffset);
SuccessOrExit(error);
}
else
{
@@ -2912,11 +2911,11 @@ otError Mle::HandleChildIdResponse(const Message &aMessage, const Ip6::MessageIn
LeaderDataTlv leaderData;
SourceAddressTlv sourceAddress;
Address16Tlv shortAddress;
NetworkDataTlv networkData;
RouteTlv route;
ActiveTimestampTlv activeTimestamp;
PendingTimestampTlv pendingTimestamp;
Tlv tlv;
uint16_t networkDataOffset;
uint16_t offset;
// Source Address
@@ -2936,7 +2935,8 @@ otError Mle::HandleChildIdResponse(const Message &aMessage, const Ip6::MessageIn
VerifyOrExit(shortAddress.IsValid(), error = OT_ERROR_PARSE);
// Network Data
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kNetworkData, sizeof(networkData), networkData));
error = Tlv::GetOffset(aMessage, Tlv::kNetworkData, networkDataOffset);
SuccessOrExit(error);
// Active Timestamp
if (Tlv::GetTlv(aMessage, Tlv::kActiveTimestamp, sizeof(activeTimestamp), activeTimestamp) == OT_ERROR_NONE)
@@ -3003,8 +3003,8 @@ otError Mle::HandleChildIdResponse(const Message &aMessage, const Ip6::MessageIn
mParent.SetRloc16(sourceAddress.GetRloc16());
netif.GetNetworkDataLeader().SetNetworkData(leaderData.GetDataVersion(), leaderData.GetStableDataVersion(),
(mDeviceMode & ModeTlv::kModeFullNetworkData) == 0,
networkData.GetNetworkData(), networkData.GetLength());
(mDeviceMode & ModeTlv::kModeFullNetworkData) == 0, aMessage,
networkDataOffset);
netif.GetActiveDataset().ApplyConfiguration();
@@ -3029,7 +3029,6 @@ otError Mle::HandleChildUpdateRequest(const Message &aMessage, const Ip6::Messag
Mac::ExtAddress srcAddr;
SourceAddressTlv sourceAddress;
LeaderDataTlv leaderData;
NetworkDataTlv networkData;
ChallengeTlv challenge;
StatusTlv status;
TlvRequestTlv tlvRequest;
-9
View File
@@ -864,15 +864,6 @@ public:
SetLength(sizeof(*this) - sizeof(Tlv));
}
/**
* This method indicates whether or not the TLV appears to be well-formed.
*
* @retval TRUE If the TLV appears to be well-formed.
* @retval FALSE If the TLV does not appear to be well-formed.
*
*/
bool IsValid(void) const { return GetLength() < sizeof(*this) - sizeof(Tlv); }
/**
* This method returns a pointer to the Network Data.
*
+19 -7
View File
@@ -404,16 +404,25 @@ otError LeaderBase::DefaultRouteLookup(PrefixTlv &aPrefix, uint16_t *aRloc16)
return error;
}
void LeaderBase::SetNetworkData(uint8_t aVersion,
uint8_t aStableVersion,
bool aStable,
const uint8_t *aData,
uint8_t aDataLength)
otError LeaderBase::SetNetworkData(uint8_t aVersion,
uint8_t aStableVersion,
bool aStable,
const Message &aMessage,
uint16_t aMessageOffset)
{
otError error = OT_ERROR_NONE;
Mle::Tlv tlv;
uint16_t length;
length = aMessage.Read(aMessageOffset, sizeof(tlv), &tlv);
VerifyOrExit(length == sizeof(tlv), error = OT_ERROR_PARSE);
length = aMessage.Read(aMessageOffset + sizeof(tlv), tlv.GetLength(), mTlvs);
VerifyOrExit(length == tlv.GetLength(), error = OT_ERROR_PARSE);
mLength = tlv.GetLength();
mVersion = aVersion;
mStableVersion = aStableVersion;
memcpy(mTlvs, aData, aDataLength);
mLength = aDataLength;
if (aStable)
{
@@ -423,6 +432,9 @@ void LeaderBase::SetNetworkData(uint8_t aVersion,
otDumpDebgNetData(GetInstance(), "set network data", mTlvs, mLength);
GetNotifier().SetFlags(OT_CHANGED_THREAD_NETDATA);
exit:
return error;
}
otError LeaderBase::SetCommissioningData(const uint8_t *aValue, uint8_t aValueLength)
+10 -7
View File
@@ -153,15 +153,18 @@ public:
* @param[in] aVersion The Version value.
* @param[in] aStableVersion The Stable Version value.
* @param[in] aStableOnly TRUE if storing only the stable data, FALSE otherwise.
* @param[in] aData A pointer to the Network Data.
* @param[in] aDataLength The length of the Network Data in bytes.
* @param[in] aMessage A reference to the MLE message.
* @param[in] aMessageOffset The offset in @p aMessage for the Network Data TLV.
*
* @retval OT_ERROR_NONE Successfully set the network data.
* @retval OT_ERROR_PARSE Network Data TLV in @p aMessage is not valid.
*
*/
void SetNetworkData(uint8_t aVersion,
uint8_t aStableVersion,
bool aStableOnly,
const uint8_t *aData,
uint8_t aDataLength);
otError SetNetworkData(uint8_t aVersion,
uint8_t aStableVersion,
bool aStableOnly,
const Message &aMessage,
uint16_t aMessageOffset);
/**
* This method sends a Server Data Notification message to the Leader indicating an invalid RLOC16.
+9 -1
View File
@@ -114,6 +114,9 @@ static void Init()
// Emulate global prefixes with contextes.
uint8_t mockNetworkData[] = {
0x0c, // MLE Network Data Type
0x20, // MLE Network Data Length
// Prefix 2001:2:0:1::/64
0x03, 0x0e, // Prefix TLV
0x00, 0x40, 0x20, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x07, 0x02, // 6LoWPAN Context ID TLV
@@ -125,7 +128,12 @@ static void Init()
0x02, 0x40 // Context ID = 2, C = FALSE
};
sThreadNetif->GetNetworkDataLeader().SetNetworkData(0, 0, true, mockNetworkData, sizeof(mockNetworkData));
Message *message = sInstance->GetMessagePool().New(Message::kTypeIp6, 0);
VerifyOrQuit(message != NULL, "6lo: Ip6::NewMessage failed");
SuccessOrQuit(message->Append(mockNetworkData, sizeof(mockNetworkData)), "6lo: Message::Append failed");
sThreadNetif->GetNetworkDataLeader().SetNetworkData(0, 0, true, *message, 0);
}
/**