From b89d05c5fca22170558db4f3f8533be2485c3bf9 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Wed, 13 Aug 2025 10:15:24 -0700 Subject: [PATCH] [netdata] unify `GetNext...()` methods into a single template (#11812) This change updates the `NetworkData` iteration methods to reduce redundant code and simplify their use. Previously, separate methods were defined to iterate over different types of network data entries (e.g., `GetNextOnMeshPrefix()`, `GetNextExternalRoute()`). This change unifies these into a single template method, `NetworkData::GetNext()`. A similar change is applied to unify the corresponding `Contains...()` methods into a single template. --- src/core/api/border_router_api.cpp | 4 +- src/core/api/netdata_api.cpp | 9 +- src/core/api/server_api.cpp | 2 +- src/core/backbone_router/bbr_leader.cpp | 10 +- src/core/border_router/routing_manager.cpp | 12 +- src/core/net/dhcp6_client.cpp | 20 +-- src/core/net/dhcp6_server.cpp | 14 +- src/core/net/nd_agent.cpp | 14 +- src/core/thread/mle.cpp | 4 +- src/core/thread/network_data.cpp | 123 ++++------------- src/core/thread/network_data.hpp | 149 +++++++-------------- src/core/thread/network_data_leader.cpp | 21 +-- src/core/thread/network_data_types.hpp | 28 ++++ src/core/utils/history_tracker.cpp | 16 +-- src/core/utils/slaac_address.cpp | 22 +-- tests/unit/test_network_data.cpp | 10 +- 16 files changed, 186 insertions(+), 272 deletions(-) diff --git a/src/core/api/border_router_api.cpp b/src/core/api/border_router_api.cpp index ac83080a3..d000b1c56 100644 --- a/src/core/api/border_router_api.cpp +++ b/src/core/api/border_router_api.cpp @@ -87,7 +87,7 @@ otError otBorderRouterGetNextOnMeshPrefix(otInstance *aInstance, { AssertPointerIsNotNull(aIterator); - return AsCoreType(aInstance).Get().GetNextOnMeshPrefix(*aIterator, AsCoreType(aConfig)); + return AsCoreType(aInstance).Get().GetNext(*aIterator, AsCoreType(aConfig)); } otError otBorderRouterAddRoute(otInstance *aInstance, const otExternalRouteConfig *aConfig) @@ -106,7 +106,7 @@ otError otBorderRouterGetNextRoute(otInstance *aInstance, { AssertPointerIsNotNull(aIterator); - return AsCoreType(aInstance).Get().GetNextExternalRoute(*aIterator, AsCoreType(aConfig)); + return AsCoreType(aInstance).Get().GetNext(*aIterator, AsCoreType(aConfig)); } otError otBorderRouterRegister(otInstance *aInstance) diff --git a/src/core/api/netdata_api.cpp b/src/core/api/netdata_api.cpp index 9db82b122..10091c28f 100644 --- a/src/core/api/netdata_api.cpp +++ b/src/core/api/netdata_api.cpp @@ -67,7 +67,7 @@ otError otNetDataGetNextOnMeshPrefix(otInstance *aInstance, { AssertPointerIsNotNull(aIterator); - return AsCoreType(aInstance).Get().GetNextOnMeshPrefix(*aIterator, AsCoreType(aConfig)); + return AsCoreType(aInstance).Get().GetNext(*aIterator, AsCoreType(aConfig)); } #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE @@ -81,14 +81,14 @@ otError otNetDataGetNextRoute(otInstance *aInstance, otNetworkDataIterator *aIte { AssertPointerIsNotNull(aIterator); - return AsCoreType(aInstance).Get().GetNextExternalRoute(*aIterator, AsCoreType(aConfig)); + return AsCoreType(aInstance).Get().GetNext(*aIterator, AsCoreType(aConfig)); } otError otNetDataGetNextService(otInstance *aInstance, otNetworkDataIterator *aIterator, otServiceConfig *aConfig) { AssertPointerIsNotNull(aIterator); - return AsCoreType(aInstance).Get().GetNextService(*aIterator, AsCoreType(aConfig)); + return AsCoreType(aInstance).Get().GetNext(*aIterator, AsCoreType(aConfig)); } otError otNetDataGetNextLowpanContextInfo(otInstance *aInstance, @@ -97,8 +97,7 @@ otError otNetDataGetNextLowpanContextInfo(otInstance *aInstance, { AssertPointerIsNotNull(aIterator); - return AsCoreType(aInstance).Get().GetNextLowpanContextInfo(*aIterator, - AsCoreType(aContextInfo)); + return AsCoreType(aInstance).Get().GetNext(*aIterator, AsCoreType(aContextInfo)); } void otNetDataGetCommissioningDataset(otInstance *aInstance, otCommissioningDataset *aDataset) diff --git a/src/core/api/server_api.cpp b/src/core/api/server_api.cpp index 707bd5f01..7b1167bf1 100644 --- a/src/core/api/server_api.cpp +++ b/src/core/api/server_api.cpp @@ -75,7 +75,7 @@ otError otServerGetNextService(otInstance *aInstance, otNetworkDataIterator *aIt VerifyOrExit(aIterator && aConfig, error = kErrorInvalidArgs); - error = AsCoreType(aInstance).Get().GetNextService(*aIterator, AsCoreType(aConfig)); + error = AsCoreType(aInstance).Get().GetNext(*aIterator, AsCoreType(aConfig)); exit: return error; diff --git a/src/core/backbone_router/bbr_leader.cpp b/src/core/backbone_router/bbr_leader.cpp index a153fa360..f6c77b58c 100644 --- a/src/core/backbone_router/bbr_leader.cpp +++ b/src/core/backbone_router/bbr_leader.cpp @@ -226,13 +226,13 @@ void Leader::UpdateBackboneRouterPrimary(void) void Leader::UpdateDomainPrefixConfig(void) { NetworkData::Iterator iterator = NetworkData::kIteratorInit; - NetworkData::OnMeshPrefixConfig config; + NetworkData::OnMeshPrefixConfig prefixConfig; DomainPrefixEvent event; bool found = false; - while (Get().GetNextOnMeshPrefix(iterator, config) == kErrorNone) + while (Get().GetNext(iterator, prefixConfig) == kErrorNone) { - if (config.mDp) + if (prefixConfig.mDp) { found = true; break; @@ -247,14 +247,14 @@ void Leader::UpdateDomainPrefixConfig(void) mDomainPrefix.Clear(); event = kDomainPrefixRemoved; } - else if (config.GetPrefix() == mDomainPrefix) + else if (prefixConfig.GetPrefix() == mDomainPrefix) { event = kDomainPrefixUnchanged; } else { event = HasDomainPrefix() ? kDomainPrefixRefreshed : kDomainPrefixAdded; - mDomainPrefix = config.GetPrefix(); + mDomainPrefix = prefixConfig.GetPrefix(); } LogInfo("%s domain Prefix: %s", DomainPrefixEventToString(event), mDomainPrefix.ToString().AsCString()); diff --git a/src/core/border_router/routing_manager.cpp b/src/core/border_router/routing_manager.cpp index 058816a6d..64917ec4a 100644 --- a/src/core/border_router/routing_manager.cpp +++ b/src/core/border_router/routing_manager.cpp @@ -812,7 +812,7 @@ bool RoutingManager::NetworkDataContainsUlaRoute(void) const NetworkData::ExternalRouteConfig routeConfig; bool contains = false; - while (Get().GetNextExternalRoute(iterator, routeConfig) == kErrorNone) + while (Get().GetNext(iterator, routeConfig) == kErrorNone) { if (routeConfig.mStable && RoutePublisher::GetUlaPrefix().ContainsPrefix(routeConfig.GetPrefix())) { @@ -840,7 +840,7 @@ void RoutingManager::CheckReachabilityToSendIcmpError(const Message &aMessage, c // Validate that source matches a ULA OMR prefix with low preference // (indicating it is not infrastructure-derived). - while (Get().GetNextOnMeshPrefix(iterator, prefixConfig) == kErrorNone) + while (Get().GetNext(iterator, prefixConfig) == kErrorNone) { if (IsValidOmrPrefix(prefixConfig) && prefixConfig.GetPrefix().IsUniqueLocal() && aIp6Header.GetSource().MatchesPrefix(prefixConfig.GetPrefix())) @@ -1690,7 +1690,7 @@ void RoutingManager::RxRaTracker::HandleNetDataChange(void) NetworkData::OnMeshPrefixConfig prefixConfig; bool didChange = false; - while (Get().GetNextOnMeshPrefix(iterator, prefixConfig) == kErrorNone) + while (Get().GetNext(iterator, prefixConfig) == kErrorNone) { if (!IsValidOmrPrefix(prefixConfig)) { @@ -2666,7 +2666,7 @@ void RoutingManager::OmrPrefixManager::DetermineFavoredPrefixInNetData(FavoredOm aFavoredPrefix.Clear(); - while (Get().GetNextOnMeshPrefix(iterator, prefixConfig) == kErrorNone) + while (Get().GetNext(iterator, prefixConfig) == kErrorNone) { if (!IsValidOmrPrefix(prefixConfig) || !prefixConfig.mPreferred) { @@ -3636,7 +3636,7 @@ Error RoutingManager::RioAdvertiser::AppendRios(RouterAdvert::TxMessage &aRaMess iterator = NetworkData::kIteratorInit; - while (Get().GetNextOnMeshPrefix(iterator, prefixConfig) == kErrorNone) + while (Get().GetNext(iterator, prefixConfig) == kErrorNone) { // The decision to include the local OMR prefix as a RIO is // delegated to `OmrPrefixManager.ShouldAdvertiseLocalAsRio()` @@ -3662,7 +3662,7 @@ Error RoutingManager::RioAdvertiser::AppendRios(RouterAdvert::TxMessage &aRaMess iterator = NetworkData::kIteratorInit; - while (Get().GetNextOnMeshPrefix(iterator, prefixConfig) == kErrorNone) + while (Get().GetNext(iterator, prefixConfig) == kErrorNone) { if (prefixConfig.mOnMesh && !prefixConfig.mDp && !IsValidOmrPrefix(prefixConfig)) { diff --git a/src/core/net/dhcp6_client.cpp b/src/core/net/dhcp6_client.cpp index e78664621..ce3d9a353 100644 --- a/src/core/net/dhcp6_client.cpp +++ b/src/core/net/dhcp6_client.cpp @@ -65,7 +65,7 @@ void Client::UpdateAddresses(void) bool found = false; bool doesAgentExist = false; NetworkData::Iterator iterator; - NetworkData::OnMeshPrefixConfig config; + NetworkData::OnMeshPrefixConfig prefixConfig; // remove addresses directly if prefix not valid in network data for (IdentityAssociation &idAssociation : mIdentityAssociations) @@ -78,14 +78,14 @@ void Client::UpdateAddresses(void) found = false; iterator = NetworkData::kIteratorInit; - while (Get().GetNextOnMeshPrefix(iterator, config) == kErrorNone) + while (Get().GetNext(iterator, prefixConfig) == kErrorNone) { - if (!config.mDhcp) + if (!prefixConfig.mDhcp) { continue; } - if (idAssociation.mNetifAddress.HasPrefix(config.GetPrefix())) + if (idAssociation.mNetifAddress.HasPrefix(prefixConfig.GetPrefix())) { found = true; break; @@ -102,11 +102,11 @@ void Client::UpdateAddresses(void) // add IdentityAssociation for new configured prefix iterator = NetworkData::kIteratorInit; - while (Get().GetNextOnMeshPrefix(iterator, config) == kErrorNone) + while (Get().GetNext(iterator, prefixConfig) == kErrorNone) { IdentityAssociation *idAssociation = nullptr; - if (!config.mDhcp) + if (!prefixConfig.mDhcp) { continue; } @@ -124,7 +124,7 @@ void Client::UpdateAddresses(void) idAssociation = &ia; } } - else if (ia.mNetifAddress.HasPrefix(config.GetPrefix())) + else if (ia.mNetifAddress.HasPrefix(prefixConfig.GetPrefix())) { found = true; idAssociation = &ia; @@ -136,8 +136,8 @@ void Client::UpdateAddresses(void) { if (idAssociation != nullptr) { - idAssociation->mNetifAddress.mAddress = config.mPrefix.mPrefix; - idAssociation->mNetifAddress.mPrefixLength = config.mPrefix.mLength; + idAssociation->mNetifAddress.mAddress = prefixConfig.mPrefix.mPrefix; + idAssociation->mNetifAddress.mPrefixLength = prefixConfig.mPrefix.mLength; idAssociation->mStatus = kIaStatusSolicit; idAssociation->mValidLifetime = 0; } @@ -148,7 +148,7 @@ void Client::UpdateAddresses(void) } } - idAssociation->mPrefixAgentRloc = config.mRloc16; + idAssociation->mPrefixAgentRloc = prefixConfig.mRloc16; } if (doesAgentExist) diff --git a/src/core/net/dhcp6_server.cpp b/src/core/net/dhcp6_server.cpp index 167ba1aed..93bd9f2f5 100644 --- a/src/core/net/dhcp6_server.cpp +++ b/src/core/net/dhcp6_server.cpp @@ -64,7 +64,7 @@ void Server::UpdateService(void) Error error = kErrorNone; uint16_t rloc16 = Get().GetRloc16(); NetworkData::Iterator iterator; - NetworkData::OnMeshPrefixConfig config; + NetworkData::OnMeshPrefixConfig prefixConfig; Lowpan::Context lowpanContext; // remove dhcp agent aloc and prefix delegation @@ -79,9 +79,9 @@ void Server::UpdateService(void) iterator = NetworkData::kIteratorInit; - while (Get().GetNextOnMeshPrefix(iterator, rloc16, config) == kErrorNone) + while (Get().GetNext(iterator, rloc16, prefixConfig) == kErrorNone) { - if (!(config.mDhcp || config.mConfigure)) + if (!(prefixConfig.mDhcp || prefixConfig.mConfigure)) { continue; } @@ -107,18 +107,18 @@ void Server::UpdateService(void) // add dhcp agent aloc and prefix delegation iterator = NetworkData::kIteratorInit; - while (Get().GetNextOnMeshPrefix(iterator, rloc16, config) == kErrorNone) + while (Get().GetNext(iterator, rloc16, prefixConfig) == kErrorNone) { - if (!(config.mDhcp || config.mConfigure)) + if (!(prefixConfig.mDhcp || prefixConfig.mConfigure)) { continue; } - error = Get().GetContext(AsCoreType(&config.mPrefix.mPrefix), lowpanContext); + error = Get().GetContext(AsCoreType(&prefixConfig.mPrefix.mPrefix), lowpanContext); if (error == kErrorNone) { - AddPrefixAgent(config.GetPrefix(), lowpanContext); + AddPrefixAgent(prefixConfig.GetPrefix(), lowpanContext); } } diff --git a/src/core/net/nd_agent.cpp b/src/core/net/nd_agent.cpp index 5d8a38b84..e709aaac1 100644 --- a/src/core/net/nd_agent.cpp +++ b/src/core/net/nd_agent.cpp @@ -53,7 +53,7 @@ void Agent::UpdateService(void) Error error; uint16_t rloc16 = Get().GetRloc16(); NetworkData::Iterator iterator; - NetworkData::OnMeshPrefixConfig config; + NetworkData::OnMeshPrefixConfig prefixConfig; Lowpan::Context lowpanContext; if (IsAlocInUse()) @@ -64,14 +64,14 @@ void Agent::UpdateService(void) iterator = NetworkData::kIteratorInit; - while (Get().GetNextOnMeshPrefix(iterator, rloc16, config) == kErrorNone) + while (Get().GetNext(iterator, rloc16, prefixConfig) == kErrorNone) { - if (!config.mNdDns) + if (!prefixConfig.mNdDns) { continue; } - error = Get().GetContext(AsCoreType(&config.mPrefix.mPrefix), lowpanContext); + error = Get().GetContext(AsCoreType(&prefixConfig.mPrefix.mPrefix), lowpanContext); if ((error != kErrorNone) || (lowpanContext.mContextId != contextId)) { @@ -93,14 +93,14 @@ void Agent::UpdateService(void) iterator = NetworkData::kIteratorInit; - while (Get().GetNextOnMeshPrefix(iterator, rloc16, config) == kErrorNone) + while (Get().GetNext(iterator, rloc16, prefixConfig) == kErrorNone) { - if (!config.mNdDns) + if (!prefixConfig.mNdDns) { continue; } - error = Get().GetContext(AsCoreType(&config.mPrefix.mPrefix), lowpanContext); + error = Get().GetContext(AsCoreType(&prefixConfig.mPrefix.mPrefix), lowpanContext); if (error == kErrorNone) { diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index eec2a62ca..5f087c89f 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -1271,7 +1271,7 @@ void Mle::UpdateServiceAlocs(void) iterator = NetworkData::kIteratorInit; - while (Get().GetNextService(iterator, GetRloc16(), service) == kErrorNone) + while (Get().GetNext(iterator, GetRloc16(), service) == kErrorNone) { if (service.mServiceId == ServiceIdFromAloc(serviceAloc.GetAloc16())) { @@ -1291,7 +1291,7 @@ void Mle::UpdateServiceAlocs(void) iterator = NetworkData::kIteratorInit; - while (Get().GetNextService(iterator, GetRloc16(), service) == kErrorNone) + while (Get().GetNext(iterator, GetRloc16(), service) == kErrorNone) { uint16_t aloc16 = ServiceAlocFromId(service.mServiceId); diff --git a/src/core/thread/network_data.cpp b/src/core/thread/network_data.cpp index 142666dae..d0e145ba8 100644 --- a/src/core/thread/network_data.cpp +++ b/src/core/thread/network_data.cpp @@ -73,68 +73,30 @@ exit: return error; } -Error NetworkData::GetNextOnMeshPrefix(Iterator &aIterator, OnMeshPrefixConfig &aConfig) const +template Error NetworkData::GetNext(Iterator &aIterator, EntryType &aEntry) const { - return GetNextOnMeshPrefix(aIterator, Mac::kShortAddrBroadcast, aConfig); + return GetNext(aIterator, Mac::kShortAddrBroadcast, aEntry); } -Error NetworkData::GetNextOnMeshPrefix(Iterator &aIterator, uint16_t aRloc16, OnMeshPrefixConfig &aConfig) const +template Error NetworkData::GetNext(Iterator &aIterator, uint16_t aRloc16, EntryType &aEntry) const { Config config; - config.mOnMeshPrefix = &aConfig; - config.mExternalRoute = nullptr; - config.mService = nullptr; - config.mLowpanContext = nullptr; + config.Clear(); + config.Set(aEntry); return Iterate(aIterator, aRloc16, config); } -Error NetworkData::GetNextExternalRoute(Iterator &aIterator, ExternalRouteConfig &aConfig) const -{ - return GetNextExternalRoute(aIterator, Mac::kShortAddrBroadcast, aConfig); -} - -Error NetworkData::GetNextExternalRoute(Iterator &aIterator, uint16_t aRloc16, ExternalRouteConfig &aConfig) const -{ - Config config; - - config.mOnMeshPrefix = nullptr; - config.mExternalRoute = &aConfig; - config.mService = nullptr; - config.mLowpanContext = nullptr; - - return Iterate(aIterator, aRloc16, config); -} - -Error NetworkData::GetNextService(Iterator &aIterator, ServiceConfig &aConfig) const -{ - return GetNextService(aIterator, Mac::kShortAddrBroadcast, aConfig); -} - -Error NetworkData::GetNextService(Iterator &aIterator, uint16_t aRloc16, ServiceConfig &aConfig) const -{ - Config config; - - config.mOnMeshPrefix = nullptr; - config.mExternalRoute = nullptr; - config.mService = &aConfig; - config.mLowpanContext = nullptr; - - return Iterate(aIterator, aRloc16, config); -} - -Error NetworkData::GetNextLowpanContextInfo(Iterator &aIterator, LowpanContextInfo &aContextInfo) const -{ - Config config; - - config.mOnMeshPrefix = nullptr; - config.mExternalRoute = nullptr; - config.mService = nullptr; - config.mLowpanContext = &aContextInfo; - - return Iterate(aIterator, Mac::kShortAddrBroadcast, config); -} +// Explicit template instantiations +template Error NetworkData::GetNext(Iterator &, OnMeshPrefixConfig &) const; +template Error NetworkData::GetNext(Iterator &, ExternalRouteConfig &) const; +template Error NetworkData::GetNext(Iterator &, ServiceConfig &) const; +template Error NetworkData::GetNext(Iterator &, LowpanContextInfo &) const; +template Error NetworkData::GetNext(Iterator &, uint16_t, OnMeshPrefixConfig &) const; +template Error NetworkData::GetNext(Iterator &, uint16_t, ExternalRouteConfig &) const; +template Error NetworkData::GetNext(Iterator &, uint16_t, ServiceConfig &) const; +template Error NetworkData::GetNext(Iterator &, uint16_t, LowpanContextInfo &) const; Error NetworkData::Iterate(Iterator &aIterator, uint16_t aRloc16, Config &aConfig) const { @@ -313,15 +275,15 @@ exit: return error; } -bool NetworkData::ContainsOnMeshPrefix(const OnMeshPrefixConfig &aPrefix) const +template bool NetworkData::Contains(const EntryType &aEntry) const { - bool contains = false; - Iterator iterator = kIteratorInit; - OnMeshPrefixConfig prefix; + bool contains = false; + Iterator iterator = kIteratorInit; + EntryType entry; - while (GetNextOnMeshPrefix(iterator, aPrefix.mRloc16, prefix) == kErrorNone) + while (GetNext(iterator, aEntry.GetRloc16(), entry) == kErrorNone) { - if (prefix == aPrefix) + if (entry == aEntry) { contains = true; break; @@ -331,41 +293,10 @@ bool NetworkData::ContainsOnMeshPrefix(const OnMeshPrefixConfig &aPrefix) const return contains; } -bool NetworkData::ContainsExternalRoute(const ExternalRouteConfig &aRoute) const -{ - bool contains = false; - Iterator iterator = kIteratorInit; - ExternalRouteConfig route; - - while (GetNextExternalRoute(iterator, aRoute.mRloc16, route) == kErrorNone) - { - if (route == aRoute) - { - contains = true; - break; - } - } - - return contains; -} - -bool NetworkData::ContainsService(const ServiceConfig &aService) const -{ - bool contains = false; - Iterator iterator = kIteratorInit; - ServiceConfig service; - - while (GetNextService(iterator, aService.GetServerConfig().mRloc16, service) == kErrorNone) - { - if (service == aService) - { - contains = true; - break; - } - } - - return contains; -} +// Explicit template instantiations +template bool NetworkData::Contains(const OnMeshPrefixConfig &) const; +template bool NetworkData::Contains(const ExternalRouteConfig &) const; +template bool NetworkData::Contains(const ServiceConfig &) const; bool NetworkData::ContainsEntriesFrom(const NetworkData &aCompare, uint16_t aRloc16) const { @@ -386,9 +317,9 @@ bool NetworkData::ContainsEntriesFrom(const NetworkData &aCompare, uint16_t aRlo SuccessOrExit(aCompare.Iterate(iterator, aRloc16, config)); - if (((config.mOnMeshPrefix != nullptr) && !ContainsOnMeshPrefix(*config.mOnMeshPrefix)) || - ((config.mExternalRoute != nullptr) && !ContainsExternalRoute(*config.mExternalRoute)) || - ((config.mService != nullptr) && !ContainsService(*config.mService))) + if (((config.mOnMeshPrefix != nullptr) && !Contains(*config.mOnMeshPrefix)) || + ((config.mExternalRoute != nullptr) && !Contains(*config.mExternalRoute)) || + ((config.mService != nullptr) && !Contains(*config.mService))) { ExitNow(contains = false); } diff --git a/src/core/thread/network_data.hpp b/src/core/thread/network_data.hpp index 7eab9b7d7..ed3b63bed 100644 --- a/src/core/thread/network_data.hpp +++ b/src/core/thread/network_data.hpp @@ -96,7 +96,7 @@ class Publisher; class MutableNetworkData; /** - * Represents a Iterator used to iterate through Network Data info (e.g., see `GetNextOnMeshPrefix()`) + * Represents a Iterator used to iterate through Network Data info (e.g., see `GetNext()`) */ typedef otNetworkDataIterator Iterator; @@ -184,114 +184,51 @@ public: Error CopyNetworkData(Type aType, MutableNetworkData &aNetworkData) const; /** - * Provides the next On Mesh prefix in the Thread Network Data. + * Gets the next Network Data entry of a specific type (e.g., on-mesh prefix, external route, service). * - * @param[in,out] aIterator A reference to the Network Data iterator. - * @param[out] aConfig A reference to a config variable where the On Mesh Prefix information will be placed. + * @tparam EntryType The type of Network Data entry to find. It MUST be `OnMeshPrefixConfig`, + * `ExternalRouteConfig`, `ServiceConfig`, or `LowpanContextInfo`. * - * @retval kErrorNone Successfully found the next On Mesh prefix. - * @retval kErrorNotFound No subsequent On Mesh prefix exists in the Thread Network Data. + * To start iterating from the first entry, `aIterator` must be set to `kIteratorInit` before the first call. + * + * @param[in,out] aIterator A reference to an iterator to track the current position in the Network Data. + * @param[out] aEntry A reference to an object to populate with the retrieved entry's information. + * + * @retval kErrorNone Successfully found the next entry and populated @p aEntry. + * @retval kErrorNotFound No subsequent entry of the requested type exists in the Thread Network Data. */ - Error GetNextOnMeshPrefix(Iterator &aIterator, OnMeshPrefixConfig &aConfig) const; + template Error GetNext(Iterator &aIterator, EntryType &aEntry) const; /** - * Provides the next On Mesh prefix in the Thread Network Data for a given RLOC16. + * Gets the next Network Data entry of a specific type (e.g., on-mesh prefix, external route, service) associated + * with a given RLOC16. * - * @param[in,out] aIterator A reference to the Network Data iterator. - * @param[in] aRloc16 The RLOC16 value. - * @param[out] aConfig A reference to a config variable where the On Mesh Prefix information will be placed. + * @tparam EntryType The type of Network Data entry to find. It MUST be `OnMeshPrefixConfig`, + * `ExternalRouteConfig`, `ServiceConfig`, or `LowpanContextInfo`. * - * @retval kErrorNone Successfully found the next On Mesh prefix. - * @retval kErrorNotFound No subsequent On Mesh prefix exists in the Thread Network Data. + * To start iterating from the first entry, `aIterator` must be set to `kIteratorInit` before the first call. + * + * @param[in,out] aIterator An iterator to track the current position in the Network Data. + * @param[in] aRloc16 The RLOC16 to filter entries by. + * @param[out] aEntry An object to populate with the retrieved entry's information. + * + * @retval kErrorNone Successfully found the next entry and populated @p aEntry. + * @retval kErrorNotFound No subsequent entry of the requested type exists in the Thread Network Data. */ - Error GetNextOnMeshPrefix(Iterator &aIterator, uint16_t aRloc16, OnMeshPrefixConfig &aConfig) const; + template Error GetNext(Iterator &aIterator, uint16_t aRloc16, EntryType &aEntry) const; /** - * Provides the next external route in the Thread Network Data. + * Indicates whether or not the Network Data contains a given entry of specific type. * - * @param[in,out] aIterator A reference to the Network Data iterator. - * @param[out] aConfig A reference to a config variable where the external route information will be placed. + * @tparam EntryType The type of Network Data entry to find. It MUST be `OnMeshPrefixConfig`, + * `ExternalRouteConfig`, or `ServiceConfig`. * - * @retval kErrorNone Successfully found the next external route. - * @retval kErrorNotFound No subsequent external route exists in the Thread Network Data. + * @param[in] aEntry The entry to check + * + * @retval TRUE if Network Data contains an entry matching @p aEntry. + * @retval FALSE if Network Data does not contain any entry matching @p aEntry. */ - Error GetNextExternalRoute(Iterator &aIterator, ExternalRouteConfig &aConfig) const; - - /** - * Provides the next external route in the Thread Network Data for a given RLOC16. - * - * @param[in,out] aIterator A reference to the Network Data iterator. - * @param[in] aRloc16 The RLOC16 value. - * @param[out] aConfig A reference to a config variable where the external route information will be placed. - * - * @retval kErrorNone Successfully found the next external route. - * @retval kErrorNotFound No subsequent external route exists in the Thread Network Data. - */ - Error GetNextExternalRoute(Iterator &aIterator, uint16_t aRloc16, ExternalRouteConfig &aConfig) const; - - /** - * Provides the next service in the Thread Network Data. - * - * @param[in,out] aIterator A reference to the Network Data iterator. - * @param[out] aConfig A reference to a config variable where the service information will be placed. - * - * @retval kErrorNone Successfully found the next service. - * @retval kErrorNotFound No subsequent service exists in the Thread Network Data. - */ - Error GetNextService(Iterator &aIterator, ServiceConfig &aConfig) const; - - /** - * Provides the next service in the Thread Network Data for a given RLOC16. - * - * @param[in,out] aIterator A reference to the Network Data iterator. - * @param[in] aRloc16 The RLOC16 value. - * @param[out] aConfig A reference to a config variable where the service information will be placed. - * - * @retval kErrorNone Successfully found the next service. - * @retval kErrorNotFound No subsequent service exists in the Thread Network Data. - */ - Error GetNextService(Iterator &aIterator, uint16_t aRloc16, ServiceConfig &aConfig) const; - - /** - * Gets the next 6LoWPAN Context ID info in the Thread Network Data. - * - * @param[in,out] aIterator A reference to the Network Data iterator. - * @param[out] aContextInfo A reference to where the retrieved 6LoWPAN Context ID information will be placed. - * - * @retval kErrorNone Successfully found the next 6LoWPAN Context ID info. - * @retval kErrorNotFound No subsequent 6LoWPAN Context info exists in the partition's Network Data. - */ - Error GetNextLowpanContextInfo(Iterator &aIterator, LowpanContextInfo &aContextInfo) const; - - /** - * Indicates whether or not the Thread Network Data contains a given on mesh prefix entry. - * - * @param[in] aPrefix The on mesh prefix config to check. - * - * @retval TRUE if Network Data contains an on mesh prefix matching @p aPrefix. - * @retval FALSE if Network Data does not contain an on mesh prefix matching @p aPrefix. - */ - bool ContainsOnMeshPrefix(const OnMeshPrefixConfig &aPrefix) const; - - /** - * Indicates whether or not the Thread Network Data contains a given external route entry. - * - * @param[in] aRoute The external route config to check. - * - * @retval TRUE if Network Data contains an external route matching @p aRoute. - * @retval FALSE if Network Data does not contain an external route matching @p aRoute. - */ - bool ContainsExternalRoute(const ExternalRouteConfig &aRoute) const; - - /** - * Indicates whether or not the Thread Network Data contains a given service entry. - * - * @param[in] aService The service config to check. - * - * @retval TRUE if Network Data contains a service matching @p aService. - * @retval FALSE if Network Data does not contain a service matching @p aService. - */ - bool ContainsService(const ServiceConfig &aService) const; + template bool Contains(const EntryType &aEntry) const; /** * Indicates whether or not the Thread Network Data contains all the on mesh prefixes, external @@ -533,8 +470,13 @@ private: uint8_t *mIteratorBuffer; }; - struct Config + struct Config : Clearable { + void Set(OnMeshPrefixConfig &aConfig) { mOnMeshPrefix = &aConfig; } + void Set(ExternalRouteConfig &aConfig) { mExternalRoute = &aConfig; } + void Set(ServiceConfig &aConfig) { mService = &aConfig; } + void Set(LowpanContextInfo &aInfo) { mLowpanContext = &aInfo; } + OnMeshPrefixConfig *mOnMeshPrefix; ExternalRouteConfig *mExternalRoute; ServiceConfig *mService; @@ -554,6 +496,19 @@ private: uint8_t mLength; }; +// Explicit instantiation declarations +extern template Error NetworkData::GetNext(Iterator &, OnMeshPrefixConfig &) const; +extern template Error NetworkData::GetNext(Iterator &, ExternalRouteConfig &) const; +extern template Error NetworkData::GetNext(Iterator &, ServiceConfig &) const; +extern template Error NetworkData::GetNext(Iterator &, LowpanContextInfo &) const; +extern template Error NetworkData::GetNext(Iterator &, uint16_t, OnMeshPrefixConfig &) const; +extern template Error NetworkData::GetNext(Iterator &, uint16_t, ExternalRouteConfig &) const; +extern template Error NetworkData::GetNext(Iterator &, uint16_t, ServiceConfig &) const; +extern template Error NetworkData::GetNext(Iterator &, uint16_t, LowpanContextInfo &) const; +extern template bool NetworkData::Contains(const OnMeshPrefixConfig &) const; +extern template bool NetworkData::Contains(const ExternalRouteConfig &) const; +extern template bool NetworkData::Contains(const ServiceConfig &) const; + /** * Represents mutable Network Data. */ diff --git a/src/core/thread/network_data_leader.cpp b/src/core/thread/network_data_leader.cpp index 82ca120e5..cb3d29c1a 100644 --- a/src/core/thread/network_data_leader.cpp +++ b/src/core/thread/network_data_leader.cpp @@ -77,7 +77,7 @@ Error Leader::GetServiceId(uint32_t aEnterpriseNumber, ServiceConfig serviceConfig; ServiceData serviceData; - while (GetNextService(iterator, serviceConfig) == kErrorNone) + while (GetNext(iterator, serviceConfig) == kErrorNone) { serviceConfig.GetServiceData(serviceData); @@ -97,19 +97,19 @@ Error Leader::GetPreferredNat64Prefix(ExternalRouteConfig &aConfig) const { Error error = kErrorNotFound; Iterator iterator = kIteratorInit; - ExternalRouteConfig config; + ExternalRouteConfig routeConfig; - while (GetNextExternalRoute(iterator, config) == kErrorNone) + while (GetNext(iterator, routeConfig) == kErrorNone) { - if (!config.mNat64 || !config.GetPrefix().IsValidNat64()) + if (!routeConfig.mNat64 || !routeConfig.GetPrefix().IsValidNat64()) { continue; } - if ((error == kErrorNotFound) || (config.mPreference > aConfig.mPreference) || - (config.mPreference == aConfig.mPreference && config.GetPrefix() < aConfig.GetPrefix())) + if ((error == kErrorNotFound) || (routeConfig.mPreference > aConfig.mPreference) || + (routeConfig.mPreference == aConfig.mPreference && routeConfig.GetPrefix() < aConfig.GetPrefix())) { - aConfig = config; + aConfig = routeConfig; error = kErrorNone; } } @@ -121,11 +121,12 @@ bool Leader::IsNat64(const Ip6::Address &aAddress) const { bool isNat64 = false; Iterator iterator = kIteratorInit; - ExternalRouteConfig config; + ExternalRouteConfig routeConfig; - while (GetNextExternalRoute(iterator, config) == kErrorNone) + while (GetNext(iterator, routeConfig) == kErrorNone) { - if (config.mNat64 && config.GetPrefix().IsValidNat64() && aAddress.MatchesPrefix(config.GetPrefix())) + if (routeConfig.mNat64 && routeConfig.GetPrefix().IsValidNat64() && + aAddress.MatchesPrefix(routeConfig.GetPrefix())) { isNat64 = true; break; diff --git a/src/core/thread/network_data_types.hpp b/src/core/thread/network_data_types.hpp index d0188c913..9613faa9b 100644 --- a/src/core/thread/network_data_types.hpp +++ b/src/core/thread/network_data_types.hpp @@ -204,6 +204,13 @@ public: */ Ip6::Prefix &GetPrefix(void) { return AsCoreType(&mPrefix); } + /** + * Gets the RLOC16. + * + * @returns The RLOC16. + */ + uint16_t GetRloc16(void) const { return mRloc16; } + /** * Gets the preference. * @@ -266,6 +273,13 @@ public: */ void SetPrefix(const Ip6::Prefix &aPrefix) { mPrefix = aPrefix; } + /** + * Gets the RLOC16. + * + * @returns The RLOC16. + */ + uint16_t GetRloc16(void) const { return mRloc16; } + #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE /** * Indicates whether or not the external route configuration is valid. @@ -346,6 +360,13 @@ public: */ void GetServerData(ServerData &aServerData) const { aServerData.Init(mServerData, mServerDataLength); } + /** + * Gets the server RLOC16. + * + * @returns The server RLOC16. + */ + uint16_t GetRloc16(void) const { return mRloc16; } + /** * Overloads operator `==` to evaluate whether or not two `ServerConfig` instances are equal. * @@ -381,6 +402,13 @@ public: */ ServerConfig &GetServerConfig(void) { return static_cast(mServerConfig); } + /** + * Gets the RLOC16. + * + * @returns The RLOC16. + */ + uint16_t GetRloc16(void) const { return GetServerConfig().GetRloc16(); } + /** * Overloads operator `==` to evaluate whether or not two `ServiceConfig` instances are equal. * diff --git a/src/core/utils/history_tracker.cpp b/src/core/utils/history_tracker.cpp index 1a7ce2fc3..254f3bf19 100644 --- a/src/core/utils/history_tracker.cpp +++ b/src/core/utils/history_tracker.cpp @@ -364,9 +364,9 @@ void Local::RecordNetworkDataChange(void) iterator = NetworkData::kIteratorInit; - while (mPreviousNetworkData.GetNextOnMeshPrefix(iterator, prefix) == kErrorNone) + while (mPreviousNetworkData.GetNext(iterator, prefix) == kErrorNone) { - if (!Get().ContainsOnMeshPrefix(prefix)) + if (!Get().Contains(prefix)) { RecordOnMeshPrefixEvent(kNetDataEntryRemoved, prefix); } @@ -374,9 +374,9 @@ void Local::RecordNetworkDataChange(void) iterator = NetworkData::kIteratorInit; - while (Get().GetNextOnMeshPrefix(iterator, prefix) == kErrorNone) + while (Get().GetNext(iterator, prefix) == kErrorNone) { - if (!mPreviousNetworkData.ContainsOnMeshPrefix(prefix)) + if (!mPreviousNetworkData.Contains(prefix)) { RecordOnMeshPrefixEvent(kNetDataEntryAdded, prefix); } @@ -386,9 +386,9 @@ void Local::RecordNetworkDataChange(void) iterator = NetworkData::kIteratorInit; - while (mPreviousNetworkData.GetNextExternalRoute(iterator, route) == kErrorNone) + while (mPreviousNetworkData.GetNext(iterator, route) == kErrorNone) { - if (!Get().ContainsExternalRoute(route)) + if (!Get().Contains(route)) { RecordExternalRouteEvent(kNetDataEntryRemoved, route); } @@ -396,9 +396,9 @@ void Local::RecordNetworkDataChange(void) iterator = NetworkData::kIteratorInit; - while (Get().GetNextExternalRoute(iterator, route) == kErrorNone) + while (Get().GetNext(iterator, route) == kErrorNone) { - if (!mPreviousNetworkData.ContainsExternalRoute(route)) + if (!mPreviousNetworkData.Contains(route)) { RecordExternalRouteEvent(kNetDataEntryAdded, route); } diff --git a/src/core/utils/slaac_address.cpp b/src/core/utils/slaac_address.cpp index 575232a51..9f0f0296b 100644 --- a/src/core/utils/slaac_address.cpp +++ b/src/core/utils/slaac_address.cpp @@ -171,7 +171,7 @@ void Slaac::RemoveOrDeprecateAddresses(void) for (SlaacAddress &slaacAddr : mSlaacAddresses) { NetworkData::Iterator iterator; - NetworkData::OnMeshPrefixConfig config; + NetworkData::OnMeshPrefixConfig prefixConfig; bool found = false; if (!slaacAddr.IsInUse()) @@ -181,9 +181,9 @@ void Slaac::RemoveOrDeprecateAddresses(void) iterator = NetworkData::kIteratorInit; - while (Get().GetNextOnMeshPrefix(iterator, config) == kErrorNone) + while (Get().GetNext(iterator, prefixConfig) == kErrorNone) { - if (IsSlaac(config) && DoesConfigMatchNetifAddr(config, slaacAddr)) + if (IsSlaac(prefixConfig) && DoesConfigMatchNetifAddr(prefixConfig, slaacAddr)) { found = true; break; @@ -192,7 +192,7 @@ void Slaac::RemoveOrDeprecateAddresses(void) if (found) { - if (IsFiltered(config)) + if (IsFiltered(prefixConfig)) { RemoveAddress(slaacAddr); } @@ -252,26 +252,26 @@ void Slaac::RemoveAddress(SlaacAddress &aAddress) void Slaac::AddAddresses(void) { NetworkData::Iterator iterator; - NetworkData::OnMeshPrefixConfig config; + NetworkData::OnMeshPrefixConfig prefixConfig; // Generate and add SLAAC addresses for any newly added on-mesh prefixes. iterator = NetworkData::kIteratorInit; - while (Get().GetNextOnMeshPrefix(iterator, config) == kErrorNone) + while (Get().GetNext(iterator, prefixConfig) == kErrorNone) { bool found = false; - if (!IsSlaac(config) || IsFiltered(config)) + if (!IsSlaac(prefixConfig) || IsFiltered(prefixConfig)) { continue; } for (SlaacAddress &slaacAddr : mSlaacAddresses) { - if (slaacAddr.IsInUse() && DoesConfigMatchNetifAddr(config, slaacAddr)) + if (slaacAddr.IsInUse() && DoesConfigMatchNetifAddr(prefixConfig, slaacAddr)) { - if (slaacAddr.IsDeprecating() && config.mPreferred) + if (slaacAddr.IsDeprecating() && prefixConfig.mPreferred) { slaacAddr.MarkAsNotDeprecating(); Get().UpdatePreferredFlagOn(slaacAddr, true); @@ -289,7 +289,7 @@ void Slaac::AddAddresses(void) for (const Ip6::Netif::UnicastAddress &netifAddr : Get().GetUnicastAddresses()) { - if (DoesConfigMatchNetifAddr(config, netifAddr)) + if (DoesConfigMatchNetifAddr(prefixConfig, netifAddr)) { found = true; break; @@ -298,7 +298,7 @@ void Slaac::AddAddresses(void) if (!found) { - AddAddressFor(config); + AddAddressFor(prefixConfig); } } } diff --git a/tests/unit/test_network_data.cpp b/tests/unit/test_network_data.cpp index 635f58638..e308fdf5a 100644 --- a/tests/unit/test_network_data.cpp +++ b/tests/unit/test_network_data.cpp @@ -179,12 +179,12 @@ void TestNetworkDataIterator(void) for (const auto &route : routes) { - SuccessOrQuit(netData.GetNextExternalRoute(iter, rconfig)); + SuccessOrQuit(netData.GetNext(iter, rconfig)); PrintExternalRouteConfig(rconfig); VerifyOrQuit(CompareExternalRouteConfig(rconfig, route)); } - VerifyOrQuit(netData.GetNextExternalRoute(iter, rconfig) == kErrorNotFound); + VerifyOrQuit(netData.GetNext(iter, rconfig) == kErrorNotFound); netData.FindRlocs(kAnyBrOrServer, kAnyRole, rlocs); VerifyRlocsArray(rlocs, kRlocs); @@ -303,7 +303,7 @@ void TestNetworkDataIterator(void) for (const auto &route : routes) { - SuccessOrQuit(netData.GetNextExternalRoute(iter, rconfig)); + SuccessOrQuit(netData.GetNext(iter, rconfig)); PrintExternalRouteConfig(rconfig); VerifyOrQuit(CompareExternalRouteConfig(rconfig, route)); } @@ -471,7 +471,7 @@ void TestNetworkDataIterator(void) for (const auto &route : routes) { - SuccessOrQuit(netData.GetNextExternalRoute(iter, rconfig)); + SuccessOrQuit(netData.GetNext(iter, rconfig)); PrintExternalRouteConfig(rconfig); VerifyOrQuit(CompareExternalRouteConfig(rconfig, route)); } @@ -480,7 +480,7 @@ void TestNetworkDataIterator(void) for (const auto &prefix : prefixes) { - SuccessOrQuit(netData.GetNextOnMeshPrefix(iter, pconfig)); + SuccessOrQuit(netData.GetNext(iter, pconfig)); PrintOnMeshPrefixConfig(pconfig); VerifyOrQuit(CompareOnMeshPrefixConfig(pconfig, prefix)); }