From 4a9b611d053f16afddee6ed7e55782eba627efe0 Mon Sep 17 00:00:00 2001 From: Rongli Sun Date: Fri, 30 Aug 2019 23:58:16 +0800 Subject: [PATCH] [core] EID-to-RLOC cache map optimization (#4091) This commit adds EID-to-RLOC map cache entries by inspecting packets received, aiming to reduce RealmLocal multicast AQ when response is expected. --- src/core/thread/address_resolver.cpp | 26 +++++++++++++++++++++++--- src/core/thread/address_resolver.hpp | 23 +++++++++++++++++++---- src/core/thread/mesh_forwarder_ftd.cpp | 18 +++++++++++++++++- 3 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/core/thread/address_resolver.cpp b/src/core/thread/address_resolver.cpp index a38f55b22..f61325123 100644 --- a/src/core/thread/address_resolver.cpp +++ b/src/core/thread/address_resolver.cpp @@ -212,8 +212,10 @@ void AddressResolver::InvalidateCacheEntry(Cache &aEntry, InvalidationReason aRe aEntry.mState = Cache::kStateInvalid; } -void AddressResolver::UpdateCacheEntry(const Ip6::Address &aEid, Mac::ShortAddress aRloc16) +otError AddressResolver::UpdateCacheEntry(const Ip6::Address &aEid, Mac::ShortAddress aRloc16) { + otError error = OT_ERROR_NOT_FOUND; + for (int i = 0; i < kCacheEntries; i++) { if (mCache[i].mState == Cache::kStateInvalid || mCache[i].mTarget != aEid) @@ -240,11 +242,29 @@ void AddressResolver::UpdateCacheEntry(const Ip6::Address &aEid, Mac::ShortAddre otLogNoteArp("Cache entry updated (snoop): %s, 0x%04x", aEid.ToString().AsCString(), aRloc16); } - ExitNow(); + error = OT_ERROR_NONE; } + return error; +} + +otError AddressResolver::AddCacheEntry(const Ip6::Address &aEid, Mac::ShortAddress aRloc16) +{ + otError error = OT_ERROR_NONE; + Cache * entry = NewCacheEntry(); + + VerifyOrExit(entry != NULL, error = OT_ERROR_NO_BUFS); + + entry->mTarget = aEid; + entry->mRloc16 = aRloc16; + entry->mTimeout = 0; + entry->mFailures = 0; + entry->mState = Cache::kStateCached; + + MarkCacheEntryAsUsed(*entry); + exit: - return; + return error; } void AddressResolver::RestartAddressQueries(void) diff --git a/src/core/thread/address_resolver.hpp b/src/core/thread/address_resolver.hpp index 5fa3e4e89..b0b0e089a 100644 --- a/src/core/thread/address_resolver.hpp +++ b/src/core/thread/address_resolver.hpp @@ -103,13 +103,28 @@ public: void Remove(uint8_t aRouterId); /** - * This method updates an existing cache entry for the EID, if one exists. + * This method updates an existing cache entry for the EID. * - * @param[in] aEid A reference to the EID. - * @param[in] aRloc16 The RLOC16 corresponding to @p aEid. + * @param[in] aEid A reference to the EID. + * @param[in] aRloc16 The RLOC16 corresponding to @p aEid. + * + * @retval OT_ERROR_NONE Successfully updates an existing cache entry. + * @retval OT_ERROR_NOT_FOUND No cache entry with @p aEid. * */ - void UpdateCacheEntry(const Ip6::Address &aEid, Mac::ShortAddress aRloc16); + otError UpdateCacheEntry(const Ip6::Address &aEid, Mac::ShortAddress aRloc16); + + /** + * This method adds one cache entry for the EID. + * + * @param[in] aEid A reference to the EID. + * @param[in] aRloc16 The RLOC16 corresponding to @p aEid. + * + * @retval OT_ERROR_NONE Successfully adds one cache entry. + * @retval OT_ERROR_NO_BUFS Insufficient buffer space available to add one cache entry. + * + */ + otError AddCacheEntry(const Ip6::Address &aEid, Mac::ShortAddress aRloc16); /** * This method returns the RLOC16 for a given EID, or initiates an Address Query if the mapping is not known. diff --git a/src/core/thread/mesh_forwarder_ftd.cpp b/src/core/thread/mesh_forwarder_ftd.cpp index 46030e627..1d3143264 100644 --- a/src/core/thread/mesh_forwarder_ftd.cpp +++ b/src/core/thread/mesh_forwarder_ftd.cpp @@ -593,7 +593,23 @@ void MeshForwarder::UpdateRoutes(uint8_t * aFrame, VerifyOrExit(!aMeshDest.IsBroadcast() && aMeshSource.IsShort()); SuccessOrExit(GetIp6Header(aFrame, aFrameLength, aMeshSource, aMeshDest, ip6Header)); - Get().UpdateCacheEntry(ip6Header.GetSource(), aMeshSource.GetShort()); + if (!ip6Header.GetSource().IsRoutingLocator() && !ip6Header.GetSource().IsAnycastRoutingLocator() && + Get().IsOnMesh(ip6Header.GetSource()) /* only for on mesh address which may require AQ */) + { + if (Get().UpdateCacheEntry(ip6Header.GetSource(), aMeshSource.GetShort()) == + OT_ERROR_NOT_FOUND) + { + // Thread 1.1 Specification 5.5.2.2: + // FTDs MAY add/update EID-to-RLOC Map Cache entries by inspecting packets being received. + if ((Get().IsFullThreadDevice() /* only for FTD */ && + !Get().IsMinimalChild(aMeshSource.GetShort()) /* Exclude MTD child source */) && + (aMeshDest.GetShort() == Get().GetShortAddress() || + Get().IsMinimalChild(aMeshDest.GetShort())) /* Received for itself or its MTD child */) + { + Get().AddCacheEntry(ip6Header.GetSource(), aMeshSource.GetShort()); + } + } + } neighbor = Get().GetNeighbor(ip6Header.GetSource()); VerifyOrExit(neighbor != NULL && !neighbor->IsFullThreadDevice());