Skip to content

Commit ddfd665

Browse files
authored
[mlr] simplify multicast address state tracking (openthread#13089)
This commit simplifies the tracking of Multicast Listener Registration (MLR) state for IPv6 addresses by removing intermediate states and relying on the original CoAP request payload. Previously, `Mlr::Manager` used a 3-state system (`kStateToRegister`, `kStateRegistering`, `kStateRegistered`) which required core structures like `Child` and `Netif` to track transient registration states. This commit reduces the state to a single boolean (`IsMlrRegistered`) tracked in `ChildTable` and `ThreadNetif`. When a CoAP response is received, `Mlr::Manager` now uses `GetDispatchingRequest()` to retrieve the original TMR MLE request message, parses the `Ip6AddressesTlv` to determine exactly which addresses were included in the request, and updates the registration states based purely on this info (minus any explicitly failed addresses). This change improves robustness, reduces RAM usage by eliminating state-tracking arrays, and significantly cleans up the logical flow within the MLR manager.
1 parent 1f24ace commit ddfd665

9 files changed

Lines changed: 178 additions & 329 deletions

File tree

src/core/net/ip6_address.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,18 @@ class Address : public otIp6Address, public Equatable<Address>, public Clearable
742742
*/
743743
bool MatchesPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) const;
744744

745+
/**
746+
* Indicates whether the address matches a given other address.
747+
*
748+
* This method is intended to be used with `FindMatching()` in collections.
749+
*
750+
* @param[in] aAddress The IPv6 address to match against.
751+
*
752+
* @retval TRUE If the address matches @p aAddress.
753+
* @retval FALSE If the address does not match @p aAddress.
754+
*/
755+
bool Matches(const Ip6::Address &aAddress) const { return (*this == aAddress); }
756+
745757
/**
746758
* Sets the IPv6 address prefix.
747759
*

src/core/net/netif.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -613,11 +613,6 @@ void Netif::MulticastAddress::InitAsManualOrigin(void)
613613
{
614614
Clear();
615615
mAddressOrigin = kOriginManual;
616-
617-
#if OPENTHREAD_CONFIG_MLR_ENABLE
618-
// Make sure `Clear()` sets the "MlrState" to `Mlr::kStateToRegister` value.
619-
static_assert(Mlr::kStateToRegister == 0, "Mlr::kStateToRegister is not correct.");
620-
#endif
621616
}
622617

623618
#if OPENTHREAD_CONFIG_MLR_ENABLE
@@ -627,11 +622,6 @@ bool Netif::MulticastAddress::IsMlrCandidate(void) const
627622
return (GetOrigin() == kOriginManual) && GetAddress().IsMulticastLargerThanRealmLocal();
628623
}
629624

630-
bool Netif::MulticastAddress::Matches(Mlr::State aMlrState) const
631-
{
632-
return IsMlrCandidate() && (GetMlrState() == aMlrState);
633-
}
634-
635625
#endif
636626

637627
} // namespace Ip6

src/core/net/netif.hpp

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -290,28 +290,19 @@ class Netif : public InstanceLocator, private NonCopyable
290290
bool IsMlrCandidate(void) const;
291291

292292
/**
293-
* Returns the current Multicast Listener Registration (MLR) state.
293+
* Indicates whether the multicast address is registered via Multicast Listener Registration (MLR).
294294
*
295-
* @returns The current Multicast Listener Registration state.
295+
* @retval TRUE If the multicast address is MLR registered.
296+
* @retval FALSE If the multicast address is not MLR registered.
296297
*/
297-
Mlr::State GetMlrState(void) const { return static_cast<Mlr::State>(mData); }
298+
bool IsMlrRegistered(void) const { return (mData != 0); }
298299

299300
/**
300-
* Sets the Multicast Listener Registration (MLR) state.
301+
* Sets whether the multicast address is registered via Multicast Listener Registration (MLR).
301302
*
302-
* @param[in] aState The new Multicast Listener Registration state.
303+
* @param[in] aRegistered TRUE if MLR registered, FALSE otherwise.
303304
*/
304-
void SetMlrState(Mlr::State aState) { mData = aState; }
305-
306-
/**
307-
* Indicates whether or not the address is an MLR candidate and matches a given MLR state.
308-
*
309-
* @param[in] aMlrState The MLR state to match against.
310-
*
311-
* @retval TRUE If the address is an MLR candidate and its state matches @p aMlrState.
312-
* @retval FALSE If the address is not an MLR candidate or its state does not match @p aMlrState.
313-
*/
314-
bool Matches(Mlr::State aMlrState) const;
305+
void SetMlrRegistered(bool aRegistered) { mData = aRegistered ? 1 : 0; }
315306
#endif
316307

