mirror of
https://github.com/espressif/openthread.git
synced 2026-08-03 09:27:47 +00:00
[test] update RoutingManager unit test adding new helper methods (#7951)
This commit updates `test_routing_manager` unit test and adds a new set of helper methods to simplify the implementation of test-case: - `VerifyOmrPrefixInNetData()` to check OMR prefix in Network Data. - `VerifyExternalRoutesInNetData()` to check external route prefixes in Network Data. - `VerifyPrefixTable()` to check the on-link and route prefixes in discovered prefix table. - Different flavors of `SendRouterAdvert()` to send RA with different PIOs, RIOs, and default route info (in header). This commit also breaks the test-cases into multiple functions each covering specific aspect.
This commit is contained in:
+369
-320
@@ -54,7 +54,9 @@ static const char kInfraIfAddress[] = "fe80::1";
|
||||
static constexpr uint32_t kValidLitime = 2000;
|
||||
static constexpr uint32_t kPreferredLifetime = 1800;
|
||||
|
||||
static otInstance *sInstance;
|
||||
static constexpr uint16_t kMaxRaSize = 800;
|
||||
|
||||
static ot::Instance *sInstance;
|
||||
|
||||
static uint32_t sNow = 0;
|
||||
static uint32_t sAlarmTime;
|
||||
@@ -361,30 +363,276 @@ Ip6::Address AddressFromString(const char *aString)
|
||||
return address;
|
||||
}
|
||||
|
||||
void TestRoutingManager(void)
|
||||
void VerifyOmrPrefixInNetData(const Ip6::Prefix &aOmrPrefix, bool aDefaultRoute = false)
|
||||
{
|
||||
otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
|
||||
NetworkData::OnMeshPrefixConfig prefixConfig;
|
||||
|
||||
Log("VerifyOmrPrefixInNetData(%s, def-route:%s)", aOmrPrefix.ToString().AsCString(), aDefaultRoute ? "yes" : "no");
|
||||
|
||||
SuccessOrQuit(otNetDataGetNextOnMeshPrefix(sInstance, &iterator, &prefixConfig));
|
||||
VerifyOrQuit(prefixConfig.GetPrefix() == aOmrPrefix);
|
||||
VerifyOrQuit(prefixConfig.mStable == true);
|
||||
VerifyOrQuit(prefixConfig.mSlaac == true);
|
||||
VerifyOrQuit(prefixConfig.mPreferred == true);
|
||||
VerifyOrQuit(prefixConfig.mOnMesh == true);
|
||||
VerifyOrQuit(prefixConfig.mDefaultRoute == aDefaultRoute);
|
||||
|
||||
VerifyOrQuit(otNetDataGetNextOnMeshPrefix(sInstance, &iterator, &prefixConfig) == kErrorNotFound);
|
||||
}
|
||||
|
||||
using NetworkData::RoutePreference;
|
||||
|
||||
struct ExternalRoute
|
||||
{
|
||||
ExternalRoute(const Ip6::Prefix &aPrefix, RoutePreference aPreference)
|
||||
: mPrefix(aPrefix)
|
||||
, mPreference(aPreference)
|
||||
{
|
||||
}
|
||||
|
||||
const Ip6::Prefix &mPrefix;
|
||||
RoutePreference mPreference;
|
||||
};
|
||||
|
||||
template <uint16_t kLength> void VerifyExternalRoutesInNetData(const ExternalRoute (&aExternRoutes)[kLength])
|
||||
{
|
||||
otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
|
||||
NetworkData::ExternalRouteConfig routeConfig;
|
||||
uint16_t counter;
|
||||
|
||||
Log("VerifyExternalRoutesInNetData()");
|
||||
|
||||
counter = 0;
|
||||
|
||||
while (otNetDataGetNextRoute(sInstance, &iterator, &routeConfig) == kErrorNone)
|
||||
{
|
||||
bool didFind = false;
|
||||
|
||||
counter++;
|
||||
|
||||
Log(" prefix:%s, prf:%s", routeConfig.GetPrefix().ToString().AsCString(),
|
||||
PreferenceToString(routeConfig.mPreference));
|
||||
|
||||
for (const ExternalRoute &externalRoute : aExternRoutes)
|
||||
{
|
||||
if (externalRoute.mPrefix == routeConfig.GetPrefix())
|
||||
{
|
||||
VerifyOrQuit(static_cast<int8_t>(routeConfig.mPreference) == externalRoute.mPreference);
|
||||
didFind = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VerifyOrQuit(didFind);
|
||||
}
|
||||
|
||||
VerifyOrQuit(counter == kLength);
|
||||
}
|
||||
|
||||
struct Pio
|
||||
{
|
||||
Pio(const Ip6::Prefix &aPrefix, uint32_t aValidLifetime, uint32_t aPreferredLifetime)
|
||||
: mPrefix(aPrefix)
|
||||
, mValidLifetime(aValidLifetime)
|
||||
, mPreferredLifetime(aPreferredLifetime)
|
||||
{
|
||||
}
|
||||
|
||||
const Ip6::Prefix &mPrefix;
|
||||
uint32_t mValidLifetime;
|
||||
uint32_t mPreferredLifetime;
|
||||
};
|
||||
|
||||
struct Rio
|
||||
{
|
||||
Rio(const Ip6::Prefix &aPrefix, uint32_t aValidLifetime, RoutePreference aPreference)
|
||||
: mPrefix(aPrefix)
|
||||
, mValidLifetime(aValidLifetime)
|
||||
, mPreference(aPreference)
|
||||
{
|
||||
}
|
||||
|
||||
const Ip6::Prefix &mPrefix;
|
||||
uint32_t mValidLifetime;
|
||||
RoutePreference mPreference;
|
||||
};
|
||||
|
||||
struct DefaultRoute
|
||||
{
|
||||
DefaultRoute(uint32_t aLifetime, RoutePreference aPreference)
|
||||
: mLifetime(aLifetime)
|
||||
, mPreference(aPreference)
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t mLifetime;
|
||||
RoutePreference mPreference;
|
||||
};
|
||||
|
||||
void SendRouterAdvert(const Ip6::Address &aRouterAddress,
|
||||
const Pio * aPios,
|
||||
uint16_t aNumPios,
|
||||
const Rio * aRios,
|
||||
uint16_t aNumRios,
|
||||
const DefaultRoute &aDefaultRoute)
|
||||
{
|
||||
Ip6::Nd::RouterAdvertMessage::Header header;
|
||||
uint8_t buffer[kMaxRaSize];
|
||||
|
||||
header.SetRouterLifetime(aDefaultRoute.mLifetime);
|
||||
header.SetDefaultRouterPreference(aDefaultRoute.mPreference);
|
||||
|
||||
{
|
||||
Ip6::Nd::RouterAdvertMessage raMsg(header, buffer);
|
||||
|
||||
for (; aNumPios > 0; aPios++, aNumPios--)
|
||||
{
|
||||
SuccessOrQuit(
|
||||
raMsg.AppendPrefixInfoOption(aPios->mPrefix, aPios->mValidLifetime, aPios->mPreferredLifetime));
|
||||
}
|
||||
|
||||
for (; aNumRios > 0; aRios++, aNumRios--)
|
||||
{
|
||||
SuccessOrQuit(raMsg.AppendRouteInfoOption(aRios->mPrefix, aRios->mValidLifetime, aRios->mPreference));
|
||||
}
|
||||
|
||||
SendRouterAdvert(aRouterAddress, raMsg.GetAsPacket());
|
||||
Log("Sending RA from router %s", aRouterAddress.ToString().AsCString());
|
||||
LogRouterAdvert(raMsg.GetAsPacket());
|
||||
}
|
||||
}
|
||||
|
||||
template <uint16_t kNumPios, uint16_t kNumRios>
|
||||
void SendRouterAdvert(const Ip6::Address &aRouterAddress,
|
||||
const Pio (&aPios)[kNumPios],
|
||||
const Rio (&aRios)[kNumRios],
|
||||
const DefaultRoute &aDefaultRoute = DefaultRoute(0, NetworkData::kRoutePreferenceMedium))
|
||||
{
|
||||
SendRouterAdvert(aRouterAddress, aPios, kNumPios, aRios, kNumRios, aDefaultRoute);
|
||||
}
|
||||
|
||||
template <uint16_t kNumPios>
|
||||
void SendRouterAdvert(const Ip6::Address &aRouterAddress,
|
||||
const Pio (&aPios)[kNumPios],
|
||||
const DefaultRoute &aDefaultRoute = DefaultRoute(0, NetworkData::kRoutePreferenceMedium))
|
||||
{
|
||||
SendRouterAdvert(aRouterAddress, aPios, kNumPios, nullptr, 0, aDefaultRoute);
|
||||
}
|
||||
|
||||
template <uint16_t kNumRios>
|
||||
void SendRouterAdvert(const Ip6::Address &aRouterAddress,
|
||||
const Rio (&aRios)[kNumRios],
|
||||
const DefaultRoute &aDefaultRoute = DefaultRoute(0, NetworkData::kRoutePreferenceMedium))
|
||||
{
|
||||
SendRouterAdvert(aRouterAddress, nullptr, 0, aRios, kNumRios, aDefaultRoute);
|
||||
}
|
||||
|
||||
void SendRouterAdvert(const Ip6::Address &aRouterAddress, const DefaultRoute &aDefaultRoute)
|
||||
{
|
||||
SendRouterAdvert(aRouterAddress, nullptr, 0, nullptr, 0, aDefaultRoute);
|
||||
}
|
||||
|
||||
struct OnLinkPrefix : public Pio
|
||||
{
|
||||
OnLinkPrefix(const Ip6::Prefix & aPrefix,
|
||||
uint32_t aValidLifetime,
|
||||
uint32_t aPreferredLifetime,
|
||||
const Ip6::Address &aRouterAddress)
|
||||
: Pio(aPrefix, aValidLifetime, aPreferredLifetime)
|
||||
, mRouterAddress(aRouterAddress)
|
||||
{
|
||||
}
|
||||
|
||||
const Ip6::Address &mRouterAddress;
|
||||
};
|
||||
|
||||
struct RoutePrefix : public Rio
|
||||
{
|
||||
RoutePrefix(const Ip6::Prefix & aPrefix,
|
||||
uint32_t aValidLifetime,
|
||||
RoutePreference aPreference,
|
||||
const Ip6::Address &aRouterAddress)
|
||||
: Rio(aPrefix, aValidLifetime, aPreference)
|
||||
, mRouterAddress(aRouterAddress)
|
||||
{
|
||||
}
|
||||
|
||||
const Ip6::Address &mRouterAddress;
|
||||
};
|
||||
|
||||
template <uint16_t kNumOnLinkPrefixes, uint16_t kNumRoutePrefixes>
|
||||
void VerifyPrefixTable(const OnLinkPrefix (&aOnLinkPrefixes)[kNumOnLinkPrefixes],
|
||||
const RoutePrefix (&aRoutePrefixes)[kNumRoutePrefixes])
|
||||
{
|
||||
Instance & instance = *static_cast<Instance *>(testInitInstance());
|
||||
BorderRouter::RoutingManager & rm = instance.Get<BorderRouter::RoutingManager>();
|
||||
Ip6::Prefix localOnLink;
|
||||
Ip6::Prefix localOmr;
|
||||
Ip6::Prefix onLinkPrefix = PrefixFromString("2000:abba:baba::", 64);
|
||||
Ip6::Prefix routePrefix = PrefixFromString("2000:1234:5678::", 64);
|
||||
Ip6::Prefix omrPrefix = PrefixFromString("2000:0000:1111:4444::", 64);
|
||||
Ip6::Address routerAddressA = AddressFromString("fd00::aaaa");
|
||||
Ip6::Address routerAddressB = AddressFromString("fd00::bbbb");
|
||||
BorderRouter::RoutingManager::PrefixTableIterator iter;
|
||||
BorderRouter::RoutingManager::PrefixTableEntry entry;
|
||||
NetworkData::Iterator iterator;
|
||||
NetworkData::OnMeshPrefixConfig prefixConfig;
|
||||
NetworkData::ExternalRouteConfig routeConfig;
|
||||
uint8_t counter;
|
||||
uint8_t buffer[800];
|
||||
uint16_t onLinkPrefixCount = 0;
|
||||
uint16_t routePrefixCount = 0;
|
||||
|
||||
Log("VerifyPrefixTable()");
|
||||
|
||||
sInstance->Get<BorderRouter::RoutingManager>().InitPrefixTableIterator(iter);
|
||||
|
||||
while (sInstance->Get<BorderRouter::RoutingManager>().GetNextPrefixTableEntry(iter, entry) == kErrorNone)
|
||||
{
|
||||
bool didFind = false;
|
||||
|
||||
if (entry.mIsOnLink)
|
||||
{
|
||||
Log(" on-link prefix:%s, valid:%u, preferred:%u, router:%s",
|
||||
AsCoreType(&entry.mPrefix).ToString().AsCString(), entry.mValidLifetime, entry.mPreferredLifetime,
|
||||
AsCoreType(&entry.mRouterAddress).ToString().AsCString());
|
||||
|
||||
onLinkPrefixCount++;
|
||||
|
||||
for (const OnLinkPrefix &onLinkPrefix : aOnLinkPrefixes)
|
||||
{
|
||||
if ((onLinkPrefix.mPrefix == AsCoreType(&entry.mPrefix)) &&
|
||||
(AsCoreType(&entry.mRouterAddress) == onLinkPrefix.mRouterAddress))
|
||||
{
|
||||
VerifyOrQuit(entry.mValidLifetime == onLinkPrefix.mValidLifetime);
|
||||
VerifyOrQuit(entry.mPreferredLifetime == onLinkPrefix.mPreferredLifetime);
|
||||
didFind = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(" route prefix:%s, valid:%u, prf:%s, router:%s", AsCoreType(&entry.mPrefix).ToString().AsCString(),
|
||||
entry.mValidLifetime, PreferenceToString(entry.mRoutePreference),
|
||||
AsCoreType(&entry.mRouterAddress).ToString().AsCString());
|
||||
|
||||
routePrefixCount++;
|
||||
|
||||
for (const RoutePrefix &routePrefix : aRoutePrefixes)
|
||||
{
|
||||
if ((routePrefix.mPrefix == AsCoreType(&entry.mPrefix)) &&
|
||||
(AsCoreType(&entry.mRouterAddress) == routePrefix.mRouterAddress))
|
||||
{
|
||||
VerifyOrQuit(entry.mValidLifetime == routePrefix.mValidLifetime);
|
||||
VerifyOrQuit(static_cast<int8_t>(entry.mRoutePreference) == routePrefix.mPreference);
|
||||
didFind = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VerifyOrQuit(didFind);
|
||||
}
|
||||
|
||||
VerifyOrQuit(onLinkPrefixCount == kNumOnLinkPrefixes);
|
||||
VerifyOrQuit(routePrefixCount == kNumRoutePrefixes);
|
||||
}
|
||||
|
||||
void InitTest(void)
|
||||
{
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Initialize OT instance.
|
||||
|
||||
sNow = 0;
|
||||
sInstance = &instance;
|
||||
sInstance = static_cast<Instance *>(testInitInstance());
|
||||
|
||||
memset(&sRadioTxFrame, 0, sizeof(sRadioTxFrame));
|
||||
sRadioTxFrame.mPsdu = sRadioTxFramePsdu;
|
||||
@@ -406,6 +654,23 @@ void TestRoutingManager(void)
|
||||
AdvanceTime(10000);
|
||||
|
||||
VerifyOrQuit(otThreadGetDeviceRole(sInstance) == OT_DEVICE_ROLE_LEADER);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void TestSamePrefixesFromMultipleRouters(void)
|
||||
{
|
||||
Ip6::Prefix localOnLink;
|
||||
Ip6::Prefix localOmr;
|
||||
Ip6::Prefix onLinkPrefix = PrefixFromString("2000:abba:baba::", 64);
|
||||
Ip6::Prefix routePrefix = PrefixFromString("2000:1234:5678::", 64);
|
||||
Ip6::Address routerAddressA = AddressFromString("fd00::aaaa");
|
||||
Ip6::Address routerAddressB = AddressFromString("fd00::bbbb");
|
||||
|
||||
Log("--------------------------------------------------------------------------------------------");
|
||||
Log("TestSamePrefixesFromMultipleRouters");
|
||||
|
||||
InitTest();
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Start Routing Manager. Check emitted RS and RA messages.
|
||||
@@ -415,12 +680,10 @@ void TestRoutingManager(void)
|
||||
sSawExpectedRio = false;
|
||||
sExpectedPio = kPioAdvertisingLocalOnLink;
|
||||
|
||||
Log("Starting RoutingManager");
|
||||
SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
|
||||
|
||||
SuccessOrQuit(rm.SetEnabled(true));
|
||||
|
||||
SuccessOrQuit(rm.GetOnLinkPrefix(localOnLink));
|
||||
SuccessOrQuit(rm.GetOmrPrefix(localOmr));
|
||||
SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
|
||||
SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
|
||||
|
||||
Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
|
||||
Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
|
||||
@@ -437,43 +700,14 @@ void TestRoutingManager(void)
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Check Network Data to include the local OMR and on-link prefix.
|
||||
|
||||
iterator = NetworkData::kIteratorInit;
|
||||
|
||||
// We expect to see OMR prefix in net data as on-mesh prefix.
|
||||
SuccessOrQuit(instance.Get<NetworkData::Leader>().GetNextOnMeshPrefix(iterator, prefixConfig));
|
||||
VerifyOrQuit(prefixConfig.GetPrefix() == localOmr);
|
||||
VerifyOrQuit(prefixConfig.mStable == true);
|
||||
VerifyOrQuit(prefixConfig.mSlaac == true);
|
||||
VerifyOrQuit(prefixConfig.mPreferred == true);
|
||||
VerifyOrQuit(prefixConfig.mOnMesh == true);
|
||||
VerifyOrQuit(prefixConfig.mDefaultRoute == false);
|
||||
|
||||
VerifyOrQuit(instance.Get<NetworkData::Leader>().GetNextOnMeshPrefix(iterator, prefixConfig) == kErrorNotFound);
|
||||
|
||||
iterator = NetworkData::kIteratorInit;
|
||||
|
||||
// We expect to see local on-link prefix in net data as external route.
|
||||
SuccessOrQuit(instance.Get<NetworkData::Leader>().GetNextExternalRoute(iterator, routeConfig));
|
||||
VerifyOrQuit(routeConfig.GetPrefix() == localOnLink);
|
||||
VerifyOrQuit(routeConfig.mStable == true);
|
||||
VerifyOrQuit(routeConfig.mPreference == NetworkData::kRoutePreferenceMedium);
|
||||
|
||||
VerifyOrQuit(instance.Get<NetworkData::Leader>().GetNextExternalRoute(iterator, routeConfig) == kErrorNotFound);
|
||||
VerifyOmrPrefixInNetData(localOmr);
|
||||
VerifyExternalRoutesInNetData({ExternalRoute(localOnLink, NetworkData::kRoutePreferenceMedium)});
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Send an RA from router A with a new on-link (PIO) and route prefix (RIO).
|
||||
|
||||
{
|
||||
Ip6::Nd::RouterAdvertMessage raMsg(Ip6::Nd::RouterAdvertMessage::Header(), buffer);
|
||||
|
||||
SuccessOrQuit(raMsg.AppendPrefixInfoOption(onLinkPrefix, kValidLitime, kPreferredLifetime));
|
||||
SuccessOrQuit(raMsg.AppendRouteInfoOption(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium));
|
||||
|
||||
SendRouterAdvert(routerAddressA, raMsg.GetAsPacket());
|
||||
|
||||
Log("Send RA from router A");
|
||||
LogRouterAdvert(raMsg.GetAsPacket());
|
||||
}
|
||||
SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)},
|
||||
{Rio(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium)});
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Check that the local on-link prefix is now deprecating in the new RA.
|
||||
@@ -490,120 +724,35 @@ void TestRoutingManager(void)
|
||||
// Check the discovered prefix table and ensure info from router A
|
||||
// is present in the table.
|
||||
|
||||
counter = 0;
|
||||
|
||||
rm.InitPrefixTableIterator(iter);
|
||||
|
||||
while (rm.GetNextPrefixTableEntry(iter, entry) == kErrorNone)
|
||||
{
|
||||
counter++;
|
||||
VerifyOrQuit(AsCoreType(&entry.mRouterAddress) == routerAddressA);
|
||||
|
||||
if (entry.mIsOnLink)
|
||||
{
|
||||
VerifyOrQuit(AsCoreType(&entry.mPrefix) == onLinkPrefix);
|
||||
VerifyOrQuit(entry.mValidLifetime = kValidLitime);
|
||||
VerifyOrQuit(entry.mPreferredLifetime = kPreferredLifetime);
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrQuit(AsCoreType(&entry.mPrefix) == routePrefix);
|
||||
VerifyOrQuit(entry.mValidLifetime = kValidLitime);
|
||||
VerifyOrQuit(static_cast<int8_t>(entry.mRoutePreference) == NetworkData::kRoutePreferenceMedium);
|
||||
}
|
||||
}
|
||||
|
||||
VerifyOrQuit(counter == 2);
|
||||
VerifyPrefixTable({OnLinkPrefix(onLinkPrefix, kValidLitime, kPreferredLifetime, routerAddressA)},
|
||||
{RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA)});
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Check Network Data to include new prefixes from router A.
|
||||
|
||||
iterator = NetworkData::kIteratorInit;
|
||||
|
||||
// We expect to see OMR prefix in net data as on-mesh prefix.
|
||||
SuccessOrQuit(instance.Get<NetworkData::Leader>().GetNextOnMeshPrefix(iterator, prefixConfig));
|
||||
VerifyOrQuit(prefixConfig.GetPrefix() == localOmr);
|
||||
VerifyOrQuit(prefixConfig.mStable == true);
|
||||
VerifyOrQuit(prefixConfig.mSlaac == true);
|
||||
VerifyOrQuit(prefixConfig.mPreferred == true);
|
||||
VerifyOrQuit(prefixConfig.mOnMesh == true);
|
||||
VerifyOrQuit(prefixConfig.mDefaultRoute == false);
|
||||
|
||||
VerifyOrQuit(instance.Get<NetworkData::Leader>().GetNextOnMeshPrefix(iterator, prefixConfig) == kErrorNotFound);
|
||||
|
||||
iterator = NetworkData::kIteratorInit;
|
||||
|
||||
counter = 0;
|
||||
|
||||
// We expect to see 3 entries, our local on link and new prefixes from router A.
|
||||
while (instance.Get<NetworkData::Leader>().GetNextExternalRoute(iterator, routeConfig) == kErrorNone)
|
||||
{
|
||||
VerifyOrQuit((routeConfig.GetPrefix() == localOnLink) || (routeConfig.GetPrefix() == onLinkPrefix) ||
|
||||
(routeConfig.GetPrefix() == routePrefix));
|
||||
VerifyOrQuit(static_cast<int8_t>(routeConfig.mPreference) == NetworkData::kRoutePreferenceMedium);
|
||||
counter++;
|
||||
}
|
||||
|
||||
VerifyOrQuit(counter == 3);
|
||||
VerifyOmrPrefixInNetData(localOmr);
|
||||
VerifyExternalRoutesInNetData({ExternalRoute(localOnLink, NetworkData::kRoutePreferenceMedium),
|
||||
ExternalRoute(onLinkPrefix, NetworkData::kRoutePreferenceMedium),
|
||||
ExternalRoute(routePrefix, NetworkData::kRoutePreferenceMedium)});
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Send the same RA again from router A with the on-link (PIO) and route prefix (RIO).
|
||||
|
||||
{
|
||||
Ip6::Nd::RouterAdvertMessage raMsg(Ip6::Nd::RouterAdvertMessage::Header(), buffer);
|
||||
|
||||
SuccessOrQuit(raMsg.AppendPrefixInfoOption(onLinkPrefix, kValidLitime, kPreferredLifetime));
|
||||
SuccessOrQuit(raMsg.AppendRouteInfoOption(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium));
|
||||
|
||||
SendRouterAdvert(routerAddressA, raMsg.GetAsPacket());
|
||||
|
||||
Log("Send RA from router A");
|
||||
LogRouterAdvert(raMsg.GetAsPacket());
|
||||
}
|
||||
SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)},
|
||||
{Rio(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium)});
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Check the discovered prefix table and ensure info from router A
|
||||
// remains unchanged.
|
||||
|
||||
counter = 0;
|
||||
|
||||
rm.InitPrefixTableIterator(iter);
|
||||
|
||||
while (rm.GetNextPrefixTableEntry(iter, entry) == kErrorNone)
|
||||
{
|
||||
counter++;
|
||||
VerifyOrQuit(AsCoreType(&entry.mRouterAddress) == routerAddressA);
|
||||
|
||||
if (entry.mIsOnLink)
|
||||
{
|
||||
VerifyOrQuit(AsCoreType(&entry.mPrefix) == onLinkPrefix);
|
||||
VerifyOrQuit(entry.mValidLifetime = kValidLitime);
|
||||
VerifyOrQuit(entry.mPreferredLifetime = kPreferredLifetime);
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrQuit(AsCoreType(&entry.mPrefix) == routePrefix);
|
||||
VerifyOrQuit(entry.mValidLifetime = kValidLitime);
|
||||
VerifyOrQuit(static_cast<int8_t>(entry.mRoutePreference) == NetworkData::kRoutePreferenceMedium);
|
||||
}
|
||||
}
|
||||
|
||||
VerifyOrQuit(counter == 2);
|
||||
VerifyPrefixTable({OnLinkPrefix(onLinkPrefix, kValidLitime, kPreferredLifetime, routerAddressA)},
|
||||
{RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA)});
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Send an RA from router B with same route prefix (RIO) but with
|
||||
// high route preference.
|
||||
|
||||
{
|
||||
Ip6::Nd::RouterAdvertMessage raMsg(Ip6::Nd::RouterAdvertMessage::Header(), buffer);
|
||||
|
||||
SuccessOrQuit(raMsg.AppendRouteInfoOption(routePrefix, kValidLitime, NetworkData::kRoutePreferenceHigh));
|
||||
|
||||
SendRouterAdvert(routerAddressB, raMsg.GetAsPacket());
|
||||
|
||||
Log("Send RA from router B");
|
||||
LogRouterAdvert(raMsg.GetAsPacket());
|
||||
}
|
||||
SendRouterAdvert(routerAddressB, {Rio(routePrefix, kValidLitime, NetworkData::kRoutePreferenceHigh)});
|
||||
|
||||
AdvanceTime(10000);
|
||||
|
||||
@@ -611,99 +760,27 @@ void TestRoutingManager(void)
|
||||
// Check the discovered prefix table and ensure info from router B
|
||||
// is also included in the table.
|
||||
|
||||
counter = 0;
|
||||
|
||||
rm.InitPrefixTableIterator(iter);
|
||||
|
||||
while (rm.GetNextPrefixTableEntry(iter, entry) == kErrorNone)
|
||||
{
|
||||
const Ip6::Address &routerAddr = AsCoreType(&entry.mRouterAddress);
|
||||
counter++;
|
||||
|
||||
if (routerAddr == routerAddressA)
|
||||
{
|
||||
if (entry.mIsOnLink)
|
||||
{
|
||||
VerifyOrQuit(AsCoreType(&entry.mPrefix) == onLinkPrefix);
|
||||
VerifyOrQuit(entry.mValidLifetime = kValidLitime);
|
||||
VerifyOrQuit(entry.mPreferredLifetime = kPreferredLifetime);
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrQuit(AsCoreType(&entry.mPrefix) == routePrefix);
|
||||
VerifyOrQuit(entry.mValidLifetime = kValidLitime);
|
||||
VerifyOrQuit(static_cast<int8_t>(entry.mRoutePreference) == NetworkData::kRoutePreferenceMedium);
|
||||
}
|
||||
}
|
||||
else if (routerAddr == routerAddressB)
|
||||
{
|
||||
VerifyOrQuit(!entry.mIsOnLink);
|
||||
VerifyOrQuit(AsCoreType(&entry.mPrefix) == routePrefix);
|
||||
VerifyOrQuit(entry.mValidLifetime = kValidLitime);
|
||||
VerifyOrQuit(static_cast<int8_t>(entry.mRoutePreference) == NetworkData::kRoutePreferenceHigh);
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrQuit(false, "Unexpected entry in prefix table with unknown router address");
|
||||
}
|
||||
}
|
||||
|
||||
VerifyOrQuit(counter == 3);
|
||||
VerifyPrefixTable({OnLinkPrefix(onLinkPrefix, kValidLitime, kPreferredLifetime, routerAddressA)},
|
||||
{RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA),
|
||||
RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceHigh, routerAddressB)});
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Check Network Data.
|
||||
|
||||
iterator = NetworkData::kIteratorInit;
|
||||
|
||||
// We expect to see OMR prefix in net data as on-mesh prefix
|
||||
SuccessOrQuit(instance.Get<NetworkData::Leader>().GetNextOnMeshPrefix(iterator, prefixConfig));
|
||||
VerifyOrQuit(prefixConfig.GetPrefix() == localOmr);
|
||||
VerifyOrQuit(prefixConfig.mStable == true);
|
||||
VerifyOrQuit(prefixConfig.mSlaac == true);
|
||||
VerifyOrQuit(prefixConfig.mPreferred == true);
|
||||
VerifyOrQuit(prefixConfig.mOnMesh == true);
|
||||
VerifyOrQuit(prefixConfig.mDefaultRoute == false);
|
||||
|
||||
VerifyOrQuit(instance.Get<NetworkData::Leader>().GetNextOnMeshPrefix(iterator, prefixConfig) == kErrorNotFound);
|
||||
|
||||
iterator = NetworkData::kIteratorInit;
|
||||
|
||||
counter = 0;
|
||||
VerifyOmrPrefixInNetData(localOmr);
|
||||
|
||||
// We expect to see 3 entries, our local on link and new prefixes
|
||||
// from router A and B. The `routePrefix` now should have high
|
||||
// preference.
|
||||
|
||||
while (instance.Get<NetworkData::Leader>().GetNextExternalRoute(iterator, routeConfig) == kErrorNone)
|
||||
{
|
||||
counter++;
|
||||
|
||||
if (routeConfig.GetPrefix() == routePrefix)
|
||||
{
|
||||
VerifyOrQuit(static_cast<int8_t>(routeConfig.mPreference) == NetworkData::kRoutePreferenceHigh);
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrQuit((routeConfig.GetPrefix() == localOnLink) || (routeConfig.GetPrefix() == onLinkPrefix));
|
||||
VerifyOrQuit(static_cast<int8_t>(routeConfig.mPreference) == NetworkData::kRoutePreferenceMedium);
|
||||
}
|
||||
}
|
||||
|
||||
VerifyOrQuit(counter == 3);
|
||||
VerifyExternalRoutesInNetData({ExternalRoute(routePrefix, NetworkData::kRoutePreferenceHigh),
|
||||
ExternalRoute(localOnLink, NetworkData::kRoutePreferenceMedium),
|
||||
ExternalRoute(onLinkPrefix, NetworkData::kRoutePreferenceMedium)});
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Send an RA from router B removing the route prefix.
|
||||
|
||||
{
|
||||
Ip6::Nd::RouterAdvertMessage raMsg(Ip6::Nd::RouterAdvertMessage::Header(), buffer);
|
||||
|
||||
SuccessOrQuit(raMsg.AppendRouteInfoOption(routePrefix, 0, NetworkData::kRoutePreferenceHigh));
|
||||
|
||||
SendRouterAdvert(routerAddressB, raMsg.GetAsPacket());
|
||||
|
||||
Log("Send RA from router B");
|
||||
LogRouterAdvert(raMsg.GetAsPacket());
|
||||
}
|
||||
SendRouterAdvert(routerAddressB, {Rio(routePrefix, 0, NetworkData::kRoutePreferenceHigh)});
|
||||
|
||||
AdvanceTime(10000);
|
||||
|
||||
@@ -711,48 +788,65 @@ void TestRoutingManager(void)
|
||||
// Check the discovered prefix table and ensure info from router B
|
||||
// is now removed from the table.
|
||||
|
||||
counter = 0;
|
||||
|
||||
rm.InitPrefixTableIterator(iter);
|
||||
|
||||
while (rm.GetNextPrefixTableEntry(iter, entry) == kErrorNone)
|
||||
{
|
||||
counter++;
|
||||
|
||||
VerifyOrQuit(AsCoreType(&entry.mRouterAddress) == routerAddressA);
|
||||
|
||||
if (entry.mIsOnLink)
|
||||
{
|
||||
VerifyOrQuit(AsCoreType(&entry.mPrefix) == onLinkPrefix);
|
||||
VerifyOrQuit(entry.mValidLifetime = kValidLitime);
|
||||
VerifyOrQuit(entry.mPreferredLifetime = kPreferredLifetime);
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrQuit(AsCoreType(&entry.mPrefix) == routePrefix);
|
||||
VerifyOrQuit(entry.mValidLifetime = kValidLitime);
|
||||
VerifyOrQuit(static_cast<int8_t>(entry.mRoutePreference) == NetworkData::kRoutePreferenceMedium);
|
||||
}
|
||||
}
|
||||
|
||||
VerifyOrQuit(counter == 2);
|
||||
VerifyPrefixTable({OnLinkPrefix(onLinkPrefix, kValidLitime, kPreferredLifetime, routerAddressA)},
|
||||
{RoutePrefix(routePrefix, kValidLitime, NetworkData::kRoutePreferenceMedium, routerAddressA)});
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Check Network Data, all prefixes should be again at medium preference.
|
||||
|
||||
counter = 0;
|
||||
iterator = NetworkData::kIteratorInit;
|
||||
VerifyExternalRoutesInNetData({ExternalRoute(localOnLink, NetworkData::kRoutePreferenceMedium),
|
||||
ExternalRoute(onLinkPrefix, NetworkData::kRoutePreferenceMedium),
|
||||
ExternalRoute(routePrefix, NetworkData::kRoutePreferenceMedium)});
|
||||
|
||||
while (instance.Get<NetworkData::Leader>().GetNextExternalRoute(iterator, routeConfig) == kErrorNone)
|
||||
{
|
||||
counter++;
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
VerifyOrQuit((routeConfig.GetPrefix() == localOnLink) || (routeConfig.GetPrefix() == onLinkPrefix) ||
|
||||
(routeConfig.GetPrefix() == routePrefix));
|
||||
VerifyOrQuit(static_cast<int8_t>(routeConfig.mPreference) == NetworkData::kRoutePreferenceMedium);
|
||||
}
|
||||
Log("End of TestSamePrefixesFromMultipleRouters");
|
||||
|
||||
VerifyOrQuit(counter == 3);
|
||||
testFreeInstance(sInstance);
|
||||
}
|
||||
|
||||
void TestOmrSelection(void)
|
||||
{
|
||||
Ip6::Prefix localOnLink;
|
||||
Ip6::Prefix localOmr;
|
||||
Ip6::Prefix omrPrefix = PrefixFromString("2000:0000:1111:4444::", 64);
|
||||
NetworkData::OnMeshPrefixConfig prefixConfig;
|
||||
|
||||
Log("--------------------------------------------------------------------------------------------");
|
||||
Log("TestOmrSelection");
|
||||
|
||||
InitTest();
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Start Routing Manager. Check emitted RS and RA messages.
|
||||
|
||||
sRsEmitted = false;
|
||||
sRaValidated = false;
|
||||
sSawExpectedRio = false;
|
||||
sExpectedPio = kPioAdvertisingLocalOnLink;
|
||||
|
||||
SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().SetEnabled(true));
|
||||
|
||||
SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(localOnLink));
|
||||
SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetOmrPrefix(localOmr));
|
||||
|
||||
Log("Local on-link prefix is %s", localOnLink.ToString().AsCString());
|
||||
Log("Local OMR prefix is %s", localOmr.ToString().AsCString());
|
||||
|
||||
sExpectedRioPrefix = localOmr;
|
||||
|
||||
AdvanceTime(30000);
|
||||
|
||||
VerifyOrQuit(sRsEmitted);
|
||||
VerifyOrQuit(sRaValidated);
|
||||
VerifyOrQuit(sSawExpectedRio);
|
||||
Log("Received RA was validated");
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Check Network Data to include the local OMR and on-link prefix.
|
||||
|
||||
VerifyOmrPrefixInNetData(localOmr);
|
||||
VerifyExternalRoutesInNetData({ExternalRoute(localOnLink, NetworkData::kRoutePreferenceMedium)});
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Add a new OMR prefix directly into net data. The new prefix should
|
||||
@@ -777,6 +871,7 @@ void TestRoutingManager(void)
|
||||
|
||||
sRaValidated = false;
|
||||
sSawExpectedRio = false;
|
||||
sExpectedPio = kPioAdvertisingLocalOnLink;
|
||||
sExpectedRioPrefix = omrPrefix;
|
||||
|
||||
AdvanceTime(20000);
|
||||
@@ -788,32 +883,9 @@ void TestRoutingManager(void)
|
||||
// Check Network Data. We should now see that the local OMR prefix
|
||||
// is removed.
|
||||
|
||||
iterator = NetworkData::kIteratorInit;
|
||||
VerifyOmrPrefixInNetData(omrPrefix);
|
||||
|
||||
// We expect to see new OMR prefix in net data.
|
||||
SuccessOrQuit(instance.Get<NetworkData::Leader>().GetNextOnMeshPrefix(iterator, prefixConfig));
|
||||
VerifyOrQuit(prefixConfig.GetPrefix() == omrPrefix);
|
||||
VerifyOrQuit(prefixConfig.mStable == true);
|
||||
VerifyOrQuit(prefixConfig.mSlaac == true);
|
||||
VerifyOrQuit(prefixConfig.mPreferred == true);
|
||||
VerifyOrQuit(prefixConfig.mOnMesh == true);
|
||||
VerifyOrQuit(prefixConfig.mDefaultRoute == false);
|
||||
|
||||
VerifyOrQuit(instance.Get<NetworkData::Leader>().GetNextOnMeshPrefix(iterator, prefixConfig) == kErrorNotFound);
|
||||
|
||||
counter = 0;
|
||||
iterator = NetworkData::kIteratorInit;
|
||||
|
||||
while (instance.Get<NetworkData::Leader>().GetNextExternalRoute(iterator, routeConfig) == kErrorNone)
|
||||
{
|
||||
counter++;
|
||||
|
||||
VerifyOrQuit((routeConfig.GetPrefix() == localOnLink) || (routeConfig.GetPrefix() == onLinkPrefix) ||
|
||||
(routeConfig.GetPrefix() == routePrefix));
|
||||
VerifyOrQuit(static_cast<int8_t>(routeConfig.mPreference) == NetworkData::kRoutePreferenceMedium);
|
||||
}
|
||||
|
||||
VerifyOrQuit(counter == 3);
|
||||
VerifyExternalRoutesInNetData({ExternalRoute(localOnLink, NetworkData::kRoutePreferenceMedium)});
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Remove the OMR prefix previously added in net data.
|
||||
@@ -839,38 +911,14 @@ void TestRoutingManager(void)
|
||||
// Check Network Data. We should see that the local OMR prefix is
|
||||
// added again.
|
||||
|
||||
iterator = NetworkData::kIteratorInit;
|
||||
VerifyOmrPrefixInNetData(localOmr);
|
||||
|
||||
// We expect to see new OMR prefix in net data as on-mesh prefix.
|
||||
SuccessOrQuit(instance.Get<NetworkData::Leader>().GetNextOnMeshPrefix(iterator, prefixConfig));
|
||||
VerifyOrQuit(prefixConfig.GetPrefix() == localOmr);
|
||||
VerifyOrQuit(prefixConfig.mStable == true);
|
||||
VerifyOrQuit(prefixConfig.mSlaac == true);
|
||||
VerifyOrQuit(prefixConfig.mPreferred == true);
|
||||
VerifyOrQuit(prefixConfig.mOnMesh == true);
|
||||
VerifyOrQuit(prefixConfig.mDefaultRoute == false);
|
||||
|
||||
VerifyOrQuit(instance.Get<NetworkData::Leader>().GetNextOnMeshPrefix(iterator, prefixConfig) == kErrorNotFound);
|
||||
|
||||
counter = 0;
|
||||
iterator = NetworkData::kIteratorInit;
|
||||
|
||||
while (instance.Get<NetworkData::Leader>().GetNextExternalRoute(iterator, routeConfig) == kErrorNone)
|
||||
{
|
||||
counter++;
|
||||
|
||||
VerifyOrQuit((routeConfig.GetPrefix() == localOnLink) || (routeConfig.GetPrefix() == onLinkPrefix) ||
|
||||
(routeConfig.GetPrefix() == routePrefix));
|
||||
VerifyOrQuit(static_cast<int8_t>(routeConfig.mPreference) == NetworkData::kRoutePreferenceMedium);
|
||||
}
|
||||
|
||||
VerifyOrQuit(counter == 3);
|
||||
VerifyExternalRoutesInNetData({ExternalRoute(localOnLink, NetworkData::kRoutePreferenceMedium)});
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
Log("End of test");
|
||||
|
||||
testFreeInstance(&instance);
|
||||
Log("End of TestOmrSelection");
|
||||
testFreeInstance(sInstance);
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
@@ -878,7 +926,8 @@ void TestRoutingManager(void)
|
||||
int main(void)
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
TestRoutingManager();
|
||||
TestSamePrefixesFromMultipleRouters();
|
||||
TestOmrSelection();
|
||||
printf("All tests passed\n");
|
||||
#else
|
||||
printf("BORDER_ROUTING feature is not enabled\n");
|
||||
|
||||
Reference in New Issue
Block a user