diff --git a/include/openthread/instance.h b/include/openthread/instance.h index 562d5b961..1497359cf 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -52,7 +52,7 @@ extern "C" { * * @note This number versions both OpenThread platform and user APIs. */ -#define OPENTHREAD_API_VERSION (579) +#define OPENTHREAD_API_VERSION (580) /** * @addtogroup api-instance diff --git a/include/openthread/ip6.h b/include/openthread/ip6.h index 889451cb9..f6a9d3ed5 100644 --- a/include/openthread/ip6.h +++ b/include/openthread/ip6.h @@ -163,10 +163,10 @@ typedef struct otIp6Prefix otIp6Prefix; */ enum { - OT_ADDRESS_ORIGIN_THREAD = 0, ///< Thread assigned address (ALOC, RLOC, MLEID, etc) - OT_ADDRESS_ORIGIN_SLAAC = 1, ///< SLAAC assigned address - OT_ADDRESS_ORIGIN_DHCPV6 = 2, ///< DHCPv6 assigned address - OT_ADDRESS_ORIGIN_MANUAL = 3, ///< Manually assigned address + OT_ADDRESS_ORIGIN_THREAD = 0, ///< Thread assigned (ALOC, RLOC, MLEID, etc.) + OT_ADDRESS_ORIGIN_SLAAC = 1, ///< SLAAC assigned (used in `otNetifAddress` and not in `otNetifMulticastAddress`). + OT_ADDRESS_ORIGIN_DHCPV6 = 2, ///< DHCPv6 assigned (used in `otNetifAddress` and not in `otNetifMulticastAddress`). + OT_ADDRESS_ORIGIN_MANUAL = 3, ///< Manually assigned address. }; /** @@ -176,7 +176,7 @@ typedef struct otNetifAddress { otIp6Address mAddress; ///< The IPv6 unicast address. uint8_t mPrefixLength; ///< The Prefix length (in bits). - uint8_t mAddressOrigin; ///< The IPv6 address origin. + uint8_t mAddressOrigin; ///< The IPv6 address origin (OT_ADDRESS_ORIGIN_* values). bool mPreferred : 1; ///< TRUE if the address is preferred, FALSE otherwise. bool mValid : 1; ///< TRUE if the address is valid, FALSE otherwise. bool mScopeOverrideValid : 1; ///< TRUE if the mScopeOverride value is valid, FALSE otherwise. @@ -189,11 +189,25 @@ typedef struct otNetifAddress /** * Represents an IPv6 network interface multicast address. + * + * The `mAddressOrigin` field is set to either `OT_ADDRESS_ORIGIN_THREAD` if the multicast address is subscribed by + * OpenThread core or `OT_ADDRESS_ORIGIN_MANUAL` if it is subscribed manually using `otIp6SubscribeMulticastAddress()`. + * + * The multicast addresses subscribed by OpenThread core include addresses such as + * - link-local all nodes (`ff02::01`), + * - realm-local all nodes (`ff03::01`), + * - link-local all routers (`ff02::02`), + * - realm-local all routers (`ff03::02`), + * - realm-local all MPL forwarders (`ff03::fc`), + * - link-local all Thread nodes, + * - realm-local all Thread nodes. */ typedef struct otNetifMulticastAddress { - otIp6Address mAddress; ///< The IPv6 multicast address. - const struct otNetifMulticastAddress *mNext; ///< A pointer to the next network interface multicast address. + otIp6Address mAddress; ///< The IPv6 multicast address. + const struct otNetifMulticastAddress *mNext; ///< A pointer to the next multicast address. + uint8_t mAddressOrigin; ///< The multicast address origin. + uint8_t mData; ///< Opaque data used by OpenThread core. } otNetifMulticastAddress; /** diff --git a/src/core/net/ip6_address.cpp b/src/core/net/ip6_address.cpp index 7fa14222a..8c598bf36 100644 --- a/src/core/net/ip6_address.cpp +++ b/src/core/net/ip6_address.cpp @@ -420,31 +420,6 @@ uint8_t Address::PrefixMatch(const Address &aOther) const return static_cast(CountMatchingBits(mFields.m8, aOther.mFields.m8, BitSizeOf(Address))); } -bool Address::MatchesFilter(TypeFilter aFilter) const -{ - bool matches = true; - - switch (aFilter) - { - case kTypeAny: - break; - - case kTypeUnicast: - matches = !IsUnspecified() && !IsMulticast(); - break; - - case kTypeMulticast: - matches = IsMulticast(); - break; - - case kTypeMulticastLargerThanRealmLocal: - matches = IsMulticastLargerThanRealmLocal(); - break; - } - - return matches; -} - void Address::SynthesizeFromIp4Address(const Prefix &aPrefix, const Ip4::Address &aIp4Address) { // The prefix length must be 32, 40, 48, 56, 64, 96. IPv4 bytes are added diff --git a/src/core/net/ip6_address.hpp b/src/core/net/ip6_address.hpp index 82eeea40e..ffe73dc05 100644 --- a/src/core/net/ip6_address.hpp +++ b/src/core/net/ip6_address.hpp @@ -526,17 +526,6 @@ public: static constexpr uint8_t kOrgLocalScope = 8; ///< Organization-Local scope static constexpr uint8_t kGlobalScope = 14; ///< Global scope - /** - * Defines IPv6 address type filter. - */ - enum TypeFilter : uint8_t - { - kTypeAny, ///< Accept any IPv6 address (unicast or multicast). - kTypeUnicast, ///< Accept unicast IPv6 addresses only. - kTypeMulticast, ///< Accept multicast IPv6 addresses only. - kTypeMulticastLargerThanRealmLocal, ///< Accept multicast IPv6 addresses with scope larger than Realm Local. - }; - /** * Defines the fixed-length `String` object returned from `ToString()`. */ @@ -849,16 +838,6 @@ public: */ uint8_t PrefixMatch(const Address &aOther) const; - /** - * Indicates whether address matches a given type filter. - * - * @param[in] aFilter An address type filter. - * - * @retval TRUE The address matches @p aFilter. - * @retval FALSE The address does not match @p aFilter. - */ - bool MatchesFilter(TypeFilter aFilter) const; - /** * Sets the IPv6 address by performing NAT64 address translation from a given IPv4 address as specified * in RFC 6052. diff --git a/src/core/net/netif.cpp b/src/core/net/netif.cpp index 605451da4..d17567a41 100644 --- a/src/core/net/netif.cpp +++ b/src/core/net/netif.cpp @@ -52,27 +52,37 @@ namespace Ip6 { // "ff03::fc" const otNetifMulticastAddress Netif::kRealmLocalAllMplForwardersMulticastAddress = { {{{0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc}}}, - nullptr}; + nullptr, + kOriginThread, + 0}; // "ff03::01" const otNetifMulticastAddress Netif::kRealmLocalAllNodesMulticastAddress = { {{{0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}}, - &Netif::kRealmLocalAllMplForwardersMulticastAddress}; + &Netif::kRealmLocalAllMplForwardersMulticastAddress, + Netif::kOriginThread, + 0}; // "ff02::01" const otNetifMulticastAddress Netif::kLinkLocalAllNodesMulticastAddress = { {{{0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}}, - &Netif::kRealmLocalAllNodesMulticastAddress}; + &Netif::kRealmLocalAllNodesMulticastAddress, + Netif::kOriginThread, + 0}; // "ff03::02" const otNetifMulticastAddress Netif::kRealmLocalAllRoutersMulticastAddress = { {{{0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}}}, - &Netif::kLinkLocalAllNodesMulticastAddress}; + &Netif::kLinkLocalAllNodesMulticastAddress, + Netif::kOriginThread, + 0}; // "ff02::02" const otNetifMulticastAddress Netif::kLinkLocalAllRoutersMulticastAddress = { {{{0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}}}, - &Netif::kRealmLocalAllRoutersMulticastAddress}; + &Netif::kRealmLocalAllRoutersMulticastAddress, + Netif::kOriginThread, + 0}; //--------------------------------------------------------------------------------------------------------------------- // Netif @@ -230,15 +240,15 @@ exit: return; } -void Netif::SignalMulticastAddressChange(AddressEvent aEvent, const MulticastAddress &aAddress, AddressOrigin aOrigin) +void Netif::SignalMulticastAddressChange(AddressEvent aEvent, const MulticastAddress &aAddress) { Get().Signal(aEvent == kAddressAdded ? kEventIp6MulticastSubscribed : kEventIp6MulticastUnsubscribed); #if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE - Get().RecordAddressEvent(aEvent, aAddress, aOrigin); + Get().RecordAddressEvent(aEvent, aAddress); #endif - if ((aOrigin == kOriginThread) && mAddressCallback.IsSet()) + if ((aAddress.GetOrigin() == kOriginThread) && mAddressCallback.IsSet()) { AddressInfo info; @@ -261,19 +271,14 @@ void Netif::SignalMulticastAddressesChange(AddressEvent aEvent, for (const MulticastAddress *entry = aStart; entry != aEnd; entry = entry->GetNext()) { - SignalMulticastAddressChange(aEvent, *entry, kOriginThread); + SignalMulticastAddressChange(aEvent, *entry); } } -bool Netif::IsMulticastAddressExternal(const MulticastAddress &aAddress) const -{ - return mExtMulticastAddressPool.IsPoolEntry(static_cast(aAddress)); -} - void Netif::SubscribeMulticast(MulticastAddress &aAddress) { SuccessOrExit(mMulticastAddresses.Add(aAddress)); - SignalMulticastAddressChange(kAddressAdded, aAddress, kOriginThread); + SignalMulticastAddressChange(kAddressAdded, aAddress); exit: return; @@ -282,7 +287,7 @@ exit: void Netif::UnsubscribeMulticast(const MulticastAddress &aAddress) { SuccessOrExit(mMulticastAddresses.Remove(aAddress)); - SignalMulticastAddressChange(kAddressRemoved, aAddress, kOriginThread); + SignalMulticastAddressChange(kAddressRemoved, aAddress); exit: return; @@ -292,7 +297,7 @@ Error Netif::SubscribeExternalMulticast(const Address &aAddress) { Error error = kErrorNone; MulticastAddress &linkLocalAllRoutersAddress = AsCoreType(&AsNonConst(kLinkLocalAllRoutersMulticastAddress)); - ExternalMulticastAddress *entry; + MulticastAddress *entry; VerifyOrExit(aAddress.IsMulticast(), error = kErrorInvalidArgs); VerifyOrExit(!IsMulticastSubscribed(aAddress), error = kErrorAlready); @@ -309,13 +314,12 @@ Error Netif::SubscribeExternalMulticast(const Address &aAddress) entry = mExtMulticastAddressPool.Allocate(); VerifyOrExit(entry != nullptr, error = kErrorNoBufs); + entry->InitAsManualOrigin(); entry->mAddress = aAddress; -#if OPENTHREAD_CONFIG_MLR_ENABLE - entry->mMlrState = kMlrStateToRegister; -#endif + mMulticastAddresses.Push(*entry); - SignalMulticastAddressChange(kAddressAdded, *entry, kOriginManual); + SignalMulticastAddressChange(kAddressAdded, *entry); exit: return error; @@ -330,13 +334,13 @@ Error Netif::UnsubscribeExternalMulticast(const Address &aAddress) entry = mMulticastAddresses.FindMatchingWithPrev(prev, aAddress); VerifyOrExit(entry != nullptr, error = kErrorNotFound); - VerifyOrExit(IsMulticastAddressExternal(*entry), error = kErrorRejected); + VerifyOrExit(entry->GetOrigin() == kOriginManual, error = kErrorRejected); mMulticastAddresses.PopAfter(prev); - SignalMulticastAddressChange(kAddressRemoved, *entry, kOriginManual); + SignalMulticastAddressChange(kAddressRemoved, *entry); - mExtMulticastAddressPool.Free(static_cast(*entry)); + mExtMulticastAddressPool.Free(*entry); exit: return error; @@ -350,7 +354,7 @@ void Netif::UnsubscribeAllExternalMulticastAddresses(void) { next = entry->GetNext(); - if (IsMulticastAddressExternal(*entry)) + if (entry->GetOrigin() == kOriginManual) { IgnoreError(UnsubscribeExternalMulticast(entry->GetAddress())); } @@ -511,6 +515,8 @@ bool Netif::IsUnicastAddressExternal(const UnicastAddress &aAddress) const return mExtUnicastAddressPool.IsPoolEntry(aAddress); } +bool Netif::HasAnyExternalMulticastAddress(void) const { return mMulticastAddresses.ContainsMatching(kOriginManual); } + void Netif::ApplyNewMeshLocalPrefix(void) { for (UnicastAddress &address : mUnicastAddresses) @@ -528,9 +534,9 @@ void Netif::ApplyNewMeshLocalPrefix(void) { if (Get().IsMulticastAddressMeshLocalPrefixBased(address)) { - SignalMulticastAddressChange(kAddressRemoved, address, kOriginThread); + SignalMulticastAddressChange(kAddressRemoved, address); address.GetAddress().SetMulticastNetworkPrefix(Get().GetMeshLocalPrefix()); - SignalMulticastAddressChange(kAddressAdded, address, kOriginThread); + SignalMulticastAddressChange(kAddressAdded, address); } } } @@ -572,26 +578,38 @@ void Netif::UnicastAddress::InitAsSlaacOrigin(uint8_t aPrefixLength, bool aPrefe } //--------------------------------------------------------------------------------------------------------------------- -// Netif::ExternalMulticastAddress::Iterator +// Netif::MulticastAddress -Netif::ExternalMulticastAddress::Iterator::Iterator(const Netif &aNetif, Address::TypeFilter aFilter) - : ItemPtrIterator(nullptr) - , mNetif(aNetif) - , mFilter(aFilter) +void Netif::MulticastAddress::InitAsThreadOrigin(void) { - AdvanceFrom(mNetif.GetMulticastAddresses().GetHead()); + Clear(); + mAddressOrigin = kOriginThread; } -void Netif::ExternalMulticastAddress::Iterator::AdvanceFrom(const MulticastAddress *aAddr) +void Netif::MulticastAddress::InitAsManualOrigin(void) { - while (aAddr != nullptr && - !(mNetif.IsMulticastAddressExternal(*aAddr) && aAddr->GetAddress().MatchesFilter(mFilter))) - { - aAddr = aAddr->GetNext(); - } + Clear(); + mAddressOrigin = kOriginManual; - mItem = AsNonConst(static_cast(aAddr)); +#if OPENTHREAD_CONFIG_MLR_ENABLE + // Make sure `Clear()` sets the "MlrState" to `kMlrStateToRegister` value. + static_assert(kMlrStateToRegister == 0, "kMlrStateToRegister is not correct."); +#endif } +#if OPENTHREAD_CONFIG_MLR_ENABLE + +bool Netif::MulticastAddress::IsMlrCandidate(void) const +{ + return (GetOrigin() == kOriginManual) && GetAddress().IsMulticastLargerThanRealmLocal(); +} + +bool Netif::MulticastAddress::Matches(MlrState aMlrState) const +{ + return IsMlrCandidate() && (GetMlrState() == aMlrState); +} + +#endif + } // namespace Ip6 } // namespace ot diff --git a/src/core/net/netif.hpp b/src/core/net/netif.hpp index 3581af5c0..1bde35b73 100644 --- a/src/core/net/netif.hpp +++ b/src/core/net/netif.hpp @@ -232,6 +232,16 @@ public: friend class LinkedList; public: + /** + * Clears and initializes the multicast address as a thread-origin address. + */ + void InitAsThreadOrigin(void); + + /** + * Clears and initializes the multicast address as a manual-origin address. + */ + void InitAsManualOrigin(void); + /** * Returns the multicast address. * @@ -246,6 +256,13 @@ public: */ Address &GetAddress(void) { return AsCoreType(&mAddress); } + /** + * Gets the IPv6 address origin. + * + * @returns The address origin. + */ + AddressOrigin GetOrigin(void) const { return static_cast(mAddressOrigin); } + /** * Returns the next multicast address subscribed to the interface. * @@ -260,91 +277,46 @@ public: */ MulticastAddress *GetNext(void) { return static_cast(AsNonConst(mNext)); } - private: - bool Matches(const Address &aAddress) const { return GetAddress() == aAddress; } - }; - - class ExternalMulticastAddress : public MulticastAddress - { - friend class Netif; - friend class LinkedList; - - public: - /** - * Represents an iterator for iterating external multicast addresses in a `Netif` instance. - */ - class Iterator : public ItemPtrIterator - { - friend class ItemPtrIterator; - friend class Netif; - - public: - /** - * Initializes an `Iterator` instance to start from the first external multicast address - * that matches a given IPv6 address type filter. - * - * @param[in] aNetif A reference to the `Netif` instance. - * @param[in] aFilter The IPv6 address type filter. - */ - explicit Iterator(const Netif &aNetif, Address::TypeFilter aFilter = Address::kTypeAny); - - private: - class Builder - { - public: - Builder(const Netif &aNetif, Address::TypeFilter aFilter) - : mNetif(aNetif) - , mFilter(aFilter) - { - } - - Iterator begin(void) { return Iterator(mNetif, mFilter); } - Iterator end(void) { return Iterator(mNetif, Iterator::kEndIterator); } - - private: - const Netif &mNetif; - Address::TypeFilter mFilter; - }; - - enum IteratorType : uint8_t - { - kEndIterator, - }; - - Iterator(const Netif &aNetif, IteratorType) - : mNetif(aNetif) - { - } - - void AdvanceFrom(const MulticastAddress *aAddr); - void Advance(void) { AdvanceFrom(mItem->GetNext()); } - - const Netif &mNetif; - Address::TypeFilter mFilter; - }; - #if OPENTHREAD_CONFIG_MLR_ENABLE + /** + * Indicates whether or not the address is a Multicast Listener Registration (MLR) candidate. + * + * An address is an MLR candidate if it is an external address (origin `kOriginManual`) and its scope + * is larger than realm-local. + * + * @retval TRUE If the address is an MLR candidate. + * @retval FALSE If the address is not an MLR candidate. + */ + bool IsMlrCandidate(void) const; + /** * Returns the current Multicast Listener Registration (MLR) state. * * @returns The current Multicast Listener Registration state. */ - MlrState GetMlrState(void) const { return mMlrState; } + MlrState GetMlrState(void) const { return static_cast(mData); } /** * Sets the Multicast Listener Registration (MLR) state. * * @param[in] aState The new Multicast Listener Registration state. */ - void SetMlrState(MlrState aState) { mMlrState = aState; } + void SetMlrState(MlrState aState) { mData = aState; } + + /** + * Indicates whether or not the address is an MLR candidate and matches a given MLR state. + * + * @param[in] aMlrState The MLR state to match against. + * + * @retval TRUE If the address is an MLR candidate and its state matches @p aMlrState. + * @retval FALSE If the address is not an MLR candidate or its state does not match @p aMlrState. + */ + bool Matches(MlrState aMlrState) const; #endif private: - ExternalMulticastAddress *GetNext(void) { return static_cast(AsNonConst(mNext)); } - -#if OPENTHREAD_CONFIG_MLR_ENABLE - MlrState mMlrState; -#endif + bool Matches(const Address &aAddress) const { return GetAddress() == aAddress; } + bool Matches(AddressOrigin aOrigin) const { return GetOrigin() == aOrigin; } }; /** @@ -506,14 +478,11 @@ public: const LinkedList &GetMulticastAddresses(void) const { return mMulticastAddresses; } /** - * Indicates whether a multicast address is an external or internal address. + * Returns the linked list of multicast addresses. * - * @param[in] aAddress A reference to the multicast address. - * - * @retval TRUE The address is an external address. - * @retval FALSE The address is not an external address (it is an OpenThread internal address). + * @returns The linked list of multicast addresses. */ - bool IsMulticastAddressExternal(const MulticastAddress &aAddress) const; + LinkedList &GetMulticastAddresses(void) { return mMulticastAddresses; } /** * Subscribes the network interface to a multicast address. @@ -570,37 +539,12 @@ public: void UnsubscribeAllExternalMulticastAddresses(void); /** - * Enables range-based `for` loop iteration over external multicast addresses on the Netif that matches - * a given IPv6 address type filter. - * - * Should be used like follows: to iterate over all external multicast addresses - * - * for (Ip6::Netif::ExternalMulticastAddress &addr : Get().IterateExternalMulticastAddresses()) - * { ... } - * - * or to iterate over a subset of external multicast addresses determined by a given address type filter - * - * for (Ip6::Netif::ExternalMulticastAddress &addr : - * Get().IterateExternalMulticastAddresses(Ip6::Address::kTypeMulticastLargerThanRealmLocal)) - * { ... } - * - * @param[in] aFilter The IPv6 address type filter. - * - * @returns An `ExternalMulticastAddress::Iterator::Builder` instance. - */ - ExternalMulticastAddress::Iterator::Builder IterateExternalMulticastAddresses( - Address::TypeFilter aFilter = Address::kTypeAny) - { - return ExternalMulticastAddress::Iterator::Builder(*this, aFilter); - } - - /** - * Indicates whether or not the network interfaces is subscribed to any external multicast address. + * Indicates whether or not the network interface is subscribed to any external multicast address. * * @retval TRUE The network interface is subscribed to at least one external multicast address. * @retval FALSE The network interface is not subscribed to any external multicast address. */ - bool HasAnyExternalMulticastAddress(void) const { return !ExternalMulticastAddress::Iterator(*this).IsDone(); } + bool HasAnyExternalMulticastAddress(void) const; /** * Applies the new mesh local prefix. @@ -625,12 +569,15 @@ protected: void UnsubscribeAllNodesMulticast(void); private: - typedef otIp6AddressInfo AddressInfo; + static constexpr uint16_t kMaxExtUnicastAddrs = OPENTHREAD_CONFIG_IP6_MAX_EXT_UCAST_ADDRS; + static constexpr uint16_t kMaxExtMulticastAddrs = OPENTHREAD_CONFIG_IP6_MAX_EXT_MCAST_ADDRS; static constexpr uint8_t kMulticastPrefixLength = 128; // Multicast prefix length used in `AdressInfo`. + typedef otIp6AddressInfo AddressInfo; + void SignalUnicastAddressChange(AddressEvent aEvent, const UnicastAddress &aAddress); - void SignalMulticastAddressChange(AddressEvent aEvent, const MulticastAddress &aAddress, AddressOrigin aOrigin); + void SignalMulticastAddressChange(AddressEvent aEvent, const MulticastAddress &aAddress); void SignalMulticastAddressesChange(AddressEvent aEvent, const MulticastAddress *aStart, const MulticastAddress *aEnd); @@ -640,8 +587,8 @@ private: Callback mAddressCallback; - Pool mExtUnicastAddressPool; - Pool mExtMulticastAddressPool; + Pool mExtUnicastAddressPool; + Pool mExtMulticastAddressPool; static const otNetifMulticastAddress kRealmLocalAllMplForwardersMulticastAddress; static const otNetifMulticastAddress kLinkLocalAllNodesMulticastAddress; diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 43bae8e6e..8770714a1 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -127,11 +127,11 @@ Mle::Mle(Instance &aInstance) mMeshLocalRloc.GetAddress().GetIid().SetToLocator(0); mMeshLocalRloc.mRloc = true; - mLinkLocalAllThreadNodes.Clear(); + mLinkLocalAllThreadNodes.InitAsThreadOrigin(); mLinkLocalAllThreadNodes.GetAddress().mFields.m16[0] = BigEndian::HostSwap16(0xff32); mLinkLocalAllThreadNodes.GetAddress().mFields.m16[7] = BigEndian::HostSwap16(0x0001); - mRealmLocalAllThreadNodes.Clear(); + mRealmLocalAllThreadNodes.InitAsThreadOrigin(); mRealmLocalAllThreadNodes.GetAddress().mFields.m16[0] = BigEndian::HostSwap16(0xff33); mRealmLocalAllThreadNodes.GetAddress().mFields.m16[7] = BigEndian::HostSwap16(0x0001); @@ -3637,8 +3637,13 @@ Error Mle::TxMessage::AppendAddressRegistrationTlv(AddressRegistrationMode aMode if (Get().ShouldRegisterMulticastAddrsWithParent()) { - for (const Ip6::Netif::MulticastAddress &addr : Get().IterateExternalMulticastAddresses()) + for (const Ip6::Netif::MulticastAddress &addr : Get().GetMulticastAddresses()) { + if (addr.GetOrigin() != Ip6::Netif::kOriginManual) + { + continue; + } + #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) // For Thread 1.2 MED, skip multicast address with scope not // larger than realm local when registering. diff --git a/src/core/thread/mlr_manager.cpp b/src/core/thread/mlr_manager.cpp index 9786ff0c0..096ab7a87 100644 --- a/src/core/thread/mlr_manager.cpp +++ b/src/core/thread/mlr_manager.cpp @@ -84,10 +84,9 @@ void MlrManager::UpdateLocalSubscriptions(void) { #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE // Check multicast addresses are newly listened against Children - for (Ip6::Netif::ExternalMulticastAddress &addr : - Get().IterateExternalMulticastAddresses(Ip6::Address::kTypeMulticastLargerThanRealmLocal)) + for (Ip6::Netif::MulticastAddress &addr : Get().GetMulticastAddresses()) { - if (addr.GetMlrState() == kMlrStateToRegister && IsAddressMlrRegisteredByAnyChild(addr.GetAddress())) + if (addr.Matches(kMlrStateToRegister) && IsAddressMlrRegisteredByAnyChild(addr.GetAddress())) { addr.SetMlrState(kMlrStateRegistered); } @@ -104,15 +103,15 @@ bool MlrManager::IsAddressMlrRegisteredByNetif(const Ip6::Address &aAddress) con OT_ASSERT(aAddress.IsMulticastLargerThanRealmLocal()); - for (const Ip6::Netif::ExternalMulticastAddress &addr : Get().IterateExternalMulticastAddresses()) + for (const Ip6::Netif::MulticastAddress &addr : Get().GetMulticastAddresses()) { - if (addr.GetAddress() == aAddress && addr.GetMlrState() == kMlrStateRegistered) + if (addr.Matches(kMlrStateRegistered) && (addr.GetAddress() == aAddress)) { - ExitNow(ret = true); + ret = true; + break; } } -exit: return ret; } @@ -222,15 +221,14 @@ void MlrManager::SendMlr(void) #if OPENTHREAD_CONFIG_MLR_ENABLE // Append Netif multicast addresses - for (Ip6::Netif::ExternalMulticastAddress &addr : - Get().IterateExternalMulticastAddresses(Ip6::Address::kTypeMulticastLargerThanRealmLocal)) + for (Ip6::Netif::MulticastAddress &addr : Get().GetMulticastAddresses()) { if (addresses.IsFull()) { break; } - if (addr.GetMlrState() == kMlrStateToRegister) + if (addr.Matches(kMlrStateToRegister)) { addresses.AddUnique(addr.GetAddress()); addr.SetMlrState(kMlrStateRegistering); @@ -478,10 +476,9 @@ exit: void MlrManager::SetMulticastAddressMlrState(MlrState aFromState, MlrState aToState) { #if OPENTHREAD_CONFIG_MLR_ENABLE - for (Ip6::Netif::ExternalMulticastAddress &addr : - Get().IterateExternalMulticastAddresses(Ip6::Address::kTypeMulticastLargerThanRealmLocal)) + for (Ip6::Netif::MulticastAddress &addr : Get().GetMulticastAddresses()) { - if (addr.GetMlrState() == aFromState) + if (addr.Matches(aFromState)) { addr.SetMlrState(aToState); } @@ -513,10 +510,9 @@ void MlrManager::FinishMlr(bool aSuccess, const AddressArray &aFailedAddresses) mMlrPending = false; #if OPENTHREAD_CONFIG_MLR_ENABLE - for (Ip6::Netif::ExternalMulticastAddress &addr : - Get().IterateExternalMulticastAddresses(Ip6::Address::kTypeMulticastLargerThanRealmLocal)) + for (Ip6::Netif::MulticastAddress &addr : Get().GetMulticastAddresses()) { - if (addr.GetMlrState() == kMlrStateRegistering) + if (addr.Matches(kMlrStateRegistering)) { bool success = aSuccess || !aFailedAddresses.IsEmptyOrContains(addr.GetAddress()); @@ -625,8 +621,13 @@ void MlrManager::LogMulticastAddresses(void) LogDebg("-------- Multicast Addresses --------"); #if OPENTHREAD_CONFIG_MLR_ENABLE - for (const Ip6::Netif::ExternalMulticastAddress &addr : Get().IterateExternalMulticastAddresses()) + for (const Ip6::Netif::MulticastAddress &addr : Get().GetMulticastAddresses()) { + if (!addr.IsMlrCandidate()) + { + continue; + } + LogDebg("%-32s%c", addr.GetAddress().ToString().AsCString(), "-rR"[addr.GetMlrState()]); } #endif @@ -693,10 +694,12 @@ void MlrManager::CheckInvariants(void) const OT_ASSERT(!mMlrPending || mSendDelay == 0); #if OPENTHREAD_CONFIG_MLR_ENABLE - for (Ip6::Netif::ExternalMulticastAddress &addr : - Get().IterateExternalMulticastAddresses(Ip6::Address::kTypeMulticastLargerThanRealmLocal)) + for (Ip6::Netif::MulticastAddress &addr : Get().GetMulticastAddresses()) { - registeringNum += (addr.GetMlrState() == kMlrStateRegistering); + if (addr.Matches(kMlrStateRegistering)) + { + registeringNum++; + } } #endif #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE diff --git a/src/core/utils/history_tracker.cpp b/src/core/utils/history_tracker.cpp index 9a3183a7f..bddb21dbe 100644 --- a/src/core/utils/history_tracker.cpp +++ b/src/core/utils/history_tracker.cpp @@ -261,16 +261,14 @@ exit: return; } -void Local::RecordAddressEvent(Ip6::Netif::AddressEvent aEvent, - const Ip6::Netif::MulticastAddress &aMulticastAddress, - Ip6::Netif::AddressOrigin aAddressOrigin) +void Local::RecordAddressEvent(Ip6::Netif::AddressEvent aEvent, const Ip6::Netif::MulticastAddress &aMulticastAddress) { MulticastAddressInfo *entry = mMulticastAddressHistory.AddNewEntry(); VerifyOrExit(entry != nullptr); entry->mAddress = aMulticastAddress.GetAddress(); - entry->mAddressOrigin = aAddressOrigin; + entry->mAddressOrigin = aMulticastAddress.GetOrigin(); entry->mEvent = (aEvent == Ip6::Netif::kAddressAdded) ? kAddressAdded : kAddressRemoved; exit: diff --git a/src/core/utils/history_tracker.hpp b/src/core/utils/history_tracker.hpp index 5857e9eee..654c73bd5 100644 --- a/src/core/utils/history_tracker.hpp +++ b/src/core/utils/history_tracker.hpp @@ -515,9 +515,7 @@ private: bool aIsTxSuccess = true); void RecordNeighborEvent(NeighborTable::Event aEvent, const NeighborTable::EntryInfo &aInfo); void RecordAddressEvent(Ip6::Netif::AddressEvent aEvent, const Ip6::Netif::UnicastAddress &aUnicastAddress); - void RecordAddressEvent(Ip6::Netif::AddressEvent aEvent, - const Ip6::Netif::MulticastAddress &aMulticastAddress, - Ip6::Netif::AddressOrigin aAddressOrigin); + void RecordAddressEvent(Ip6::Netif::AddressEvent aEvent, const Ip6::Netif::MulticastAddress &aMulticastAddress); void HandleNotifierEvents(Events aEvents); void HandleTimer(void); #if OPENTHREAD_FTD diff --git a/tests/unit/test_child.cpp b/tests/unit/test_child.cpp index a7a0874db..ccecdc22d 100644 --- a/tests/unit/test_child.cpp +++ b/tests/unit/test_child.cpp @@ -46,9 +46,8 @@ enum void VerifyChildIp6Addresses(const Child &aChild, uint8_t aAddressListLength, const Ip6::Address aAddressList[]) { - Ip6::Address::TypeFilter filters[] = {Ip6::Address::kTypeUnicast, Ip6::Address::kTypeMulticast}; - bool addressObserved[kMaxChildIp6Addresses]; - bool hasMeshLocal = false; + bool addressObserved[kMaxChildIp6Addresses]; + bool hasMeshLocal = false; for (uint8_t index = 0; index < aAddressListLength; index++) {