[netdata] add FindRlocs() to retrieve RLOC16 of entries (#9961)

This commit introduces `NetworkData::FindRlocs()` which returns the
list of RLCO16 of all border routers and servers in the Network Data
matching specified filter conditions. The `BorderRouterFilter` can be
used to filter the entry type. It can be set to `kAnyBrOrServer` to
include all BRs and servers, or `kBrProvidingExternalIpConn` to
restrict the list to BRs providing external IP connectivity. The new
`FindRlocs()` replaces `FindBorderRouters()` and `GetNextServer()`
methods and helps simplify the code. Unit test `test_network_data`
is updated to validate the new method.
This commit is contained in:
Abtin Keshavarzian
2024-03-25 13:18:19 -07:00
committed by GitHub
parent 13ab3a606c
commit 09aa9630aa
6 changed files with 218 additions and 243 deletions
+73 -147
View File
@@ -675,177 +675,103 @@ void MutableNetworkData::Remove(void *aRemoveStart, uint8_t aRemoveLength)
void MutableNetworkData::RemoveTlv(NetworkDataTlv *aTlv) { Remove(aTlv, aTlv->GetSize()); }
Error NetworkData::GetNextServer(Iterator &aIterator, uint16_t &aRloc16) const
void NetworkData::FindRlocs(BorderRouterFilter aBrFilter, RoleFilter aRoleFilter, Rlocs &aRlocs) const
{
Error error;
OnMeshPrefixConfig prefixConfig;
ExternalRouteConfig routeConfig;
ServiceConfig serviceConfig;
Iterator iterator = kIteratorInit;
OnMeshPrefixConfig prefix;
ExternalRouteConfig route;
ServiceConfig service;
Config config;
config.mOnMeshPrefix = &prefixConfig;
config.mExternalRoute = &routeConfig;
config.mService = &serviceConfig;
config.mLowpanContext = nullptr;
aRlocs.Clear();
SuccessOrExit(error = Iterate(aIterator, Mac::kShortAddrBroadcast, config));
while (true)
{
config.mOnMeshPrefix = &prefix;
config.mExternalRoute = &route;
config.mService = &service;
config.mLowpanContext = nullptr;
if (config.mOnMeshPrefix != nullptr)
{
aRloc16 = config.mOnMeshPrefix->mRloc16;
}
else if (config.mExternalRoute != nullptr)
{
aRloc16 = config.mExternalRoute->mRloc16;
}
else if (config.mService != nullptr)
{
aRloc16 = config.mService->mServerConfig.mRloc16;
}
else
{
OT_ASSERT(false);
SuccessOrExit(Iterate(iterator, Mac::kShortAddrBroadcast, config));
if (config.mOnMeshPrefix != nullptr)
{
bool matches = true;
switch (aBrFilter)
{
case kAnyBrOrServer:
break;
case kBrProvidingExternalIpConn:
matches = prefix.mOnMesh && (prefix.mDefaultRoute || prefix.mDp);
break;
}
if (matches)
{
AddRloc16ToRlocs(prefix.mRloc16, aRlocs, aRoleFilter);
}
}
else if (config.mExternalRoute != nullptr)
{
AddRloc16ToRlocs(route.mRloc16, aRlocs, aRoleFilter);
}
else if (config.mService != nullptr)
{
switch (aBrFilter)
{
case kAnyBrOrServer:
AddRloc16ToRlocs(service.mServerConfig.mRloc16, aRlocs, aRoleFilter);
break;
case kBrProvidingExternalIpConn:
break;
}
}
}
exit:
return error;
}
Error NetworkData::FindBorderRouters(RoleFilter aRoleFilter, uint16_t aRlocs[], uint8_t &aRlocsLength) const
{
class Rlocs // Wrapper over an array of RLOC16s.
{
public:
Rlocs(RoleFilter aRoleFilter, uint16_t *aRlocs, uint8_t aRlocsMaxLength)
: mRoleFilter(aRoleFilter)
, mRlocs(aRlocs)
, mLength(0)
, mMaxLength(aRlocsMaxLength)
{
}
uint8_t GetLength(void) const { return mLength; }
Error AddRloc16(uint16_t aRloc16)
{
// Add `aRloc16` into the array if it matches `RoleFilter` and
// it is not in the array already. If we need to add the `aRloc16`
// but there is no more room in the array, return `kErrorNoBufs`.
Error error = kErrorNone;
uint8_t index;
switch (mRoleFilter)
{
case kAnyRole:
break;
case kRouterRoleOnly:
VerifyOrExit(Mle::IsActiveRouter(aRloc16));
break;
case kChildRoleOnly:
VerifyOrExit(!Mle::IsActiveRouter(aRloc16));
break;
}
for (index = 0; index < mLength; index++)
{
if (mRlocs[index] == aRloc16)
{
break;
}
}
if (index == mLength)
{
VerifyOrExit(mLength < mMaxLength, error = kErrorNoBufs);
mRlocs[mLength++] = aRloc16;
}
exit:
return error;
}
private:
RoleFilter mRoleFilter;
uint16_t *mRlocs;
uint8_t mLength;
uint8_t mMaxLength;
};
Error error = kErrorNone;
Rlocs rlocs(aRoleFilter, aRlocs, aRlocsLength);
Iterator iterator = kIteratorInit;
ExternalRouteConfig route;
OnMeshPrefixConfig prefix;
while (GetNextExternalRoute(iterator, route) == kErrorNone)
{
SuccessOrExit(error = rlocs.AddRloc16(route.mRloc16));
}
iterator = kIteratorInit;
while (GetNextOnMeshPrefix(iterator, prefix) == kErrorNone)
{
if (!prefix.mDefaultRoute || !prefix.mOnMesh)
{
continue;
}
SuccessOrExit(error = rlocs.AddRloc16(prefix.mRloc16));
}
exit:
aRlocsLength = rlocs.GetLength();
return error;
return;
}
uint8_t NetworkData::CountBorderRouters(RoleFilter aRoleFilter) const
{
// We use an over-estimate of max number of border routers in the
// Network Data using the facts that network data is limited to 254
// bytes and that an external route entry uses at minimum 3 bytes
// for RLOC16 and flag, so `ceil(254/3) = 85`.
Rlocs rlocs;
static constexpr uint16_t kMaxRlocs = 85;
FindRlocs(kBrProvidingExternalIpConn, aRoleFilter, rlocs);
uint16_t rlocs[kMaxRlocs];
uint8_t rlocsLength = kMaxRlocs;
SuccessOrAssert(FindBorderRouters(aRoleFilter, rlocs, rlocsLength));
return rlocsLength;
return rlocs.GetLength();
}
bool NetworkData::ContainsBorderRouterWithRloc(uint16_t aRloc16) const
{
bool contains = false;
Iterator iterator = kIteratorInit;
ExternalRouteConfig route;
OnMeshPrefixConfig prefix;
Rlocs rlocs;
while (GetNextExternalRoute(iterator, route) == kErrorNone)
FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
return rlocs.Contains(aRloc16);
}
void NetworkData::AddRloc16ToRlocs(uint16_t aRloc16, Rlocs &aRlocs, RoleFilter aRoleFilter)
{
switch (aRoleFilter)
{
if (route.mRloc16 == aRloc16)
{
ExitNow(contains = true);
}
case kAnyRole:
break;
case kRouterRoleOnly:
VerifyOrExit(Mle::IsActiveRouter(aRloc16));
break;
case kChildRoleOnly:
VerifyOrExit(!Mle::IsActiveRouter(aRloc16));
break;
}
iterator = kIteratorInit;
while (GetNextOnMeshPrefix(iterator, prefix) == kErrorNone)
{
if ((prefix.mRloc16 == aRloc16) && prefix.mOnMesh && (prefix.mDefaultRoute || prefix.mDp))
{
ExitNow(contains = true);
}
}
VerifyOrExit(!aRlocs.Contains(aRloc16));
IgnoreError(aRlocs.PushBack(aRloc16));
exit:
return contains;
return;
}
Error NetworkData::FindDomainIdFor(const Ip6::Prefix &aPrefix, uint8_t &aDomainId) const
+15 -25
View File
@@ -324,18 +324,6 @@ public:
*/
bool ContainsEntriesFrom(const NetworkData &aCompare, uint16_t aRloc16) const;
/**
* Provides the next server RLOC16 in the Thread Network Data.
*
* @param[in,out] aIterator A reference to the Network Data iterator.
* @param[out] aRloc16 The RLOC16 value.
*
* @retval kErrorNone Successfully found the next server.
* @retval kErrorNotFound No subsequent server exists in the Thread Network Data.
*
*/
Error GetNextServer(Iterator &aIterator, uint16_t &aRloc16) const;
/**
* Finds and returns Domain ID associated with a given prefix in the Thread Network data.
*
@@ -349,30 +337,30 @@ public:
Error FindDomainIdFor(const Ip6::Prefix &aPrefix, uint8_t &aDomainId) const;
/**
* Finds and returns the list of RLOCs of border routers providing external IP connectivity.
* Finds border routers and servers in the Network Data matching specified filters, returning their RLOC16s.
*
* A border router is considered to provide external IP connectivity if it has added at least one external route
* entry, or an on-mesh prefix with default-route and on-mesh flags set.
* @p aBrFilter can be used to filter the type of BRs. It can be set to `kAnyBrOrServer` to include all BRs and
* servers. `kBrProvidingExternalIpConn` restricts it to BRs providing external IP connectivity where at least one
* the below conditions hold:
*
* - It has added at least one external route entry.
* - It has added at least one prefix entry with default-route and on-mesh flags set.
* - It has added at least one domain prefix (domain and on-mesh flags set).
*
* Should be used when the RLOC16s are present in the Network Data (when the Network Data contains the
* full set and not the stable subset).
*
* @param[in] aRoleFilter Indicates which devices to include (any role, router role only, or child only).
* @param[out] aRlocs Array to output the list of RLOCs.
* @param[in,out] aRlocsLength On entry, @p aRlocs array length (max number of elements).
* On exit, number RLOC16 entries added in @p aRlocs.
*
* @retval kErrorNone Successfully found all RLOC16s and updated @p aRlocs and @p aRlocsLength.
* @retval kErrorNoBufs Ran out of space in @p aRlocs array. @p aRlocs and @p aRlocsLength are still updated up
* to the maximum array length.
* @param[in] aBrFilter Indicates BR filter.
* @param[in] aRoleFilter Indicates role filter (any role, router role only, or child only).
* @param[out] aRlocs Array to output the list of RLOC16s.
*
*/
Error FindBorderRouters(RoleFilter aRoleFilter, uint16_t aRlocs[], uint8_t &aRlocsLength) const;
void FindRlocs(BorderRouterFilter aBrFilter, RoleFilter aRoleFilter, Rlocs &aRlocs) const;
/**
* Counts the number of border routers providing external IP connectivity.
*
* A border router is considered to provide external IP connectivity if at least one of the below conditions hold
* A border router is considered to provide external IP connectivity if at least one of the below conditions hold:
*
* - It has added at least one external route entry.
* - It has added at least one prefix entry with default-route and on-mesh flags set.
@@ -591,6 +579,8 @@ private:
const ServiceData &aServiceData,
ServiceMatchMode aServiceMatchMode);
static void AddRloc16ToRlocs(uint16_t aRloc16, Rlocs &aRlocs, RoleFilter aRoleFilter);
const uint8_t *mTlvs;
uint8_t mLength;
};
+7 -10
View File
@@ -1218,10 +1218,10 @@ void Leader::HandleNetworkDataRestoredAfterReset(void)
{
const PrefixTlv *prefix;
TlvIterator tlvIterator(GetTlvsStart(), GetTlvsEnd());
Iterator iterator = kIteratorInit;
ChangedFlags flags;
uint16_t rloc16;
uint16_t sessionId;
Rlocs rlocs;
mWaitingForNetDataSync = false;
@@ -1232,16 +1232,13 @@ void Leader::HandleNetworkDataRestoredAfterReset(void)
// got the chance to send the updated Network Data to other
// routers.
while (GetNextServer(iterator, rloc16) == kErrorNone)
{
if (!Get<RouterTable>().IsAllocated(Mle::RouterIdFromRloc16(rloc16)))
{
// After we `RemoveRloc()` the Network Data gets changed
// and the `iterator` will not be valid anymore. So we set
// it to `kIteratorInit` to restart the loop.
FindRlocs(kAnyBrOrServer, kAnyRole, rlocs);
RemoveRloc(rloc16, kMatchModeRouterId, flags);
iterator = kIteratorInit;
for (uint16_t rloc : rlocs)
{
if (!Get<RouterTable>().IsAllocated(Mle::RouterIdFromRloc16(rloc)))
{
RemoveRloc(rloc, kMatchModeRouterId, flags);
}
}
+5 -4
View File
@@ -129,13 +129,14 @@ Error Notifier::RemoveStaleChildEntries(void)
// - `kErrorNoBufs` if could not allocate message to send message.
// - `kErrorNotFound` if no stale child entries were found.
Error error = kErrorNotFound;
Iterator iterator = kIteratorInit;
uint16_t rloc16;
Error error = kErrorNotFound;
Rlocs rlocs;
VerifyOrExit(Get<Mle::MleRouter>().IsRouterOrLeader());
while (Get<Leader>().GetNextServer(iterator, rloc16) == kErrorNone)
Get<Leader>().FindRlocs(kAnyBrOrServer, kAnyRole, rlocs);
for (uint16_t rloc16 : rlocs)
{
if (!Mle::IsActiveRouter(rloc16) && Mle::RouterIdMatch(Get<Mle::MleRouter>().GetRloc16(), rloc16) &&
Get<ChildTable>().FindChild(rloc16, Child::kInStateValid) == nullptr)
+33
View File
@@ -38,6 +38,7 @@
#include <openthread/netdata.h>
#include "common/array.hpp"
#include "common/as_core_type.hpp"
#include "common/clearable.hpp"
#include "common/data.hpp"
@@ -107,6 +108,38 @@ enum RoleFilter : uint8_t
kChildRoleOnly, ///< Include devices that act as Thread child (end-device).
};
/**
* Represents the entry filter used when searching for RLOC16 of border routers or servers in the Network Data.
*
* Regarding `kBrProvidingExternalIpConn`, a border router is considered to provide external IP connectivity if at
* least one of the below conditions hold:
*
* - It has added at least one external route entry.
* - It has added at least one prefix entry with default-route and on-mesh flags set.
* - It has added at least one domain prefix (domain and on-mesh flags set).
*
*/
enum BorderRouterFilter : uint8_t
{
kAnyBrOrServer, ///< Include any border router or server entry.
kBrProvidingExternalIpConn, ///< Include border routers providing external IP connectivity.
};
/**
* Maximum length of `Rlocs` array containing RLOC16 of all border routers and servers in the Network Data.
*
* This limit is derived from the maximum Network Data size (254 bytes) and the minimum size of an external route entry
* (3 bytes including the RLOC16 and flags) as `ceil(254/3) = 85`.
*
*/
static constexpr uint8_t kMaxRlocs = 85;
/**
* An array containing RLOC16 of all border routers and server in the Network Data.
*
*/
typedef Array<uint16_t, kMaxRlocs> Rlocs;
/**
* Indicates whether a given `int8_t` preference value is a valid route preference (i.e., one of the
* values from `RoutePreference` enumeration).
+85 -57
View File
@@ -86,32 +86,32 @@ bool CompareOnMeshPrefixConfig(const otBorderRouterConfig &aConfig1, const otBor
(aConfig1.mDefaultRoute == aConfig2.mDefaultRoute) && (aConfig1.mOnMesh == aConfig2.mOnMesh);
}
template <uint8_t kLength>
void VerifyRlocsArray(const uint16_t *aRlocs, uint16_t aRlocsLength, const uint16_t (&aExpectedRlocs)[kLength])
template <uint8_t kLength> void VerifyRlocsArray(const Rlocs &aRlocs, const uint16_t (&aExpectedRlocs)[kLength])
{
VerifyOrQuit(aRlocsLength == kLength);
VerifyOrQuit(aRlocs.GetLength() == kLength);
printf("\nRLOCs: { ");
for (uint16_t index = 0; index < aRlocsLength; index++)
for (uint16_t rloc : aRlocs)
{
VerifyOrQuit(aRlocs[index] == aExpectedRlocs[index]);
printf("0x%04x ", aRlocs[index]);
printf("0x%04x ", rloc);
}
printf("}");
for (uint16_t index = 0; index < kLength; index++)
{
VerifyOrQuit(aRlocs.Contains(aExpectedRlocs[index]));
}
}
void TestNetworkDataIterator(void)
{
static constexpr uint8_t kMaxRlocsArray = 10;
Instance *instance;
Iterator iter = kIteratorInit;
ExternalRouteConfig rconfig;
OnMeshPrefixConfig pconfig;
uint16_t rlocs[kMaxRlocsArray];
uint8_t rlocsLength;
Rlocs rlocs;
instance = testInitInstance();
VerifyOrQuit(instance != nullptr);
@@ -168,19 +168,25 @@ void TestNetworkDataIterator(void)
VerifyOrQuit(CompareExternalRouteConfig(rconfig, route));
}
rlocsLength = GetArrayLength(rlocs);
SuccessOrQuit(netData.FindBorderRouters(kAnyRole, rlocs, rlocsLength));
VerifyRlocsArray(rlocs, rlocsLength, kRlocs);
netData.FindRlocs(kAnyBrOrServer, kAnyRole, rlocs);
VerifyRlocsArray(rlocs, kRlocs);
netData.FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs);
VerifyRlocsArray(rlocs, kRlocs);
netData.FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs);
VerifyOrQuit(rlocs.GetLength() == 0);
netData.FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
VerifyRlocsArray(rlocs, kRlocs);
VerifyOrQuit(netData.CountBorderRouters(kAnyRole) == GetArrayLength(kRlocs));
rlocsLength = GetArrayLength(rlocs);
SuccessOrQuit(netData.FindBorderRouters(kRouterRoleOnly, rlocs, rlocsLength));
VerifyRlocsArray(rlocs, rlocsLength, kRlocs);
netData.FindRlocs(kBrProvidingExternalIpConn, kRouterRoleOnly, rlocs);
VerifyRlocsArray(rlocs, kRlocs);
VerifyOrQuit(netData.CountBorderRouters(kRouterRoleOnly) == GetArrayLength(kRlocs));
rlocsLength = GetArrayLength(rlocs);
SuccessOrQuit(netData.FindBorderRouters(kChildRoleOnly, rlocs, rlocsLength));
VerifyOrQuit(rlocsLength == 0);
netData.FindRlocs(kBrProvidingExternalIpConn, kChildRoleOnly, rlocs);
VerifyOrQuit(rlocs.GetLength() == 0);
VerifyOrQuit(netData.CountBorderRouters(kChildRoleOnly) == 0);
for (uint16_t rloc16 : kRlocs)
@@ -284,33 +290,29 @@ void TestNetworkDataIterator(void)
VerifyOrQuit(CompareExternalRouteConfig(rconfig, route));
}
rlocsLength = GetArrayLength(rlocs);
SuccessOrQuit(netData.FindBorderRouters(kAnyRole, rlocs, rlocsLength));
VerifyRlocsArray(rlocs, rlocsLength, kRlocsAnyRole);
netData.FindRlocs(kAnyBrOrServer, kAnyRole, rlocs);
VerifyRlocsArray(rlocs, kRlocsAnyRole);
netData.FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs);
VerifyRlocsArray(rlocs, kRlocsRouterRole);
netData.FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs);
VerifyRlocsArray(rlocs, kRlocsChildRole);
netData.FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
VerifyRlocsArray(rlocs, kRlocsAnyRole);
VerifyOrQuit(netData.CountBorderRouters(kAnyRole) == GetArrayLength(kRlocsAnyRole));
rlocsLength = GetArrayLength(rlocs);
SuccessOrQuit(netData.FindBorderRouters(kRouterRoleOnly, rlocs, rlocsLength));
VerifyRlocsArray(rlocs, rlocsLength, kRlocsRouterRole);
netData.FindRlocs(kBrProvidingExternalIpConn, kRouterRoleOnly, rlocs);
VerifyRlocsArray(rlocs, kRlocsRouterRole);
VerifyOrQuit(netData.CountBorderRouters(kRouterRoleOnly) == GetArrayLength(kRlocsRouterRole));
rlocsLength = GetArrayLength(rlocs);
SuccessOrQuit(netData.FindBorderRouters(kChildRoleOnly, rlocs, rlocsLength));
VerifyRlocsArray(rlocs, rlocsLength, kRlocsChildRole);
netData.FindRlocs(kBrProvidingExternalIpConn, kChildRoleOnly, rlocs);
VerifyRlocsArray(rlocs, kRlocsChildRole);
VerifyOrQuit(netData.CountBorderRouters(kChildRoleOnly) == GetArrayLength(kRlocsChildRole));
// Test failure case when given array is smaller than number of RLOCs.
rlocsLength = GetArrayLength(kRlocsAnyRole) - 1;
VerifyOrQuit(netData.FindBorderRouters(kAnyRole, rlocs, rlocsLength) == kErrorNoBufs);
VerifyOrQuit(rlocsLength == GetArrayLength(kRlocsAnyRole) - 1);
for (uint8_t index = 0; index < rlocsLength; index++)
{
VerifyOrQuit(rlocs[index] == kRlocsAnyRole[index]);
}
rlocsLength = GetArrayLength(kRlocsAnyRole);
SuccessOrQuit(netData.FindBorderRouters(kAnyRole, rlocs, rlocsLength));
VerifyRlocsArray(rlocs, rlocsLength, kRlocsAnyRole);
netData.FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
VerifyRlocsArray(rlocs, kRlocsAnyRole);
for (uint16_t rloc16 : kRlocsAnyRole)
{
@@ -434,10 +436,13 @@ void TestNetworkDataIterator(void)
},
};
const uint16_t kRlocsAnyRole[] = {0xec00, 0x2801, 0x2800};
const uint16_t kRlocsRouterRole[] = {0xec00, 0x2800};
const uint16_t kRlocsChildRole[] = {0x2801};
const uint16_t kNonExistingRlocs[] = {0x6000, 0x0000, 0x2806, 0x4c00};
const uint16_t kRlocsAnyRole[] = {0xec00, 0x2801, 0x2800, 0x4c00};
const uint16_t kRlocsRouterRole[] = {0xec00, 0x2800, 0x4c00};
const uint16_t kRlocsChildRole[] = {0x2801};
const uint16_t kBrRlocsAnyRole[] = {0xec00, 0x2801, 0x2800};
const uint16_t kBrRlocsRouterRole[] = {0xec00, 0x2800};
const uint16_t kBrRlocsChildRole[] = {0x2801};
const uint16_t kNonExistingRlocs[] = {0x6000, 0x0000, 0x2806, 0x4c00};
NetworkData netData(*instance, kNetworkData, sizeof(kNetworkData));
@@ -462,22 +467,28 @@ void TestNetworkDataIterator(void)
VerifyOrQuit(CompareOnMeshPrefixConfig(pconfig, prefix));
}
rlocsLength = GetArrayLength(rlocs);
SuccessOrQuit(netData.FindBorderRouters(kAnyRole, rlocs, rlocsLength));
VerifyRlocsArray(rlocs, rlocsLength, kRlocsAnyRole);
VerifyOrQuit(netData.CountBorderRouters(kAnyRole) == GetArrayLength(kRlocsAnyRole));
netData.FindRlocs(kAnyBrOrServer, kAnyRole, rlocs);
VerifyRlocsArray(rlocs, kRlocsAnyRole);
rlocsLength = GetArrayLength(rlocs);
SuccessOrQuit(netData.FindBorderRouters(kRouterRoleOnly, rlocs, rlocsLength));
VerifyRlocsArray(rlocs, rlocsLength, kRlocsRouterRole);
VerifyOrQuit(netData.CountBorderRouters(kRouterRoleOnly) == GetArrayLength(kRlocsRouterRole));
netData.FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs);
VerifyRlocsArray(rlocs, kRlocsRouterRole);
rlocsLength = GetArrayLength(rlocs);
SuccessOrQuit(netData.FindBorderRouters(kChildRoleOnly, rlocs, rlocsLength));
VerifyRlocsArray(rlocs, rlocsLength, kRlocsChildRole);
VerifyOrQuit(netData.CountBorderRouters(kChildRoleOnly) == GetArrayLength(kRlocsChildRole));
netData.FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs);
VerifyRlocsArray(rlocs, kRlocsChildRole);
for (uint16_t rloc16 : kRlocsAnyRole)
netData.FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
VerifyRlocsArray(rlocs, kBrRlocsAnyRole);
VerifyOrQuit(netData.CountBorderRouters(kAnyRole) == GetArrayLength(kBrRlocsAnyRole));
netData.FindRlocs(kBrProvidingExternalIpConn, kRouterRoleOnly, rlocs);
VerifyRlocsArray(rlocs, kBrRlocsRouterRole);
VerifyOrQuit(netData.CountBorderRouters(kRouterRoleOnly) == GetArrayLength(kBrRlocsRouterRole));
netData.FindRlocs(kBrProvidingExternalIpConn, kChildRoleOnly, rlocs);
VerifyRlocsArray(rlocs, kBrRlocsChildRole);
VerifyOrQuit(netData.CountBorderRouters(kChildRoleOnly) == GetArrayLength(kBrRlocsChildRole));
for (uint16_t rloc16 : kBrRlocsAnyRole)
{
VerifyOrQuit(netData.ContainsBorderRouterWithRloc(rloc16));
}
@@ -681,17 +692,34 @@ void TestNetworkDataDsnSrpServices(void)
{"fdde:ad00:beef:0:0:ff:fe00:6c00", 0xcd12, Service::DnsSrpUnicast::kFromServerData, 0x6c00},
};
const uint16_t kExpectedRlocs[] = {0x6c00, 0x2800, 0x4c00, 0x0000};
const uint8_t kPreferredAnycastEntryIndex = 2;
Service::Manager &manager = instance->Get<Service::Manager>();
Service::Manager::Iterator iterator;
Service::DnsSrpAnycast::Info anycastInfo;
Service::DnsSrpUnicast::Info unicastInfo;
Rlocs rlocs;
reinterpret_cast<TestLeader &>(instance->Get<Leader>()).Populate(kNetworkData, sizeof(kNetworkData));
DumpBuffer("netdata", kNetworkData, sizeof(kNetworkData));
// Verify `FindRlocs()`
instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kAnyRole, rlocs);
VerifyRlocsArray(rlocs, kExpectedRlocs);
instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs);
VerifyRlocsArray(rlocs, kExpectedRlocs);
instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs);
VerifyOrQuit(rlocs.GetLength() == 0);
instance->Get<Leader>().FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
VerifyOrQuit(rlocs.GetLength() == 0);
// Verify all the "DNS/SRP Anycast Service" entries in Network Data
printf("\n- - - - - - - - - - - - - - - - - - - -");