Skip to content

Commit

Permalink
[mle] clear/update address cache entries on promotion of child to rou…
Browse files Browse the repository at this point in the history
…ter (#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.
  • Loading branch information
abtink committed Apr 29, 2023
1 parent c59eb37 commit 34ecac8
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 10 deletions.
22 changes: 19 additions & 3 deletions src/core/thread/address_resolver.cpp
Expand Up @@ -163,12 +163,12 @@ Error AddressResolver::GetNextCacheEntry(EntryInfo &aInfo, Iterator &aIterator)
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)
{
Expand Down Expand Up @@ -221,7 +221,7 @@ AddressResolver::CacheEntry *AddressResolver::FindCacheEntry(const Ip6::Address
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)
{
Expand All @@ -239,6 +239,22 @@ void AddressResolver::Remove(const Ip6::Address &aEid, Reason aReason)
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;
Expand Down
15 changes: 12 additions & 3 deletions src/core/thread/address_resolver.hpp
Expand Up @@ -139,23 +139,32 @@ class AddressResolver : public InstanceLocator, private NonCopyable
* @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.
*
* @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.
*
* @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.
Expand Down
23 changes: 21 additions & 2 deletions src/core/thread/mle_router.cpp
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions src/core/thread/router_table.cpp
Expand Up @@ -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();
Expand Down Expand Up @@ -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());
}
}

Expand Down

0 comments on commit 34ecac8

Please sign in to comment.