317308
private:

src/core/thread/child.cpp

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -76,38 +76,15 @@ void Child::Info::SetFrom(const Child &aChild)
7676

7777
#if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
7878

79-
Mlr::State Child::Ip6AddrEntry::GetMlrState(const Child &aChild) const
79+
bool Child::Ip6AddrEntry::IsMlrRegistered(const Child &aChild) const
8080
{
81-
Mlr::State state = Mlr::kStateRegistering;
82-
Ip6AddressArray::IndexType index;
83-
84-
OT_ASSERT(aChild.mIp6Addresses.IsInArrayBuffer(this));
85-
86-
index = aChild.mIp6Addresses.IndexOf(*this);
87-
88-
if (aChild.mMlrToRegisterSet.Has(index))
89-
{
90-
state = Mlr::kStateToRegister;
91-
}
92-
else if (aChild.mMlrRegisteredSet.Has(index))
93-
{
94-
state = Mlr::kStateRegistered;
95-
}
96-
97-
return state;
81+
return aChild.mMlrRegisteredSet.Has(aChild.mIp6Addresses.IndexOf(*this));
9882
}
9983

10084
// NOLINTNEXTLINE(readability-make-member-function-const)
101-
void Child::Ip6AddrEntry::SetMlrState(Mlr::State aState, Child &aChild)
85+
void Child::Ip6AddrEntry::SetMlrRegistered(bool aRegistered, Child &aChild)
10286
{
103-
Ip6AddressArray::IndexType index;
104-
105-
OT_ASSERT(aChild.mIp6Addresses.IsInArrayBuffer(this));
106-
107-
index = aChild.mIp6Addresses.IndexOf(*this);
108-
109-
aChild.mMlrToRegisterSet.Update(index, aState == Mlr::kStateToRegister);
110-
aChild.mMlrRegisteredSet.Update(index, aState == Mlr::kStateRegistered);
87+
aChild.mMlrRegisteredSet.Update(aChild.mIp6Addresses.IndexOf(*this), aRegistered);
11188
}
11289

11390
#endif // OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
@@ -128,7 +105,6 @@ void Child::ClearIp6Addresses(void)
128105
mMeshLocalIid.Clear();
129106
mIp6Addresses.Clear();
130107
#if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
131-
mMlrToRegisterSet.Clear();
132108
mMlrRegisteredSet.Clear();
133109
#endif
134110
}
@@ -230,9 +206,6 @@ Error Child::RemoveIp6Address(const Ip6::Address &aAddress)
230206
uint16_t entryIndex = mIp6Addresses.IndexOf(*entry);
231207
uint16_t lastIndex = mIp6Addresses.GetLength() - 1;
232208

233-
mMlrToRegisterSet.Update(entryIndex, mMlrToRegisterSet.Has(lastIndex));
234-
mMlrToRegisterSet.Remove(lastIndex);
235-
236209
mMlrRegisteredSet.Update(entryIndex, mMlrRegisteredSet.Has(lastIndex));
237210
mMlrRegisteredSet.Remove(lastIndex);
238211
}
@@ -292,7 +265,8 @@ bool Child::HasMlrRegisteredAddress(const Ip6::Address &aAddress) const
292265

293266
entry = mIp6Addresses.FindMatching(aAddress);
294267
VerifyOrExit(entry != nullptr);
295-
hasAddress = entry->GetMlrState(*this) == Mlr::kStateRegistered;
268+
269+
hasAddress = entry->IsMlrRegistered(*this);
296270

297271
exit:
298272
return hasAddress;

src/core/thread/child.hpp

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -102,21 +102,22 @@ class Child : public CslNeighbor
102102

103103
#if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
104104
/**
105-
* Gets the MLR state of the IPv6 address entry.
105+
* Indicates whether the IPv6 address is registered via Multicast Listener Registration (MLR) on a given child.
106106
*
107-
* @param[in] aChild The child owning this address entry.
107+
* @param[in] aChild The child associated with the address.
108108
*
109-
* @returns The MLR state of IPv6 address entry.
109+
* @retval TRUE If the address is MLR registered on @p aChild.
110+
* @retval FALSE If the address is not MLR registered on @p aChild.
110111
*/
111-
Mlr::State GetMlrState(const Child &aChild) const;
112+
bool IsMlrRegistered(const Child &aChild) const;
112113

