mirror of
https://github.com/espressif/openthread.git
synced 2026-09-07 17:50:09 +00:00
[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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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++)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user