diff --git a/src/core/thread/address_resolver.cpp b/src/core/thread/address_resolver.cpp index 2baa1c044..fda110661 100644 --- a/src/core/thread/address_resolver.cpp +++ b/src/core/thread/address_resolver.cpp @@ -331,6 +331,10 @@ void AddressResolver::RemoveCacheEntry(CacheEntry & aEntry, Error AddressResolver::UpdateCacheEntry(const Ip6::Address &aEid, Mac::ShortAddress aRloc16) { + // This method updates an existing cache entry for the EID (if any). + // Returns `kErrorNone` if entry is found and successfully updated, + // `kErrorNotFound` if no matching entry. + Error error = kErrorNone; CacheEntryList *list; CacheEntry * entry; @@ -365,10 +369,28 @@ exit: return error; } -void AddressResolver::AddSnoopedCacheEntry(const Ip6::Address &aEid, Mac::ShortAddress aRloc16) +void AddressResolver::UpdateSnoopedCacheEntry(const Ip6::Address &aEid, + Mac::ShortAddress aRloc16, + Mac::ShortAddress aDest) { - uint16_t numNonEvictable = 0; - CacheEntry *entry; + uint16_t numNonEvictable = 0; + CacheEntry * entry; + Mac::ShortAddress macAddress; + + VerifyOrExit(Get().IsFullThreadDevice()); + + VerifyOrExit(UpdateCacheEntry(aEid, aRloc16) != kErrorNone); + + // Skip if the `aRloc16` (i.e., the source of the snooped message) + // is this device or an MTD (minimal) child of the device itself. + + macAddress = Get().GetShortAddress(); + VerifyOrExit((aRloc16 != macAddress) && !Get().IsMinimalChild(aRloc16)); + + // Ensure that the destination of the snooped message is this device + // or a minimal child of this device. + + VerifyOrExit((aDest == macAddress) || Get().IsMinimalChild(aDest)); entry = NewCacheEntry(/* aSnoopedEntry */ true); VerifyOrExit(entry != nullptr); diff --git a/src/core/thread/address_resolver.hpp b/src/core/thread/address_resolver.hpp index 853622f59..fe7884205 100644 --- a/src/core/thread/address_resolver.hpp +++ b/src/core/thread/address_resolver.hpp @@ -132,28 +132,17 @@ public: void Remove(const Ip6::Address &aEid); /** - * 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. - * - * @retval kErrorNone Successfully updates an existing cache entry. - * @retval kErrorNotFound No cache entry with @p aEid. - * - */ - Error UpdateCacheEntry(const Ip6::Address &aEid, Mac::ShortAddress aRloc16); - - /** - * This method adds a snooped cache entry for a given EID. + * This method updates an existing entry or adds a snooped cache entry for a given EID. * * The method is intended to add an entry for snoop optimization (inspection of a received message to create a * cache entry mapping an EID to a RLOC). * - * @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. + * @param[in] aDest The short MAC address destination of the received snooped message. * */ - void AddSnoopedCacheEntry(const Ip6::Address &aEid, Mac::ShortAddress aRloc16); + void UpdateSnoopedCacheEntry(const Ip6::Address &aEid, Mac::ShortAddress aRloc16, Mac::ShortAddress aDest); /** * This method returns the RLOC16 for a given EID, initiates an Address Query if allowed and the mapping is not @@ -313,6 +302,7 @@ private: CacheEntry *FindCacheEntry(const Ip6::Address &aEid, CacheEntryList *&aList, CacheEntry *&aPrevEntry); CacheEntry *NewCacheEntry(bool aSnoopedEntry); void RemoveCacheEntry(CacheEntry &aEntry, CacheEntryList &aList, CacheEntry *aPrevEntry, Reason aReason); + Error UpdateCacheEntry(const Ip6::Address &aEid, Mac::ShortAddress aRloc16); Error SendAddressQuery(const Ip6::Address &aEid); diff --git a/src/core/thread/mesh_forwarder_ftd.cpp b/src/core/thread/mesh_forwarder_ftd.cpp index 4581e9300..ed3688f33 100644 --- a/src/core/thread/mesh_forwarder_ftd.cpp +++ b/src/core/thread/mesh_forwarder_ftd.cpp @@ -819,22 +819,11 @@ void MeshForwarder::UpdateRoutes(const uint8_t * aFrame, if (!ip6Header.GetSource().GetIid().IsLocator() && Get().IsOnMesh(ip6Header.GetSource()) /* only for on mesh address which may require AQ */) { - if (Get().UpdateCacheEntry(ip6Header.GetSource(), aMeshSource.GetShort()) == kErrorNotFound) - { - // Thread 1.1 Specification 5.5.2.2: FTDs MAY add/update - // EID-to-RLOC Map Cache entries by inspecting packets - // being received. We exclude frames from an MTD child - // source and verify that the destination is the device - // itself or an MTD child of the device. + // FTDs MAY add/update EID-to-RLOC Map Cache entries by + // inspecting packets being received. - if (Get().IsFullThreadDevice() && - !Get().IsMinimalChild(aMeshSource.GetShort()) && - (aMeshDest.GetShort() == Get().GetShortAddress() || - Get().IsMinimalChild(aMeshDest.GetShort()))) - { - Get().AddSnoopedCacheEntry(ip6Header.GetSource(), aMeshSource.GetShort()); - } - } + Get().UpdateSnoopedCacheEntry(ip6Header.GetSource(), aMeshSource.GetShort(), + aMeshDest.GetShort()); } neighbor = Get().FindNeighbor(ip6Header.GetSource());