[network-data] clean stale child's server info when its parent is removed (#2905)

This commit is contained in:
rongli
2018-07-23 09:06:38 -05:00
committed by Jonathan Hui
parent 6269da241b
commit dcc3eac579
4 changed files with 68 additions and 34 deletions
+14
View File
@@ -920,6 +920,20 @@ public:
*/
static uint8_t GetRouterId(uint16_t aRloc16) { return aRloc16 >> kRouterIdOffset; }
/**
* This method returns whether the two RLOC16 have the same Router ID.
*
* @param[in] aRloc16A The first RLOC16 value.
* @param[in] aRloc16B The second RLOC16 value.
*
* @returns true if the two RLOC16 have the same Router ID, false otherwise.
*
*/
static bool RouterIdMatch(uint16_t aRloc16A, uint16_t aRloc16B)
{
return ((aRloc16A >> kRouterIdOffset) == (aRloc16B >> kRouterIdOffset));
}
/**
* This method returns the Service ID corresponding to a Service ALOC16.
*
+35 -24
View File
@@ -126,15 +126,15 @@ otError Leader::SetContextIdReuseDelay(uint32_t aDelay)
return OT_ERROR_NONE;
}
void Leader::RemoveBorderRouter(uint16_t aRloc16)
void Leader::RemoveBorderRouter(uint16_t aRloc16, bool aExactMatch)
{
bool rlocIn = false;
bool rlocStable = false;
RlocLookup(aRloc16, rlocIn, rlocStable, mTlvs, mLength);
RlocLookup(aRloc16, rlocIn, rlocStable, mTlvs, mLength, aExactMatch);
VerifyOrExit(rlocIn);
RemoveRloc(aRloc16, aExactMatch);
RemoveRloc(aRloc16);
mVersion++;
if (rlocStable)
@@ -168,7 +168,7 @@ void Leader::HandleServerData(Coap::Header &aHeader, Message &aMessage, const Ip
if (ThreadTlv::GetTlv(aMessage, ThreadTlv::kRloc16, sizeof(rloc16), rloc16) == OT_ERROR_NONE)
{
VerifyOrExit(rloc16.IsValid());
RemoveBorderRouter(rloc16.GetRloc16());
RemoveBorderRouter(rloc16.GetRloc16(), true);
}
if (ThreadTlv::GetTlv(aMessage, ThreadTlv::kThreadNetworkData, sizeof(networkData), networkData) == OT_ERROR_NONE)
@@ -433,7 +433,12 @@ exit:
}
}
otError Leader::RlocLookup(uint16_t aRloc16, bool &aIn, bool &aStable, uint8_t *aTlvs, uint8_t aTlvsLength)
otError Leader::RlocLookup(uint16_t aRloc16,
bool & aIn,
bool & aStable,
uint8_t *aTlvs,
uint8_t aTlvsLength,
bool aExactMatch)
{
otError error = OT_ERROR_NONE;
NetworkDataTlv * cur = reinterpret_cast<NetworkDataTlv *>(aTlvs);
@@ -479,7 +484,8 @@ otError Leader::RlocLookup(uint16_t aRloc16, bool &aIn, bool &aStable, uint8_t *
{
borderRouterEntry = borderRouter->GetEntry(i);
if (borderRouterEntry->GetRloc() == aRloc16)
if ((aExactMatch && borderRouterEntry->GetRloc() == aRloc16) ||
(!aExactMatch && (Mle::Mle::RouterIdMatch(borderRouterEntry->GetRloc(), aRloc16))))
{
aIn = true;
@@ -499,7 +505,8 @@ otError Leader::RlocLookup(uint16_t aRloc16, bool &aIn, bool &aStable, uint8_t *
{
hasRouteEntry = hasRoute->GetEntry(i);
if (hasRouteEntry->GetRloc() == aRloc16)
if ((aExactMatch && hasRouteEntry->GetRloc() == aRloc16) ||
(!aExactMatch && (Mle::Mle::RouterIdMatch(hasRouteEntry->GetRloc(), aRloc16))))
{
aIn = true;
@@ -548,7 +555,8 @@ otError Leader::RlocLookup(uint16_t aRloc16, bool &aIn, bool &aStable, uint8_t *
server = static_cast<ServerTlv *>(subCur);
VerifyOrExit(server->IsValid(), error = OT_ERROR_PARSE);
if (server->GetServer16() == aRloc16)
if ((aExactMatch && server->GetServer16() == aRloc16) ||
(!aExactMatch && (Mle::Mle::RouterIdMatch(server->GetServer16(), aRloc16))))
{
aIn = true;
@@ -735,7 +743,7 @@ otError Leader::RegisterNetworkData(uint16_t aRloc16, uint8_t *aTlvs, uint8_t aT
uint8_t oldTlvs[NetworkData::kMaxSize];
uint8_t oldTlvsLength = NetworkData::kMaxSize;
RlocLookup(aRloc16, rlocIn, rlocStable, mTlvs, mLength);
RlocLookup(aRloc16, rlocIn, rlocStable, mTlvs, mLength, true);
if (rlocIn)
{
@@ -747,7 +755,7 @@ otError Leader::RegisterNetworkData(uint16_t aRloc16, uint8_t *aTlvs, uint8_t aT
// Store old Service IDs for given rloc16, so updates to server will reuse the same Service ID
SuccessOrExit(error = GetNetworkData(false, oldTlvs, oldTlvsLength));
SuccessOrExit(error = RemoveRloc(aRloc16));
SuccessOrExit(error = RemoveRloc(aRloc16, true));
SuccessOrExit(error = AddNetworkData(aTlvs, aTlvsLength, oldTlvs, oldTlvsLength));
mVersion++;
@@ -759,7 +767,7 @@ otError Leader::RegisterNetworkData(uint16_t aRloc16, uint8_t *aTlvs, uint8_t aT
}
else
{
SuccessOrExit(error = RlocLookup(aRloc16, rlocIn, rlocStable, aTlvs, aTlvsLength));
SuccessOrExit(error = RlocLookup(aRloc16, rlocIn, rlocStable, aTlvs, aTlvsLength, true));
// No old data to be preserved, lets avoid memcpy() & FindService calls.
SuccessOrExit(error = AddNetworkData(aTlvs, aTlvsLength, oldTlvs, 0));
@@ -1191,7 +1199,7 @@ otError Leader::SendServerDataNotification(uint16_t aRloc16)
bool rlocIn = false;
bool rlocStable = false;
RlocLookup(aRloc16, rlocIn, rlocStable, mTlvs, mLength);
RlocLookup(aRloc16, rlocIn, rlocStable, mTlvs, mLength, true);
VerifyOrExit(rlocIn, error = OT_ERROR_NOT_FOUND);
@@ -1201,7 +1209,7 @@ exit:
return error;
}
otError Leader::RemoveRloc(uint16_t aRloc16)
otError Leader::RemoveRloc(uint16_t aRloc16, bool aExactMatch)
{
NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(mTlvs);
NetworkDataTlv *end;
@@ -1224,7 +1232,7 @@ otError Leader::RemoveRloc(uint16_t aRloc16)
case NetworkDataTlv::kTypePrefix:
{
prefix = static_cast<PrefixTlv *>(cur);
RemoveRloc(*prefix, aRloc16);
RemoveRloc(*prefix, aRloc16, aExactMatch);
if (prefix->GetSubTlvsLength() == 0)
{
@@ -1241,7 +1249,7 @@ otError Leader::RemoveRloc(uint16_t aRloc16)
case NetworkDataTlv::kTypeService:
{
service = static_cast<ServiceTlv *>(cur);
RemoveRloc(*service, aRloc16);
RemoveRloc(*service, aRloc16, aExactMatch);
if (service->GetSubTlvsLength() == 0)
{
@@ -1268,7 +1276,7 @@ otError Leader::RemoveRloc(uint16_t aRloc16)
return OT_ERROR_NONE;
}
otError Leader::RemoveRloc(PrefixTlv &prefix, uint16_t aRloc16)
otError Leader::RemoveRloc(PrefixTlv &prefix, uint16_t aRloc16, bool aExactMatch)
{
NetworkDataTlv *cur = prefix.GetSubTlvs();
NetworkDataTlv *end;
@@ -1286,7 +1294,7 @@ otError Leader::RemoveRloc(PrefixTlv &prefix, uint16_t aRloc16)
switch (cur->GetType())
{
case NetworkDataTlv::kTypeHasRoute:
RemoveRloc(prefix, *static_cast<HasRouteTlv *>(cur), aRloc16);
RemoveRloc(prefix, *static_cast<HasRouteTlv *>(cur), aRloc16, aExactMatch);
// remove has route tlv if empty
if (cur->GetLength() == 0)
@@ -1299,7 +1307,7 @@ otError Leader::RemoveRloc(PrefixTlv &prefix, uint16_t aRloc16)
break;
case NetworkDataTlv::kTypeBorderRouter:
RemoveRloc(prefix, *static_cast<BorderRouterTlv *>(cur), aRloc16);
RemoveRloc(prefix, *static_cast<BorderRouterTlv *>(cur), aRloc16, aExactMatch);
// remove border router tlv if empty
if (cur->GetLength() == 0)
@@ -1343,7 +1351,7 @@ otError Leader::RemoveRloc(PrefixTlv &prefix, uint16_t aRloc16)
}
#if OPENTHREAD_ENABLE_SERVICE
otError Leader::RemoveRloc(ServiceTlv &service, uint16_t aRloc16)
otError Leader::RemoveRloc(ServiceTlv &service, uint16_t aRloc16, bool aExactMatch)
{
NetworkDataTlv *cur = service.GetSubTlvs();
NetworkDataTlv *end;
@@ -1364,7 +1372,8 @@ otError Leader::RemoveRloc(ServiceTlv &service, uint16_t aRloc16)
case NetworkDataTlv::kTypeServer:
server = static_cast<ServerTlv *>(cur);
if (server->GetServer16() == aRloc16)
if ((aExactMatch && server->GetServer16() == aRloc16) ||
(!aExactMatch && (Mle::Mle::RouterIdMatch(server->GetServer16(), aRloc16))))
{
removeLength = sizeof(ServerTlv) + server->GetServerDataLength();
service.SetSubTlvsLength(service.GetSubTlvsLength() - removeLength);
@@ -1385,7 +1394,7 @@ otError Leader::RemoveRloc(ServiceTlv &service, uint16_t aRloc16)
}
#endif
otError Leader::RemoveRloc(PrefixTlv &aPrefix, HasRouteTlv &aHasRoute, uint16_t aRloc16)
otError Leader::RemoveRloc(PrefixTlv &aPrefix, HasRouteTlv &aHasRoute, uint16_t aRloc16, bool aExactMatch)
{
HasRouteEntry *entry;
@@ -1394,7 +1403,8 @@ otError Leader::RemoveRloc(PrefixTlv &aPrefix, HasRouteTlv &aHasRoute, uint16_t
{
entry = aHasRoute.GetEntry(i);
if (entry->GetRloc() != aRloc16)
if ((aExactMatch && entry->GetRloc() != aRloc16) ||
(!aExactMatch && !(Mle::Mle::RouterIdMatch(entry->GetRloc(), aRloc16))))
{
continue;
}
@@ -1408,7 +1418,7 @@ otError Leader::RemoveRloc(PrefixTlv &aPrefix, HasRouteTlv &aHasRoute, uint16_t
return OT_ERROR_NONE;
}
otError Leader::RemoveRloc(PrefixTlv &aPrefix, BorderRouterTlv &aBorderRouter, uint16_t aRloc16)
otError Leader::RemoveRloc(PrefixTlv &aPrefix, BorderRouterTlv &aBorderRouter, uint16_t aRloc16, bool aExactMatch)
{
BorderRouterEntry *entry;
@@ -1417,7 +1427,8 @@ otError Leader::RemoveRloc(PrefixTlv &aPrefix, BorderRouterTlv &aBorderRouter, u
{
entry = aBorderRouter.GetEntry(i);
if (entry->GetRloc() != aRloc16)
if ((aExactMatch && entry->GetRloc() != aRloc16) ||
(!aExactMatch && !(Mle::Mle::RouterIdMatch(entry->GetRloc(), aRloc16))))
{
continue;
}
+18 -9
View File
@@ -124,10 +124,13 @@ public:
/**
* This method removes Network Data associated with a given RLOC16.
*
* @param[in] aRloc16 A RLOC16 value.
* @param[in] aRloc16 A RLOC16 value.
* @param[in] aExactMatch Whether exact match or fuzzy match.
* true if to remove only the network data of the @p aRloc16.
* false if to remove the router's and all its children's network data.
*
*/
void RemoveBorderRouter(uint16_t aRloc16);
void RemoveBorderRouter(uint16_t aRloc16, bool aExactMatch);
/**
* This method sends a Server Data Notification message to the Leader indicating an invalid RLOC16.
@@ -180,16 +183,22 @@ private:
otError RemoveCommissioningData(void);
otError RemoveRloc(uint16_t aRloc16);
otError RemoveRloc(PrefixTlv &aPrefix, uint16_t aRloc16);
otError RemoveRloc(uint16_t aRloc16, bool aExactMatch);
otError RemoveRloc(PrefixTlv &aPrefix, uint16_t aRloc16, bool aExactMatch);
#if OPENTHREAD_ENABLE_SERVICE
otError RemoveRloc(ServiceTlv &service, uint16_t aRloc16);
otError RemoveRloc(ServiceTlv &service, uint16_t aRloc16, bool aExactMatch);
#endif
otError RemoveRloc(PrefixTlv &aPrefix, HasRouteTlv &aHasRoute, uint16_t aRloc16);
otError RemoveRloc(PrefixTlv &aPrefix, BorderRouterTlv &aBorderRouter, uint16_t aRloc16);
otError RemoveRloc(PrefixTlv &aPrefix, HasRouteTlv &aHasRoute, uint16_t aRloc16, bool aExactMatch);
otError RemoveRloc(PrefixTlv &aPrefix, BorderRouterTlv &aBorderRouter, uint16_t aRloc16, bool aExactMatch);
otError RlocLookup(uint16_t aRloc16, bool &aIn, bool &aStable, uint8_t *aTlvs, uint8_t aTlvsLength);
bool IsStableUpdated(uint8_t *aTlvs, uint8_t aTlvsLength, uint8_t *aTlvsBase, uint8_t aTlvsBaseLength);
otError RlocLookup(uint16_t aRloc16,
bool & aIn,
bool & aStable,
uint8_t *aTlvs,
uint8_t aTlvsLength,
bool aExactMatch);
bool IsStableUpdated(uint8_t *aTlvs, uint8_t aTlvsLength, uint8_t *aTlvsBase, uint8_t aTlvsBaseLength);
static void HandleCommissioningSet(void * aContext,
otCoapHeader * aHeader,
+1 -1
View File
@@ -289,7 +289,7 @@ otError RouterTable::Release(uint8_t aRouterId)
mRouterIdSequenceLastUpdated = TimerMilli::GetNow();
netif.GetAddressResolver().Remove(aRouterId);
netif.GetNetworkDataLeader().RemoveBorderRouter(rloc16);
netif.GetNetworkDataLeader().RemoveBorderRouter(rloc16, false);
netif.GetMle().ResetAdvertiseInterval();
otLogNoteMle(GetInstance(), "Release router id %d", aRouterId);