[netdata] move service ALOC management from MLE module (#11815)

This change moves the service ALOC management logic from the `Mle`
module to `NetworkData::Service::Manager`.

This change simplifies the code by consolidating responsibilities.
Since the `NetworkData::Service` module manages service entries in
the Network Data, it is the logical owner for managing the associated
service ALOCs.
This commit is contained in:
Abtin Keshavarzian
2025-08-13 19:07:59 -07:00
committed by GitHub
parent 562a3d8c73
commit a3cd859502
5 changed files with 133 additions and 125 deletions
+3
View File
@@ -98,6 +98,9 @@ void Notifier::EmitEvents(void)
// Emit events to core internal modules
Get<Mle::Mle>().HandleNotifierEvents(events);
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
Get<NetworkData::Service::Manager>().HandleNotifierEvents(events);
#endif
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
Get<BackboneRouter::Leader>().HandleNotifierEvents(events);
#endif
-94
View File
@@ -1182,10 +1182,6 @@ void Mle::HandleNotifierEvents(Events aEvents)
ScheduleChildUpdateRequest();
}
}
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
UpdateServiceAlocs();
#endif
}
if (aEvents.ContainsAny(kEventThreadRoleChanged | kEventThreadKeySeqCounterChanged))
@@ -1222,96 +1218,6 @@ exit:
return;
}
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
Mle::ServiceAloc::ServiceAloc(void)
{
InitAsThreadOriginMeshLocal();
GetAddress().GetIid().SetToLocator(kNotInUse);
}
Mle::ServiceAloc *Mle::FindInServiceAlocs(uint16_t aAloc16)
{
// Search in `mServiceAlocs` for an entry matching `aAloc16`.
// Can be used with `aAloc16 = ServerAloc::kNotInUse` to find
// an unused entry in the array.
ServiceAloc *match = nullptr;
for (ServiceAloc &serviceAloc : mServiceAlocs)
{
if (serviceAloc.GetAloc16() == aAloc16)
{
match = &serviceAloc;
break;
}
}
return match;
}
void Mle::UpdateServiceAlocs(void)
{
NetworkData::Iterator iterator;
NetworkData::ServiceConfig service;
VerifyOrExit(!IsDisabled());
// First remove all ALOCs which are no longer in the Network
// Data to free up space in `mServiceAlocs` array.
for (ServiceAloc &serviceAloc : mServiceAlocs)
{
bool found = false;
if (!serviceAloc.IsInUse())
{
continue;
}
iterator = NetworkData::kIteratorInit;
while (Get<NetworkData::Leader>().GetNext(iterator, GetRloc16(), service) == kErrorNone)
{
if (service.mServiceId == ServiceIdFromAloc(serviceAloc.GetAloc16()))
{
found = true;
break;
}
}
if (!found)
{
Get<ThreadNetif>().RemoveUnicastAddress(serviceAloc);
serviceAloc.MarkAsNotInUse();
}
}
// Now add any new ALOCs if there is space in `mServiceAlocs`.
iterator = NetworkData::kIteratorInit;
while (Get<NetworkData::Leader>().GetNext(iterator, GetRloc16(), service) == kErrorNone)
{
uint16_t aloc16 = ServiceAlocFromId(service.mServiceId);
if (FindInServiceAlocs(aloc16) == nullptr)
{
// No matching ALOC in `mServiceAlocs`, so we try to add it.
ServiceAloc *newServiceAloc = FindInServiceAlocs(ServiceAloc::kNotInUse);
VerifyOrExit(newServiceAloc != nullptr);
newServiceAloc->SetAloc16(aloc16);
Get<ThreadNetif>().AddUnicastAddress(*newServiceAloc);
}
}
exit:
return;
}
#endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
Error Mle::DetermineParentRequestType(ParentRequestType &aType) const
{
// This method determines the Parent Request type to use during an
-31
View File
@@ -1218,12 +1218,6 @@ private:
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
static constexpr uint8_t kMaxServiceAlocs = OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_MAX_ALOCS + 1;
#else
static constexpr uint8_t kMaxServiceAlocs = OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_MAX_ALOCS;
#endif
static constexpr uint8_t kMleHopLimit = 255;
static constexpr uint8_t kMleSecurityTagSize = 4;
static constexpr uint32_t kDefaultStoreFrameCounterAhead = OPENTHREAD_CONFIG_STORE_FRAME_COUNTER_AHEAD;
@@ -1710,23 +1704,6 @@ private:
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
class ServiceAloc : public Ip6::Netif::UnicastAddress
{
public:
static constexpr uint16_t kNotInUse = kInvalidRloc16;
ServiceAloc(void);
bool IsInUse(void) const { return GetAloc16() != kNotInUse; }
void MarkAsNotInUse(void) { SetAloc16(kNotInUse); }
uint16_t GetAloc16(void) const { return GetAddress().GetIid().GetLocator(); }
void SetAloc16(uint16_t aAloc16) { GetAddress().GetIid().SetLocator(aAloc16); }
};
#endif
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void HandleRoleRestorerTimer(void) { mPrevRoleRestorer.HandleTimer(); }
class PrevRoleRestorer : public InstanceLocator
@@ -2091,11 +2068,6 @@ private:
void UpdateRoleTimeCounters(DeviceRole aRole);
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
ServiceAloc *FindInServiceAlocs(uint16_t aAloc16);
void UpdateServiceAlocs(void);
#endif
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
void CheckTrelPeerAddrOnSecureMleRx(const Message &aMessage);
#endif
@@ -2285,9 +2257,6 @@ private:
#if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE
ParentSearch mParentSearch;
#endif
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
ServiceAloc mServiceAlocs[kMaxServiceAlocs];
#endif
#if OPENTHREAD_CONFIG_MLE_PARENT_RESPONSE_CALLBACK_API_ENABLE
Callback<otThreadParentResponseCallback> mParentResponseCallback;
#endif
+98
View File
@@ -240,6 +240,91 @@ Error Manager::RemoveService(const void *aServiceData, uint8_t aServiceDataLengt
return Get<Local>().RemoveService(kThreadEnterpriseNumber, serviceData);
}
void Manager::HandleNotifierEvents(Events aEvents)
{
ot::NetworkData::Iterator iterator;
ServiceConfig service;
uint16_t deviceRloc16;
VerifyOrExit(aEvents.Contains(kEventThreadNetdataChanged));
VerifyOrExit(!Get<Mle::Mle>().IsDisabled());
deviceRloc16 = Get<Mle::Mle>().GetRloc16();
// First remove all ALOCs which are no longer in the Network
// Data to free up space in `mServiceAlocs` array.
for (ServiceAloc &serviceAloc : mServiceAlocs)
{
bool found = false;
if (!serviceAloc.IsInUse())
{
continue;
}
iterator = kIteratorInit;
while (Get<Leader>().GetNext(iterator, deviceRloc16, service) == kErrorNone)
{
if (service.mServiceId == Mle::ServiceIdFromAloc(serviceAloc.GetAloc16()))
{
found = true;
break;
}
}
if (!found)
{
Get<ThreadNetif>().RemoveUnicastAddress(serviceAloc);
serviceAloc.MarkAsNotInUse();
}
}
// Now add any new ALOCs if there is space in `mServiceAlocs`.
iterator = kIteratorInit;
while (Get<Leader>().GetNext(iterator, deviceRloc16, service) == kErrorNone)
{
uint16_t aloc16 = Mle::ServiceAlocFromId(service.mServiceId);
if (FindInServiceAlocs(aloc16) == nullptr)
{
// No matching ALOC in `mServiceAlocs`, so we try to add it.
ServiceAloc *newServiceAloc = FindInServiceAlocs(ServiceAloc::kNotInUse);
VerifyOrExit(newServiceAloc != nullptr);
newServiceAloc->SetAloc16(aloc16);
Get<ThreadNetif>().AddUnicastAddress(*newServiceAloc);
}
}
exit:
return;
}
Manager::ServiceAloc *Manager::FindInServiceAlocs(uint16_t aAloc16)
{
// Search in `mServiceAlocs` for an entry matching `aAloc16`.
// Can be used with `aAloc16 = ServiceAloc::kNotInUse` to find
// an unused entry in the array.
ServiceAloc *match = nullptr;
for (ServiceAloc &serviceAloc : mServiceAlocs)
{
if (serviceAloc.GetAloc16() == aAloc16)
{
match = &serviceAloc;
break;
}
}
return match;
}
#endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
Error Manager::GetServiceId(uint8_t aServiceNumber, uint8_t &aServiceId) const
@@ -425,6 +510,19 @@ exit:
return error;
}
//----------------------------------------------------------------------------------------------------------------------
// Manager::ServiceAloc
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
Manager::ServiceAloc::ServiceAloc(void)
{
InitAsThreadOriginMeshLocal();
GetAddress().GetIid().SetToLocator(kNotInUse);
}
#endif
} // namespace Service
} // namespace NetworkData
} // namespace ot
+32
View File
@@ -44,8 +44,11 @@
#include "common/equatable.hpp"
#include "common/locator.hpp"
#include "common/non_copyable.hpp"
#include "common/notifier.hpp"
#include "common/serial_number.hpp"
#include "net/netif.hpp"
#include "net/socket.hpp"
#include "thread/mle_types.hpp"
#include "thread/network_data_tlvs.hpp"
namespace ot {
@@ -155,6 +158,7 @@ private:
class Manager : public InstanceLocator, private NonCopyable
{
friend class Iterator;
friend class ot::Notifier;
public:
/**
@@ -462,6 +466,27 @@ private:
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
static constexpr uint8_t kMaxServiceAlocs = OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_MAX_ALOCS + 1;
#else
static constexpr uint8_t kMaxServiceAlocs = OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_MAX_ALOCS;
#endif
class ServiceAloc : public Ip6::Netif::UnicastAddress
{
public:
static constexpr uint16_t kNotInUse = Mle::kInvalidRloc16;
ServiceAloc(void);
bool IsInUse(void) const { return GetAloc16() != kNotInUse; }
void MarkAsNotInUse(void) { SetAloc16(kNotInUse); }
uint16_t GetAloc16(void) const { return GetAddress().GetIid().GetLocator(); }
void SetAloc16(uint16_t aAloc16) { GetAddress().GetIid().SetLocator(aAloc16); }
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template <typename ServiceDataType> Error AddService(const ServiceDataType &aServiceData)
{
return AddService(&aServiceData, aServiceData.GetLength(), nullptr, 0);
@@ -492,6 +517,9 @@ private:
Error RemoveService(uint8_t aServiceNumber) { return RemoveService(&aServiceNumber, sizeof(uint8_t)); }
Error RemoveService(const void *aServiceData, uint8_t aServiceDataLength);
void HandleNotifierEvents(Events aEvents);
ServiceAloc *FindInServiceAlocs(uint16_t aAloc16);
#endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
Error GetServiceId(uint8_t aServiceNumber, uint8_t &aServiceId) const;
@@ -502,6 +530,10 @@ private:
const ServerTlv &aOtherServerTlv,
const BbrServerData &aOtherServerData) const;
#endif
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
ServiceAloc mServiceAlocs[kMaxServiceAlocs];
#endif
};
} // namespace Service