[netif] consolidate multicast address tracking and MLR states (#12576)

This commit simplifies multicast address management within `Netif` by
merging the `ExternalMulticastAddress` class directly into the base
`MulticastAddress` class. The `otNetifMulticastAddress` structure is
updated to include `mAddressOrigin` and an opaque `mData` field.

The `mData` field is utilized to track the Multicast Listener
Registration (MLR) state when the `OPENTHREAD_CONFIG_MLR_ENABLE`
feature is enabled.

By consolidating these types, we eliminate the need for separate
internal and external multicast address iteration logic in
`MlrManager`, streamlining MLR subscription checks and updates.
Additionally, this provides a more unified way to track the origin of
multicast addresses natively.
This commit is contained in:
Abtin Keshavarzian
2026-03-02 12:02:32 -06:00
committed by GitHub
parent 4866887933
commit 3289054650
11 changed files with 170 additions and 234 deletions
+1 -1
View File
@@ -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
+21 -7
View File
@@ -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;
/**
-25
View File
@@ -420,31 +420,6 @@ uint8_t Address::PrefixMatch(const Address &aOther) const
return static_cast<uint8_t>(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
-21
View File
@@ -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.
+58 -40
View File
@@ -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<Notifier>().Signal(aEvent == kAddressAdded ? kEventIp6MulticastSubscribed : kEventIp6MulticastUnsubscribed);
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
Get<HistoryTracker::Local>().RecordAddressEvent(aEvent, aAddress, aOrigin);
Get<HistoryTracker::Local>().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<const ExternalMulticastAddress &>(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<ExternalMulticastAddress &>(*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<Mle::Mle>().IsMulticastAddressMeshLocalPrefixBased(address))
{
SignalMulticastAddressChange(kAddressRemoved, address, kOriginThread);
SignalMulticastAddressChange(kAddressRemoved, address);
address.GetAddress().SetMulticastNetworkPrefix(Get<Mle::Mle>().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<const ExternalMulticastAddress *>(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
+54 -107
View File
@@ -232,6 +232,16 @@ public:
friend class LinkedList<MulticastAddress>;
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<AddressOrigin>(mAddressOrigin); }
/**
* Returns the next multicast address subscribed to the interface.
*
@@ -260,91 +277,46 @@ public:
*/
MulticastAddress *GetNext(void) { return static_cast<MulticastAddress *>(AsNonConst(mNext)); }
private:
bool Matches(const Address &aAddress) const { return GetAddress() == aAddress; }
};
class ExternalMulticastAddress : public MulticastAddress
{
friend class Netif;
friend class LinkedList<ExternalMulticastAddress>;
public:
/**
* Represents an iterator for iterating external multicast addresses in a `Netif` instance.
*/
class Iterator : public ItemPtrIterator<ExternalMulticastAddress, Iterator>
{
friend class ItemPtrIterator<ExternalMulticastAddress, Iterator>;
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<MlrState>(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<ExternalMulticastAddress *>(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<MulticastAddress> &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<MulticastAddress> &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<ThreadNetif>().IterateExternalMulticastAddresses())
* { ... }
*
* or to iterate over a subset of external multicast addresses determined by a given address type filter
*
* for (Ip6::Netif::ExternalMulticastAddress &addr :
* Get<ThreadNetif>().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<otIp6AddressCallback> mAddressCallback;
Pool<UnicastAddress, OPENTHREAD_CONFIG_IP6_MAX_EXT_UCAST_ADDRS> mExtUnicastAddressPool;
Pool<ExternalMulticastAddress, OPENTHREAD_CONFIG_IP6_MAX_EXT_MCAST_ADDRS> mExtMulticastAddressPool;
Pool<UnicastAddress, kMaxExtUnicastAddrs> mExtUnicastAddressPool;
Pool<MulticastAddress, kMaxExtMulticastAddrs> mExtMulticastAddressPool;
static const otNetifMulticastAddress kRealmLocalAllMplForwardersMulticastAddress;
static const otNetifMulticastAddress kLinkLocalAllNodesMulticastAddress;
+8 -3
View File
@@ -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<Mle>().ShouldRegisterMulticastAddrsWithParent())
{
for (const Ip6::Netif::MulticastAddress &addr : Get<ThreadNetif>().IterateExternalMulticastAddresses())
for (const Ip6::Netif::MulticastAddress &addr : Get<ThreadNetif>().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.
+23 -20
View File
@@ -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<ThreadNetif>().IterateExternalMulticastAddresses(Ip6::Address::kTypeMulticastLargerThanRealmLocal))
for (Ip6::Netif::MulticastAddress &addr : Get<ThreadNetif>().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<ThreadNetif>().IterateExternalMulticastAddresses())
for (const Ip6::Netif::MulticastAddress &addr : Get<ThreadNetif>().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<ThreadNetif>().IterateExternalMulticastAddresses(Ip6::Address::kTypeMulticastLargerThanRealmLocal))
for (Ip6::Netif::MulticastAddress &addr : Get<ThreadNetif>().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<ThreadNetif>().IterateExternalMulticastAddresses(Ip6::Address::kTypeMulticastLargerThanRealmLocal))
for (Ip6::Netif::MulticastAddress &addr : Get<ThreadNetif>().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<ThreadNetif>().IterateExternalMulticastAddresses(Ip6::Address::kTypeMulticastLargerThanRealmLocal))
for (Ip6::Netif::MulticastAddress &addr : Get<ThreadNetif>().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<ThreadNetif>().IterateExternalMulticastAddresses())
for (const Ip6::Netif::MulticastAddress &addr : Get<ThreadNetif>().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<ThreadNetif>().IterateExternalMulticastAddresses(Ip6::Address::kTypeMulticastLargerThanRealmLocal))
for (Ip6::Netif::MulticastAddress &addr : Get<ThreadNetif>().GetMulticastAddresses())
{
registeringNum += (addr.GetMlrState() == kMlrStateRegistering);
if (addr.Matches(kMlrStateRegistering))
{
registeringNum++;
}
}
#endif
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
+2 -4
View File
@@ -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:
+1 -3
View File
@@ -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
+2 -3
View File
@@ -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++)
{