mirror of
https://github.com/espressif/openthread.git
synced 2026-06-05 21:14:49 +00:00
[mlr] simplify MLR state tracking on Child (#13166)
This commit simplifies MLR state tracking for child devices. Previously, `Child::Ip6AddrEntry` inherited from `Ip6::Address` to encapsulate the MLR registration check using the `Child` reference. This introduced tight coupling between `Child` and `Ip6AddrEntry`. The logic is refactored by removing `Ip6AddrEntry`. Instead, `Child` now directly manages a `Child::Ip6AddressArray` and encapsulates the MLR state querying/updating through new methods: - `SetAddressMlrRegistrationState()` - `GetAllMlrRegisteredAddresses()` - `ClearAllAddressesMlrRegistrationState()` In `Mlr::Manager`, the redundant `ChildAddressArray` typedef and `kMaxChildAddresses` constant are removed, reusing the `Child::Ip6AddressArray`. The method `UpdateProxiedSubscriptions()` is renamed to the more intuitive `UpdateChildRegistrations()`, and overloaded to allow calling it without an old address list during initial child registration.
This commit is contained in:
committed by
GitHub
parent
290919b178
commit
eac46963bb
+31
-23
@@ -71,24 +71,6 @@ void Child::Info::SetFrom(const Child &aChild)
|
||||
mConnectionTime = aChild.GetConnectionTime();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// Child::Ip6AddrEntry
|
||||
|
||||
#if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
|
||||
|
||||
bool Child::Ip6AddrEntry::IsMlrRegistered(const Child &aChild) const
|
||||
{
|
||||
return aChild.mMlrRegisteredSet.Has(aChild.mIp6Addresses.IndexOf(*this));
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-make-member-function-const)
|
||||
void Child::Ip6AddrEntry::SetMlrRegistered(bool aRegistered, Child &aChild)
|
||||
{
|
||||
aChild.mMlrRegisteredSet.Update(aChild.mIp6Addresses.IndexOf(*this), aRegistered);
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// Child
|
||||
|
||||
@@ -182,7 +164,7 @@ Error Child::AddIp6Address(const Ip6::Address &aAddress)
|
||||
}
|
||||
|
||||
VerifyOrExit(!mIp6Addresses.ContainsMatching(aAddress), error = kErrorAlready);
|
||||
error = mIp6Addresses.PushBack(static_cast<const Ip6AddrEntry &>(aAddress));
|
||||
error = mIp6Addresses.PushBack(aAddress);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
@@ -191,7 +173,7 @@ exit:
|
||||
Error Child::RemoveIp6Address(const Ip6::Address &aAddress)
|
||||
{
|
||||
Error error = kErrorNotFound;
|
||||
Ip6AddrEntry *entry;
|
||||
Ip6::Address *entry;
|
||||
|
||||
if (Get<Mle::Mle>().IsMeshLocalAddress(aAddress))
|
||||
{
|
||||
@@ -271,18 +253,44 @@ exit:
|
||||
bool Child::HasMlrRegisteredAddress(const Ip6::Address &aAddress) const
|
||||
{
|
||||
bool hasAddress = false;
|
||||
const Ip6AddrEntry *entry;
|
||||
const Ip6::Address *entry;
|
||||
|
||||
entry = mIp6Addresses.FindMatching(aAddress);
|
||||
VerifyOrExit(entry != nullptr);
|
||||
|
||||
hasAddress = entry->IsMlrRegistered(*this);
|
||||
hasAddress = mMlrRegisteredSet.Has(mIp6Addresses.IndexOf(*entry));
|
||||
|
||||
exit:
|
||||
return hasAddress;
|
||||
}
|
||||
|
||||
#endif
|
||||
void Child::SetAddressMlrRegistrationState(const Ip6::Address &aAddress, bool aRegistered)
|
||||
{
|
||||
Ip6::Address *entry;
|
||||
|
||||
entry = mIp6Addresses.FindMatching(aAddress);
|
||||
VerifyOrExit(entry != nullptr);
|
||||
|
||||
mMlrRegisteredSet.Update(mIp6Addresses.IndexOf(*entry), aRegistered);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Child::GetAllMlrRegisteredAddresses(Ip6AddressArray &aAddressArray) const
|
||||
{
|
||||
aAddressArray.Clear();
|
||||
|
||||
for (const Ip6::Address &entry : mIp6Addresses)
|
||||
{
|
||||
if (mMlrRegisteredSet.Has(mIp6Addresses.IndexOf(entry)))
|
||||
{
|
||||
IgnoreError(aAddressArray.PushBack(entry));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
|
||||
|
||||
#endif // OPENTHREAD_FTD
|
||||
|
||||
|
||||
+27
-62
@@ -60,6 +60,13 @@ public:
|
||||
*/
|
||||
static constexpr uint16_t kNumIp6Addresses = OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD - 1;
|
||||
|
||||
/**
|
||||
* Represents an array of IPv6 addresses registered by an MTD child.
|
||||
*
|
||||
* This array does not include the mesh-local EID.
|
||||
*/
|
||||
typedef Array<Ip6::Address, kNumIp6Addresses> Ip6AddressArray;
|
||||
|
||||
/**
|
||||
* Represents the iterator for registered IPv6 address list of an MTD child.
|
||||
*/
|
||||
@@ -84,50 +91,6 @@ public:
|
||||
void SetFrom(const Child &aChild);
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents an IPv6 address entry registered by an MTD child.
|
||||
*/
|
||||
class Ip6AddrEntry : public Ip6::Address
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Indicates whether the entry matches a given IPv6 address.
|
||||
*
|
||||
* @param[in] aAddress The IPv6 address.
|
||||
*
|
||||
* @retval TRUE The entry matches @p aAddress.
|
||||
* @retval FALSE The entry does not match @p aAddress.
|
||||
*/
|
||||
bool Matches(const Ip6::Address &aAddress) const { return (*this == aAddress); }
|
||||
|
||||
#if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
|
||||
/**
|
||||
* Indicates whether the IPv6 address is registered via Multicast Listener Registration (MLR) on a given child.
|
||||
*
|
||||
* @param[in] aChild The child associated with the address.
|
||||
*
|
||||
* @retval TRUE If the address is MLR registered on @p aChild.
|
||||
* @retval FALSE If the address is not MLR registered on @p aChild.
|
||||
*/
|
||||
bool IsMlrRegistered(const Child &aChild) const;
|
||||
|
||||
/**
|
||||
* Sets whether the IPv6 address is registered via Multicast Listener Registration (MLR) on a given child.
|
||||
*
|
||||
* @param[in] aRegistered TRUE if MLR registered, FALSE otherwise.
|
||||
* @param[in] aChild The child associated with the address.
|
||||
*/
|
||||
void SetMlrRegistered(bool aRegistered, Child &aChild);
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents an array of IPv6 address entries registered by an MTD child.
|
||||
*
|
||||
* This array does not include the mesh-local EID.
|
||||
*/
|
||||
typedef Array<Ip6AddrEntry, kNumIp6Addresses> Ip6AddressArray;
|
||||
|
||||
/**
|
||||
* Initializes the `Child` object.
|
||||
*
|
||||
@@ -178,15 +141,6 @@ public:
|
||||
*/
|
||||
const Ip6AddressArray &GetIp6Addresses(void) const { return mIp6Addresses; }
|
||||
|
||||
/**
|
||||
* Gets an array of registered IPv6 address entries by the child.
|
||||
*
|
||||
* The array does not include the mesh-local EID. The ML-EID can retrieved using `GetMeshLocalIp6Address()`.
|
||||
*
|
||||
* @returns The array of registered IPv6 addresses by the child.
|
||||
*/
|
||||
Ip6AddressArray &GetIp6Addresses(void) { return mIp6Addresses; }
|
||||
|
||||
/**
|
||||
* Iterates over all registered IPv6 addresses (using an iterator).
|
||||
*
|
||||
@@ -202,7 +156,7 @@ public:
|
||||
/**
|
||||
* Adds an IPv6 address to the list.
|
||||
*
|
||||
* @param[in] aAddress A reference to IPv6 address to be added.
|
||||
* @param[in] aAddress The IPv6 address to be added.
|
||||
*
|
||||
* @retval kErrorNone Successfully added the new address.
|
||||
* @retval kErrorAlready Address is already in the list.
|
||||
@@ -214,7 +168,7 @@ public:
|
||||
/**
|
||||
* Removes an IPv6 address from the list.
|
||||
*
|
||||
* @param[in] aAddress A reference to IPv6 address to be removed.
|
||||
* @param[in] aAddress The IPv6 address to be removed.
|
||||
*
|
||||
* @retval kErrorNone Successfully removed the address.
|
||||
* @retval kErrorNotFound Address was not found in the list.
|
||||
@@ -225,7 +179,7 @@ public:
|
||||
/**
|
||||
* Indicates whether an IPv6 address is in the list of IPv6 addresses of the child.
|
||||
*
|
||||
* @param[in] aAddress A reference to IPv6 address.
|
||||
* @param[in] aAddress The IPv6 address to check.
|
||||
*
|
||||
* @retval TRUE The address exists on the list.
|
||||
* @retval FALSE Address was not found in the list.
|
||||
@@ -353,10 +307,11 @@ public:
|
||||
void SetBlockParentDowngrade(bool aBlock) { mBlockParentDowngrade = aBlock; }
|
||||
|
||||
#if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
|
||||
|
||||
/**
|
||||
* Clears the Multicast Listener Registration (MLR) registered state on all IPv6 addresses of the child.
|
||||
* Clears the Multicast Listener Registration (MLR) registration state of all IPv6 addresses of the child.
|
||||
*/
|
||||
void ClearMlrRegisteredStateOnAllIp6Addresses(void) { mMlrRegisteredSet.Clear(); }
|
||||
void ClearAllAddressesMlrRegistrationState(void) { mMlrRegisteredSet.Clear(); }
|
||||
|
||||
/**
|
||||
* Indicates whether the child has a given IPv6 address that is MLR registered.
|
||||
@@ -369,12 +324,22 @@ public:
|
||||
bool HasMlrRegisteredAddress(const Ip6::Address &aAddress) const;
|
||||
|
||||
/**
|
||||
* Indicates whether the child has any IPv6 address that is MLR registered.
|
||||
* Sets the MLR registered state of a given IPv6 address of the child.
|
||||
*
|
||||
* @retval TRUE If the child has any MLR registered IPv6 address.
|
||||
* @retval FALSE If the child does not have any MLR registered IPv6 address.
|
||||
* If @p aAddress is not present on the list, calling this method does nothing.
|
||||
*
|
||||
* @param[in] aAddress The address.
|
||||
* @param[in] aRegistered TRUE if MLR registered, FALSE otherwise.
|
||||
*/
|
||||
bool HasAnyMlrRegisteredAddress(void) const { return !mMlrRegisteredSet.IsEmpty(); }
|
||||
void SetAddressMlrRegistrationState(const Ip6::Address &aAddress, bool aRegistered);
|
||||
|
||||
/**
|
||||
* Gets all the MLR registered IPv6 addresses of the child.
|
||||
*
|
||||
* @param[out] aAddressArray A reference to an array to output the addresses.
|
||||
*/
|
||||
void GetAllMlrRegisteredAddresses(Ip6AddressArray &aAddressArray) const;
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
|
||||
|
||||
private:
|
||||
|
||||
@@ -1830,7 +1830,7 @@ Error Mle::ProcessAddressRegistrationTlv(RxInfo &aRxInfo, Child &aChild)
|
||||
Ip6::Address oldDua;
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
|
||||
Mlr::Manager::ChildAddressArray oldMlrRegisteredAddresses;
|
||||
Child::Ip6AddressArray oldMlrRegisteredAddresses;
|
||||
#endif
|
||||
|
||||
OT_UNUSED_VARIABLE(storedCount);
|
||||
@@ -1845,16 +1845,7 @@ Error Mle::ProcessAddressRegistrationTlv(RxInfo &aRxInfo, Child &aChild)
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
|
||||
if (aChild.HasAnyMlrRegisteredAddress())
|
||||
{
|
||||
for (const Child::Ip6AddrEntry &addrEntry : aChild.GetIp6Addresses())
|
||||
{
|
||||
if (addrEntry.IsMlrRegistered(aChild))
|
||||
{
|
||||
IgnoreError(oldMlrRegisteredAddresses.PushBack(addrEntry));
|
||||
}
|
||||
}
|
||||
}
|
||||
aChild.GetAllMlrRegisteredAddresses(oldMlrRegisteredAddresses);
|
||||
#endif
|
||||
|
||||
aChild.ClearIp6Addresses();
|
||||
@@ -1946,7 +1937,7 @@ Error Mle::ProcessAddressRegistrationTlv(RxInfo &aRxInfo, Child &aChild)
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
|
||||
Get<Mlr::Manager>().UpdateProxiedSubscriptions(aChild, oldMlrRegisteredAddresses);
|
||||
Get<Mlr::Manager>().UpdateChildRegistrations(aChild, oldMlrRegisteredAddresses);
|
||||
#endif
|
||||
|
||||
if (count == 0)
|
||||
@@ -3812,7 +3803,7 @@ void Mle::SetChildStateToValid(Child &aChild)
|
||||
IgnoreError(mChildTable.StoreChild(aChild));
|
||||
|
||||
#if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
|
||||
Get<Mlr::Manager>().UpdateProxiedSubscriptions(aChild, Mlr::Manager::ChildAddressArray());
|
||||
Get<Mlr::Manager>().UpdateChildRegistrations(aChild);
|
||||
#endif
|
||||
|
||||
mNeighborTable.Signal(NeighborTable::kChildAdded, aChild);
|
||||
|
||||
@@ -82,7 +82,7 @@ void Manager::EnterState(State aState)
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
|
||||
for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValid))
|
||||
{
|
||||
child.ClearMlrRegisteredStateOnAllIp6Addresses();
|
||||
child.ClearAllAddressesMlrRegistrationState();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -256,29 +256,36 @@ bool Manager::IsAddressRegisteredByAnyChildExcept(const Ip6::Address &aAddress,
|
||||
return isRegistered;
|
||||
}
|
||||
|
||||
void Manager::UpdateProxiedSubscriptions(Child &aChild, const ChildAddressArray &aOldRegisteredAddresses)
|
||||
void Manager::UpdateChildRegistrations(Child &aChild)
|
||||
{
|
||||
Child::Ip6AddressArray emptyArray;
|
||||
|
||||
UpdateChildRegistrations(aChild, emptyArray);
|
||||
}
|
||||
|
||||
void Manager::UpdateChildRegistrations(Child &aChild, const Child::Ip6AddressArray &aOldRegisteredAddresses)
|
||||
{
|
||||
bool hasUnregistered = false;
|
||||
|
||||
VerifyOrExit(aChild.IsStateValid());
|
||||
|
||||
for (Child::Ip6AddrEntry &addrEntry : aChild.GetIp6Addresses())
|
||||
for (const Ip6::Address &addr : aChild.GetIp6Addresses())
|
||||
{
|
||||
bool isRegistered;
|
||||
|
||||
if (!addrEntry.IsMulticastLargerThanRealmLocal())
|
||||
if (!addr.IsMulticastLargerThanRealmLocal())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
isRegistered = aOldRegisteredAddresses.Contains(addrEntry);
|
||||
isRegistered = aOldRegisteredAddresses.ContainsMatching(addr);
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLR_ENABLE
|
||||
isRegistered = isRegistered || IsAddressRegisteredByNetif(addrEntry);
|
||||
isRegistered = isRegistered || IsAddressRegisteredByNetif(addr);
|
||||
#endif
|
||||
isRegistered = isRegistered || IsAddressRegisteredByAnyChildExcept(addrEntry, &aChild);
|
||||
isRegistered = isRegistered || IsAddressRegisteredByAnyChildExcept(addr, &aChild);
|
||||
|
||||
addrEntry.SetMlrRegistered(isRegistered, aChild);
|
||||
aChild.SetAddressMlrRegistrationState(addr, isRegistered);
|
||||
|
||||
if (!isRegistered)
|
||||
{
|
||||
@@ -347,11 +354,11 @@ void Manager::DetermineAddressesToRegister(AddressArray &aAddresses) const
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
|
||||
for (const Child &child : Get<ChildTable>().Iterate(Child::kInStateValid))
|
||||
{
|
||||
for (const Child::Ip6AddrEntry &addrEntry : child.GetIp6Addresses())
|
||||
for (const Ip6::Address &addr : child.GetIp6Addresses())
|
||||
{
|
||||
if (addrEntry.IsMulticastLargerThanRealmLocal() && !addrEntry.IsMlrRegistered(child))
|
||||
if (addr.IsMulticastLargerThanRealmLocal() && !child.HasMlrRegisteredAddress(addr))
|
||||
{
|
||||
SuccessOrExit(aAddresses.AddUnique(addrEntry));
|
||||
SuccessOrExit(aAddresses.AddUnique(addr));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -606,12 +613,12 @@ void Manager::ProcessResponse(Coap::Msg *aMsg, Error aResult)
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
|
||||
for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValid))
|
||||
{
|
||||
for (Child::Ip6AddrEntry &addrEntry : child.GetIp6Addresses())
|
||||
for (const Ip6::Address &addr : child.GetIp6Addresses())
|
||||
{
|
||||
if (addrEntry.IsMulticastLargerThanRealmLocal() && !addrEntry.IsMlrRegistered(child) &&
|
||||
registeredAddresses.Contains(addrEntry))
|
||||
if (addr.IsMulticastLargerThanRealmLocal() && !child.HasMlrRegisteredAddress(addr) &&
|
||||
registeredAddresses.Contains(addr))
|
||||
{
|
||||
addrEntry.SetMlrRegistered(true, child);
|
||||
child.SetAddressMlrRegistrationState(addr, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,17 +97,20 @@ public:
|
||||
void HandleBackboneRouterPrimaryUpdate(BackboneRouter::PrimaryEvent aEvent);
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
|
||||
static constexpr uint16_t kMaxChildAddresses = OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD - 1; ///< Max MLR addresses
|
||||
|
||||
typedef Array<Ip6::Address, kMaxChildAddresses> ChildAddressArray; ///< Registered MLR addresses array.
|
||||
/**
|
||||
* Updates the MLR registration status of a given child's addresses.
|
||||
*
|
||||
* @param[in] aChild The child to update.
|
||||
*/
|
||||
void UpdateChildRegistrations(Child &aChild);
|
||||
|
||||
/**
|
||||
* Updates the Multicast Subscription Table according to the Child information.
|
||||
* Updates the MLR registration status of a given child's addresses.
|
||||
*
|
||||
* @param[in] aChild A reference to the child information.
|
||||
* @param[in] aOldRegisteredAddresses Array of the Child's previously registered IPv6 addresses.
|
||||
* @param[in] aChild The child to update.
|
||||
* @param[in] aOldRegisteredAddresses Child's previously registered addresses.
|
||||
*/
|
||||
void UpdateProxiedSubscriptions(Child &aChild, const ChildAddressArray &aOldRegisteredAddresses);
|
||||
void UpdateChildRegistrations(Child &aChild, const Child::Ip6AddressArray &aOldRegisteredAddresses);
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
|
||||
|
||||
Reference in New Issue
Block a user