[mle] clear/update address cache entries on promotion of child to router (#8987)

This commit contains two related changes:
- On a parent, when we detect a former child has been promoted to
  router role by receiving an MLE Advertisement from it, we replace
  the address cache entries associated with the old (child) RLOC16
  with it new RLOC16.
- On leader, when we successfully reply to an "Address Solicit"
  message and assign a new RLOC16 to a node, we clear all entries
  associated with old RLOC16. We do not change to new RLOC16 since we
  cannot be sure that child will successfully receive the Address
  Solicit" response.
This commit is contained in:
Abtin Keshavarzian
2023-04-29 10:41:45 -07:00
committed by GitHub
parent c59eb37c60
commit 34ecac8536
4 changed files with 54 additions and 10 deletions
+19 -3
View File
@@ -163,12 +163,12 @@ exit:
return error;
}
void AddressResolver::Remove(uint8_t aRouterId)
void AddressResolver::RemoveEntriesForRouterId(uint8_t aRouterId)
{
Remove(Mle::Rloc16FromRouterId(aRouterId), /* aMatchRouterId */ true);
}
void AddressResolver::Remove(uint16_t aRloc16) { Remove(aRloc16, /* aMatchRouterId */ false); }
void AddressResolver::RemoveEntriesForRloc16(uint16_t aRloc16) { Remove(aRloc16, /* aMatchRouterId */ false); }
AddressResolver::CacheEntry *AddressResolver::GetEntryAfter(CacheEntry *aPrev, CacheEntryList &aList)
{
@@ -221,7 +221,7 @@ exit:
return entry;
}
void AddressResolver::Remove(const Ip6::Address &aEid) { Remove(aEid, kReasonRemovingEid); }
void AddressResolver::RemoveEntryForAddress(const Ip6::Address &aEid) { Remove(aEid, kReasonRemovingEid); }
void AddressResolver::Remove(const Ip6::Address &aEid, Reason aReason)
{
@@ -239,6 +239,22 @@ exit:
return;
}
void AddressResolver::ReplaceEntriesForRloc16(uint16_t aOldRloc16, uint16_t aNewRloc16)
{
CacheEntryList *lists[] = {&mCachedList, &mSnoopedList};
for (CacheEntryList *list : lists)
{
for (CacheEntry &entry : *list)
{
if (entry.GetRloc16() == aOldRloc16)
{
entry.SetRloc16(aNewRloc16);
}
}
}
}
AddressResolver::CacheEntry *AddressResolver::NewCacheEntry(bool aSnoopedEntry)
{
CacheEntry *newEntry = nullptr;
+12 -3
View File
@@ -139,7 +139,7 @@ public:
* @param[in] aRloc16 The RLOC16 address.
*
*/
void Remove(Mac::ShortAddress aRloc16);
void RemoveEntriesForRloc16(Mac::ShortAddress aRloc16);
/**
* This method removes all EID-to-RLOC cache entries associated with a Router ID.
@@ -147,7 +147,7 @@ public:
* @param[in] aRouterId The Router ID.
*
*/
void Remove(uint8_t aRouterId);
void RemoveEntriesForRouterId(uint8_t aRouterId);
/**
* This method removes the cache entry for the EID.
@@ -155,7 +155,16 @@ public:
* @param[in] aEid A reference to the EID.
*
*/
void Remove(const Ip6::Address &aEid);
void RemoveEntryForAddress(const Ip6::Address &aEid);
/**
* This method replaces all EID-to-RLOC cache entries corresponding to an old RLOC16 with a new RLOC16.
*
* @param[in] aOldRloc16 The old RLOC16.
* @param[in] aNewRloc16 The new RLOC16.
*
*/
void ReplaceEntriesForRloc16(uint16_t aOldRloc16, uint16_t aNewRloc16);
/**
* This method updates an existing entry or adds a snooped cache entry for a given EID.
+21 -2
View File
@@ -1316,6 +1316,10 @@ Error MleRouter::HandleAdvertisement(RxInfo &aRxInfo, uint16_t aSourceAddress, c
DeviceMode::kModeFullNetworkData));
mNeighborTable.Signal(NeighborTable::kRouterAdded, *router);
// Change the cache entries associated with the former child
// from using the old RLOC16 to its new RLOC16.
Get<AddressResolver>().ReplaceEntriesForRloc16(aRxInfo.mNeighbor->GetRloc16(), router->GetRloc16());
}
// Send unicast link request if no link to router and no unicast/multicast link request in progress
@@ -1955,7 +1959,7 @@ Error MleRouter::ProcessAddressRegistrationTlv(RxInfo &aRxInfo, Child &aChild)
}
// Clear EID-to-RLOC cache for the unicast address registered by the child.
Get<AddressResolver>().Remove(address);
Get<AddressResolver>().RemoveEntryForAddress(address);
}
#if OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE
// Dua is removed
@@ -3254,7 +3258,7 @@ void MleRouter::RemoveNeighbor(Neighbor &aNeighbor)
if (aNeighbor.IsFullThreadDevice())
{
// Clear all EID-to-RLOC entries associated with the child.
Get<AddressResolver>().Remove(aNeighbor.GetRloc16());
Get<AddressResolver>().RemoveEntriesForRloc16(aNeighbor.GetRloc16());
}
mChildTable.RemoveStoredChild(static_cast<Child &>(aNeighbor));
@@ -3675,6 +3679,21 @@ void MleRouter::SendAddressSolicitResponse(const Coap::Message &aRequest,
Log(kMessageSend, kTypeAddressReply, aMessageInfo.GetPeerAddr());
// If assigning a new RLOC16 (e.g., on promotion of a child to
// router role) we clear any address cache entries associated
// with the old RLOC16.
if ((aResponseStatus == ThreadStatusTlv::kSuccess) && (aRouter != nullptr))
{
uint16_t oldRloc16;
VerifyOrExit(IsRoutingLocator(aMessageInfo.GetPeerAddr()));
oldRloc16 = aMessageInfo.GetPeerAddr().GetIid().GetLocator();
VerifyOrExit(oldRloc16 != aRouter->GetRloc16());
Get<AddressResolver>().RemoveEntriesForRloc16(oldRloc16);
}
exit:
FreeMessage(message);
}
+2 -2
View File
@@ -216,7 +216,7 @@ Error RouterTable::Release(uint8_t aRouterId)
mRouterIdSequence++;
mRouterIdSequenceLastUpdated = TimerMilli::GetNow();
Get<AddressResolver>().Remove(aRouterId);
Get<AddressResolver>().RemoveEntriesForRouterId(aRouterId);
Get<NetworkData::Leader>().RemoveBorderRouter(Mle::Rloc16FromRouterId(aRouterId),
NetworkData::Leader::kMatchModeRouterId);
Get<Mle::MleRouter>().ResetAdvertiseInterval();
@@ -255,7 +255,7 @@ void RouterTable::RemoveRouterLink(Router &aRouter)
Get<Mle::MleRouter>().ResetAdvertiseInterval();
// Clear all EID-to-RLOC entries associated with the router.
Get<AddressResolver>().Remove(aRouter.GetRouterId());
Get<AddressResolver>().RemoveEntriesForRouterId(aRouter.GetRouterId());
}
}