113114
/**
114-
* Sets the MLR state of the IPv6 address entry.
115+
* Sets whether the IPv6 address is registered via Multicast Listener Registration (MLR) on a given child.
115116
*
116-
* @param[in] aState The MLR state.
117-
* @param[in] aChild The child owning this address entry.
117+
* @param[in] aRegistered TRUE if MLR registered, FALSE otherwise.
118+
* @param[in] aChild The child associated with the address.
118119
*/
119-
void SetMlrState(Mlr::State aState, Child &aChild);
120+
void SetMlrRegistered(bool aRegistered, Child &aChild);
120121
#endif
121122
};
122123

@@ -353,30 +354,27 @@ class Child : public CslNeighbor
353354

354355
#if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
355356
/**
356-
* Returns if the Child has IPv6 address @p aAddress of MLR state `Mlr::kStateRegistered`.
357+
* Clears the Multicast Listener Registration (MLR) registered state on all IPv6 addresses of the child.
358+
*/
359+
void ClearMlrRegisteredStateOnAllIp6Addresses(void) { mMlrRegisteredSet.Clear(); }
360+
361+
/**
362+
* Indicates whether the child has a given IPv6 address that is MLR registered.
357363
*
358364
* @param[in] aAddress The IPv6 address.
359365
*
360-
* @retval true If the Child has IPv6 address @p aAddress of MLR state `Mlr::kStateRegistered`.
361-
* @retval false If the Child does not have IPv6 address @p aAddress of MLR state `Mlr::kStateRegistered`.
366+
* @retval TRUE If the child has the IPv6 address @p aAddress and it is MLR registered.
367+
* @retval FALSE If the child does not have the IPv6 address @p aAddress or it is not MLR registered.
362368
*/
363369
bool HasMlrRegisteredAddress(const Ip6::Address &aAddress) const;
364370

365371
/**
366-
* Returns if the Child has any IPv6 address of MLR state `Mlr::kStateRegistered`.
372+
* Indicates whether the child has any IPv6 address that is MLR registered.
367373
*
368-
* @retval true If the Child has any IPv6 address of MLR state `Mlr::kStateRegistered`.
369-
* @retval false If the Child does not have any IPv6 address of MLR state `Mlr::kStateRegistered`.
374+
* @retval TRUE If the child has any MLR registered IPv6 address.
375+
* @retval FALSE If the child does not have any MLR registered IPv6 address.
370376
*/
371377
bool HasAnyMlrRegisteredAddress(void) const { return !mMlrRegisteredSet.IsEmpty(); }
372-
373-
/**
374-
* Returns if the Child has any IPv6 address of MLR state `Mlr::kStateToRegister`.
375-
*
376-
* @retval true If the Child has any IPv6 address of MLR state `Mlr::kStateToRegister`.
377-
* @retval false If the Child does not have any IPv6 address of MLR state `Mlr::kStateToRegister`.
378-
*/
379-
bool HasAnyMlrToRegisterAddress(void) const { return !mMlrToRegisterSet.IsEmpty(); }
380378
#endif // OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
381379

382380
private:
@@ -387,7 +385,6 @@ class Child : public CslNeighbor
387385
Ip6::InterfaceIdentifier mMeshLocalIid;
388386
Ip6AddressArray mIp6Addresses;
389387
#if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
390-
ChildIp6AddressSet mMlrToRegisterSet;
391388
ChildIp6AddressSet mMlrRegisteredSet;
392389
#endif
393390

src/core/thread/mle_ftd.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1874,12 +1874,7 @@ Error Mle::ProcessAddressRegistrationTlv(RxInfo &aRxInfo, Child &aChild)
18741874
{
18751875
for (const Child::Ip6AddrEntry &addrEntry : aChild.GetIp6Addresses())
18761876
{
1877-
if (!addrEntry.IsMulticastLargerThanRealmLocal())
1878-
{
1879-
continue;
1880-
}
1881-
1882-
if (addrEntry.GetMlrState(aChild) == Mlr::kStateRegistered)
1877+
if (addrEntry.IsMlrRegistered(aChild))
18831878
{
18841879
IgnoreError(oldMlrRegisteredAddresses.PushBack(addrEntry));
18851880
}

0 commit comments

Comments
 (0)