[routing-manager] add LocalOnLinkPrefix class (#7989)

This commit simplifies `RoutingManager` by adding a nested class
`LocalOnLinkPrefix` which encapsulates the local on-link prefix
related info and functionality. It tracks the state of the prefix,
i.e. whether we are advertising, deprecating or not including it. It
provides a method to append it as a PIO in an RA message and uses a
timer to keep track of the prefix's lifetime (since the last time it
was advertised in an RA message).

This commit also updated the `test_routing_manager` unit test to add
`TestLocalOnLinkPrefixDeprecation()` checking the deprecation and
expiration of local on-link prefix.
This commit is contained in:
Abtin Keshavarzian
2022-08-08 09:24:10 -07:00
committed by GitHub
parent 62fcf85106
commit c28496dbd8
3 changed files with 357 additions and 120 deletions
+186 -106
View File
@@ -66,8 +66,7 @@ RoutingManager::RoutingManager(Instance &aInstance)
, mInfraIf(aInstance)
, mLocalOmrPrefix(aInstance)
, mRouteInfoOptionPreference(NetworkData::kRoutePreferenceMedium)
, mIsAdvertisingLocalOnLinkPrefix(false)
, mOnLinkPrefixDeprecateTimer(aInstance, HandleOnLinkPrefixDeprecateTimer)
, mLocalOnLinkPrefix(aInstance)
, mIsAdvertisingLocalNat64Prefix(false)
, mDiscoveredPrefixTable(aInstance)
, mTimeRouterAdvMessageLastUpdate(TimerMilli::GetNow())
@@ -82,9 +81,6 @@ RoutingManager::RoutingManager(Instance &aInstance)
mFavoredDiscoveredOnLinkPrefix.Clear();
mBrUlaPrefix.Clear();
mLocalOnLinkPrefix.Clear();
mLocalNat64Prefix.Clear();
}
@@ -99,7 +95,7 @@ Error RoutingManager::Init(uint32_t aInfraIfIndex, bool aInfraIfIsRunning)
#if OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE
GenerateNat64Prefix();
#endif
GenerateOnLinkPrefix();
mLocalOnLinkPrefix.Generate();
error = mInfraIf.HandleStateChanged(mInfraIf.GetIfIndex(), aInfraIfIsRunning);
@@ -168,7 +164,7 @@ Error RoutingManager::GetOnLinkPrefix(Ip6::Prefix &aPrefix)
Error error = kErrorNone;
VerifyOrExit(IsInitialized(), error = kErrorInvalidState);
aPrefix = mLocalOnLinkPrefix;
aPrefix = mLocalOnLinkPrefix.GetPrefix();
exit:
return error;
@@ -232,20 +228,6 @@ void RoutingManager::GenerateNat64Prefix(void)
}
#endif
void RoutingManager::GenerateOnLinkPrefix(void)
{
MeshCoP::ExtendedPanId extPanId = Get<MeshCoP::ExtendedPanIdManager>().GetExtPanId();
mLocalOnLinkPrefix.mPrefix.mFields.m8[0] = 0xfd;
// Global ID: 40 most significant bits of Extended PAN ID
memcpy(mLocalOnLinkPrefix.mPrefix.mFields.m8 + 1, extPanId.m8, 5);
// Subnet ID: 16 least significant bits of Extended PAN ID
memcpy(mLocalOnLinkPrefix.mPrefix.mFields.m8 + 6, extPanId.m8 + 6, 2);
mLocalOnLinkPrefix.SetLength(kOnLinkPrefixLength);
LogNote("Local on-link prefix: %s", mLocalOnLinkPrefix.ToString().AsCString());
}
void RoutingManager::EvaluateState(void)
{
if (mIsEnabled && Get<Mle::MleRouter>().IsAttached() && mInfraIf.IsRunning())
@@ -266,6 +248,7 @@ void RoutingManager::Start(void)
mIsRunning = true;
UpdateDiscoveredPrefixTableOnNetDataChange();
mLocalOnLinkPrefix.Start();
StartRouterSolicitationDelay();
}
}
@@ -279,14 +262,7 @@ void RoutingManager::Stop(void)
mFavoredDiscoveredOnLinkPrefix.Clear();
if (mIsAdvertisingLocalOnLinkPrefix)
{
UnpublishExternalRoute(mLocalOnLinkPrefix);
// Start deprecating the local on-link prefix to send a PIO
// with zero preferred lifetime in `SendRouterAdvertisement`.
DeprecateOnLinkPrefix();
}
mLocalOnLinkPrefix.Stop();
#if OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE
if (mIsAdvertisingLocalNat64Prefix)
@@ -298,7 +274,6 @@ void RoutingManager::Stop(void)
SendRouterAdvertisement(kInvalidateAllPrevPrefixes);
mAdvertisedPrefixes.Clear();
mOnLinkPrefixDeprecateTimer.Stop();
mDiscoveredPrefixTable.RemoveAllEntries();
mDiscoveredPrefixStaleTimer.Stop();
@@ -359,15 +334,7 @@ void RoutingManager::HandleNotifierEvents(Events aEvents)
if (aEvents.Contains(kEventThreadExtPanIdChanged))
{
if (mIsAdvertisingLocalOnLinkPrefix)
{
UnpublishExternalRoute(mLocalOnLinkPrefix);
// TODO: consider deprecating/invalidating existing
// on-link prefix
mIsAdvertisingLocalOnLinkPrefix = false;
}
GenerateOnLinkPrefix();
mLocalOnLinkPrefix.HandleExtPanIdChange();
if (mIsRunning)
{
@@ -511,14 +478,7 @@ void RoutingManager::EvaluateOnLinkPrefix(void)
// We need to advertise our local on-link prefix since there is
// no discovered on-link prefix.
mOnLinkPrefixDeprecateTimer.Stop();
VerifyOrExit(!mIsAdvertisingLocalOnLinkPrefix);
SuccessOrExit(PublishExternalRoute(mLocalOnLinkPrefix, NetworkData::kRoutePreferenceMedium));
mIsAdvertisingLocalOnLinkPrefix = true;
LogInfo("Start advertising on-link prefix %s on %s", mLocalOnLinkPrefix.ToString().AsCString(),
mInfraIf.ToString().AsCString());
SuccessOrExit(mLocalOnLinkPrefix.Advertise());
// We remove the local on-link prefix from discovered prefix
// table, in case it was previously discovered and included in
@@ -530,12 +490,11 @@ void RoutingManager::EvaluateOnLinkPrefix(void)
// not allow the local on-link prefix to be added in the prefix
// table while we are advertising it.
mDiscoveredPrefixTable.RemoveOnLinkPrefix(mLocalOnLinkPrefix, DiscoveredPrefixTable::kKeepInNetData);
mDiscoveredPrefixTable.RemoveOnLinkPrefix(mLocalOnLinkPrefix.GetPrefix(),
DiscoveredPrefixTable::kKeepInNetData);
}
else
else if (mLocalOnLinkPrefix.IsAdvertising())
{
VerifyOrExit(mIsAdvertisingLocalOnLinkPrefix);
// When an application-specific on-link prefix is received and
// it is larger than the local prefix, we will not remove the
// advertised local prefix. In this case, there will be two
@@ -543,11 +502,11 @@ void RoutingManager::EvaluateOnLinkPrefix(void)
// converge to the same smallest/favored on-link prefix and the
// application-specific prefix is not used.
if (!(mLocalOnLinkPrefix < mFavoredDiscoveredOnLinkPrefix))
if (!(mLocalOmrPrefix.GetPrefix() < mFavoredDiscoveredOnLinkPrefix))
{
LogInfo("EvaluateOnLinkPrefix: There is already favored on-link prefix %s on %s",
mFavoredDiscoveredOnLinkPrefix.ToString().AsCString(), mInfraIf.ToString().AsCString());
DeprecateOnLinkPrefix();
mLocalOnLinkPrefix.Deprecate();
}
}
@@ -555,34 +514,6 @@ exit:
return;
}
void RoutingManager::HandleOnLinkPrefixDeprecateTimer(Timer &aTimer)
{
aTimer.Get<RoutingManager>().HandleOnLinkPrefixDeprecateTimer();
}
void RoutingManager::HandleOnLinkPrefixDeprecateTimer(void)
{
OT_ASSERT(!mIsAdvertisingLocalOnLinkPrefix);
LogInfo("Local on-link prefix %s expired", mLocalOnLinkPrefix.ToString().AsCString());
if (!mDiscoveredPrefixTable.ContainsOnLinkPrefix(mLocalOnLinkPrefix))
{
UnpublishExternalRoute(mLocalOnLinkPrefix);
}
}
void RoutingManager::DeprecateOnLinkPrefix(void)
{
OT_ASSERT(mIsAdvertisingLocalOnLinkPrefix);
mIsAdvertisingLocalOnLinkPrefix = false;
LogInfo("Deprecate local on-link prefix %s", mLocalOnLinkPrefix.ToString().AsCString());
mOnLinkPrefixDeprecateTimer.StartAt(mTimeAdvertisedOnLinkPrefix,
TimeMilli::SecToMsec(kDefaultOnLinkPrefixLifetime));
}
#if OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE
void RoutingManager::EvaluateNat64Prefix(void)
{
@@ -747,30 +678,10 @@ void RoutingManager::SendRouterAdvertisement(RouterAdvTxMode aRaTxMode)
NetworkData::Iterator iterator;
NetworkData::OnMeshPrefixConfig prefixConfig;
// Append PIO for local on-link prefix. Ensure it is either being
// Append PIO for local on-link prefix if is either being
// advertised or deprecated.
if (mIsAdvertisingLocalOnLinkPrefix || mOnLinkPrefixDeprecateTimer.IsRunning())
{
uint32_t validLifetime = kDefaultOnLinkPrefixLifetime;
uint32_t preferredLifetime = kDefaultOnLinkPrefixLifetime;
if (mOnLinkPrefixDeprecateTimer.IsRunning())
{
validLifetime = TimeMilli::MsecToSec(mOnLinkPrefixDeprecateTimer.GetFireTime() - TimerMilli::GetNow());
preferredLifetime = 0;
}
SuccessOrAssert(raMsg.AppendPrefixInfoOption(mLocalOnLinkPrefix, validLifetime, preferredLifetime));
if (mIsAdvertisingLocalOnLinkPrefix)
{
mTimeAdvertisedOnLinkPrefix = TimerMilli::GetNow();
}
LogInfo("RouterAdvert: Added PIO for %s (valid=%u, preferred=%u)", mLocalOnLinkPrefix.ToString().AsCString(),
validLifetime, preferredLifetime);
}
mLocalOnLinkPrefix.AppendAsPioTo(raMsg);
// Determine which previously advertised prefixes need to be
// invalidated. Under `kInvalidateAllPrevPrefixes` mode we need
@@ -931,7 +842,7 @@ bool RoutingManager::IsReceivedRouterAdvertFromManager(const Ip6::Nd::RouterAdve
VerifyOrExit(pio.IsValid());
pio.GetPrefix(prefix);
VerifyOrExit(prefix == mLocalOnLinkPrefix);
VerifyOrExit(prefix == mLocalOnLinkPrefix.GetPrefix());
break;
}
@@ -1127,9 +1038,9 @@ bool RoutingManager::ShouldProcessPrefixInfoOption(const Ip6::Nd::PrefixInfoOpti
ExitNow();
}
if (mIsAdvertisingLocalOnLinkPrefix)
if (mLocalOnLinkPrefix.IsAdvertising())
{
VerifyOrExit(aPrefix != mLocalOnLinkPrefix);
VerifyOrExit(aPrefix != mLocalOnLinkPrefix.GetPrefix());
}
shouldProcess = true;
@@ -2125,6 +2036,175 @@ exit:
return;
}
//---------------------------------------------------------------------------------------------------------------------
// LocalOnLinkPrefix
RoutingManager::LocalOnLinkPrefix::LocalOnLinkPrefix(Instance &aInstance)
: InstanceLocator(aInstance)
, mState(kIdle)
, mTimer(aInstance, HandleTimer)
{
mPrefix.Clear();
}
void RoutingManager::LocalOnLinkPrefix::Generate(void)
{
MeshCoP::ExtendedPanId extPanId = Get<MeshCoP::ExtendedPanIdManager>().GetExtPanId();
mPrefix.mPrefix.mFields.m8[0] = 0xfd;
// Global ID: 40 most significant bits of Extended PAN ID
memcpy(mPrefix.mPrefix.mFields.m8 + 1, extPanId.m8, 5);
// Subnet ID: 16 least significant bits of Extended PAN ID
memcpy(mPrefix.mPrefix.mFields.m8 + 6, extPanId.m8 + 6, 2);
mPrefix.SetLength(kOnLinkPrefixLength);
LogNote("Local on-link prefix: %s", mPrefix.ToString().AsCString());
}
void RoutingManager::LocalOnLinkPrefix::Start(void)
{
mState = kIdle;
}
void RoutingManager::LocalOnLinkPrefix::Stop(void)
{
VerifyOrExit(mState != kIdle);
Get<RoutingManager>().UnpublishExternalRoute(mPrefix);
mState = kDeprecating;
// Start deprecating the local on-link prefix to send a PIO
// with zero preferred lifetime in the next call to
// `SendRouterAdvertisement()`.
exit:
return;
}
Error RoutingManager::LocalOnLinkPrefix::Advertise(void)
{
// Start advertising the local on-link prefix if not already. This
// will also publish it in the Network Data as an external route
// entry.
Error error = kErrorNone;
VerifyOrExit(mState != kAdvertising);
mTimer.Stop();
SuccessOrExit(error = Get<RoutingManager>().PublishExternalRoute(mPrefix, NetworkData::kRoutePreferenceMedium));
mState = kAdvertising;
LogInfo("Start advertising on-link prefix %s", mPrefix.ToString().AsCString());
exit:
return error;
}
void RoutingManager::LocalOnLinkPrefix::Deprecate(void)
{
// Deprecate the local on-link prefix if it was being advertised
// before. While depreciating the prefix, we wait for the lifetime
// timer to expire before unpublishing the prefix from the Network
// Data. We also continue to include it as a PIO in the RA message
// with zero preferred lifetime and the remaining valid lifetime
// until the timer expires.
VerifyOrExit(mState == kAdvertising);
mState = kDeprecating;
LogInfo("Deprecate local on-link prefix %s", mPrefix.ToString().AsCString());
exit:
return;
}
void RoutingManager::LocalOnLinkPrefix::AppendAsPioTo(Ip6::Nd::RouterAdvertMessage &aRaMessage)
{
// Append the local on-link prefix to the `aRaMessage` as a PIO
// only if it is being advertised or deprecated.
//
// If in `kAdvertising` state, we restart the lifetime timer.
// If in `kDeprecating` state, we include it as PIO with zero
// preferred lifetime and the remaining valid lifetime which
// is tracked by the timer.
uint32_t validLifetime = kDefaultOnLinkPrefixLifetime;
uint32_t preferredLifetime = kDefaultOnLinkPrefixLifetime;
TimeMilli now;
switch (mState)
{
case kAdvertising:
mTimer.Start(TimeMilli::SecToMsec(kDefaultOnLinkPrefixLifetime));
break;
case kDeprecating:
now = TimerMilli::GetNow();
VerifyOrExit(mTimer.IsRunning() && (mTimer.GetFireTime() > now));
validLifetime = TimeMilli::MsecToSec(mTimer.GetFireTime() - now);
preferredLifetime = 0;
break;
case kIdle:
ExitNow();
}
SuccessOrAssert(aRaMessage.AppendPrefixInfoOption(mPrefix, validLifetime, preferredLifetime));
LogInfo("RouterAdvert: Added PIO for %s (valid=%u, preferred=%u)", mPrefix.ToString().AsCString(), validLifetime,
preferredLifetime);
exit:
return;
}
void RoutingManager::LocalOnLinkPrefix::HandleExtPanIdChange(void)
{
switch (mState)
{
case kIdle:
break;
case kAdvertising:
Get<RoutingManager>().UnpublishExternalRoute(mPrefix);
// TODO: consider deprecating/invalidating the existing
// on-link prefix.
break;
case kDeprecating:
mTimer.Stop();
break;
}
mState = kIdle;
Generate();
}
void RoutingManager::LocalOnLinkPrefix::HandleTimer(Timer &aTimer)
{
aTimer.Get<RoutingManager>().mLocalOnLinkPrefix.HandleTimer();
}
void RoutingManager::LocalOnLinkPrefix::HandleTimer(void)
{
VerifyOrExit(mState == kDeprecating);
LogInfo("Local on-link prefix %s expired", mPrefix.ToString().AsCString());
if (!Get<RoutingManager>().mDiscoveredPrefixTable.ContainsOnLinkPrefix(mPrefix))
{
Get<RoutingManager>().UnpublishExternalRoute(mPrefix);
}
mState = kIdle;
exit:
return;
}
//---------------------------------------------------------------------------------------------------------------------
// OnMeshPrefixArray
+33 -14
View File
@@ -515,7 +515,7 @@ private:
RoutePreference mPreference;
};
class LocalOmrPrefix : InstanceLocator
class LocalOmrPrefix : public InstanceLocator
{
public:
explicit LocalOmrPrefix(Instance &aInstance);
@@ -531,6 +531,37 @@ private:
bool mIsAddedInNetData;
};
class LocalOnLinkPrefix : public InstanceLocator
{
public:
explicit LocalOnLinkPrefix(Instance &aInstance);
void Generate(void);
void Start(void);
void Stop(void);
Error Advertise(void);
void Deprecate(void);
void AppendAsPioTo(Ip6::Nd::RouterAdvertMessage &aRaMessage);
const Ip6::Prefix &GetPrefix(void) const { return mPrefix; }
bool IsAdvertising(void) const { return (mState == kAdvertising); }
void HandleExtPanIdChange(void);
private:
enum State : uint8_t
{
kIdle,
kAdvertising,
kDeprecating,
};
static void HandleTimer(Timer &aTimer);
void HandleTimer(void);
Ip6::Prefix mPrefix;
State mState;
TimerMilli mTimer;
};
typedef Ip6::Prefix OnMeshPrefix;
class OnMeshPrefixArray : public Array<OnMeshPrefix, kMaxOnMeshPrefixes>
@@ -547,7 +578,6 @@ private:
bool IsInitialized(void) const { return mInfraIf.IsInitialized(); }
bool IsEnabled(void) const { return mIsEnabled; }
Error LoadOrGenerateRandomBrUlaPrefix(void);
void GenerateOnLinkPrefix(void);
void EvaluateOnLinkPrefix(void);
@@ -574,8 +604,6 @@ private:
static void HandleDiscoveredPrefixStaleTimer(Timer &aTimer);
void HandleDiscoveredPrefixStaleTimer(void);
static void HandleRoutingPolicyTimer(Timer &aTimer);
void HandleOnLinkPrefixDeprecateTimer(void);
static void HandleOnLinkPrefixDeprecateTimer(Timer &aTimer);
void DeprecateOnLinkPrefix(void);
void HandleRouterSolicit(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress);
@@ -619,16 +647,7 @@ private:
// Prefix length of zero indicates there is none.
Ip6::Prefix mFavoredDiscoveredOnLinkPrefix;
// The on-link prefix loaded from local persistent storage or
// randomly generated if non is found in persistent storage.
Ip6::Prefix mLocalOnLinkPrefix;
bool mIsAdvertisingLocalOnLinkPrefix;
// The last time when the on-link prefix is advertised with
// non-zero preferred lifetime.
TimeMilli mTimeAdvertisedOnLinkPrefix;
TimerMilli mOnLinkPrefixDeprecateTimer;
LocalOnLinkPrefix mLocalOnLinkPrefix;
// The NAT64 prefix allocated from the /48 BR ULA prefix.
Ip6::Prefix mLocalNat64Prefix;
+138
View File
@@ -81,6 +81,7 @@ bool sRsEmitted; // Indicates if an RS message was emitted by BR.
bool sRaValidated; // Indicates if an RA was emitted by BR and successfully validated.
bool sSawExpectedRio; // Indicates if the emitted RA by BR contained an RIO with `sExpectedRioPrefix`
ExpectedPio sExpectedPio; // Expected PIO in the emitted RA by BR (MUST be seen in RA to set `sRaValidated`).
uint32_t sOnLinkLifetime; // Valid lifetime for local on-link prefix from the last processed RA.
Ip6::Prefix sExpectedRioPrefix; // Expected RIO prefix to see in RA (MUST be seen to set `sSawExpectedRio`).
//----------------------------------------------------------------------------------------------------------------------
@@ -245,6 +246,8 @@ void ValidateRouterAdvert(const Icmp6Packet &aPacket)
VerifyOrQuit(pio.GetPreferredLifetime() == 0, "On link prefix is not deprecated");
}
sOnLinkLifetime = pio.GetValidLifetime();
break;
}
@@ -1105,6 +1108,140 @@ void TestDefaultRoute(void)
testFreeInstance(sInstance);
}
void TestLocalOnLinkPrefixDeprecation(void)
{
static constexpr uint32_t kMaxRaTxInterval = 601; // In seconds
Ip6::Prefix localOnLink;
Ip6::Prefix localOmr;
Ip6::Prefix onLinkPrefix = PrefixFromString("2000:abba:baba::", 64);
Ip6::Address routerAddressA = AddressFromString("fd00::aaaa");
uint32_t localOnLinkLifetime;
Log("--------------------------------------------------------------------------------------------");
Log("TestLocalOnLinkPrefixDeprecation");
InitTest();
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Start Routing Manager. Check emitted RS and RA messages.
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());
sRsEmitted = false;
sRaValidated = false;
sSawExpectedRio = false;
sExpectedPio = kPioAdvertisingLocalOnLink;
sExpectedRioPrefix = localOmr;
AdvanceTime(30000);
VerifyOrQuit(sRsEmitted);
VerifyOrQuit(sRaValidated);
VerifyOrQuit(sSawExpectedRio);
Log("Local on-link prefix is being advertised, lifetime: %d", sOnLinkLifetime);
localOnLinkLifetime = sOnLinkLifetime;
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check Network Data to include the local OMR and on-link prefix.
VerifyOmrPrefixInNetData(localOmr);
VerifyExternalRoutesInNetData({ExternalRoute(localOnLink, NetworkData::kRoutePreferenceMedium)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Send an RA from router A with a new on-link (PIO) which is preferred over
// the local on-link prefix.
SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check that the local on-link prefix is now deprecating in the new RA.
sRaValidated = false;
sSawExpectedRio = false;
sExpectedPio = kPioDeprecatingLocalOnLink;
AdvanceTime(10000);
VerifyOrQuit(sRaValidated);
VerifyOrQuit(sSawExpectedRio);
Log("On-link prefix is deprecating, remaining lifetime:%d", sOnLinkLifetime);
VerifyOrQuit(sOnLinkLifetime < localOnLinkLifetime);
localOnLinkLifetime = sOnLinkLifetime;
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check Network Data. We must see the new on-link prefix from router A
// along with the deprecating local on-link prefix.
VerifyOmrPrefixInNetData(localOmr);
VerifyExternalRoutesInNetData({ExternalRoute(localOnLink, NetworkData::kRoutePreferenceMedium),
ExternalRoute(onLinkPrefix, NetworkData::kRoutePreferenceMedium)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Wait for local on-link prefix to expire
while (localOnLinkLifetime > kMaxRaTxInterval)
{
// Send same RA from router A to keep the on-link prefix alive.
SendRouterAdvert(routerAddressA, {Pio(onLinkPrefix, kValidLitime, kPreferredLifetime)});
// Ensure Network Data entries remain as before. Mainly we still
// see the deprecating local on-link prefix.
VerifyOmrPrefixInNetData(localOmr);
VerifyExternalRoutesInNetData({ExternalRoute(localOnLink, NetworkData::kRoutePreferenceMedium),
ExternalRoute(onLinkPrefix, NetworkData::kRoutePreferenceMedium)});
// Keep checking the emitted RAs and make sure on-link prefix
// is included with smaller lifetime every time.
sRaValidated = false;
sSawExpectedRio = false;
sExpectedPio = kPioDeprecatingLocalOnLink;
AdvanceTime(kMaxRaTxInterval * 1000);
VerifyOrQuit(sRaValidated);
VerifyOrQuit(sSawExpectedRio);
Log("On-link prefix is deprecating, remaining lifetime:%d", sOnLinkLifetime);
VerifyOrQuit(sOnLinkLifetime < localOnLinkLifetime);
localOnLinkLifetime = sOnLinkLifetime;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// The local on-link prefix must be expired and should no
// longer be seen in the emitted RA message.
sRaValidated = false;
sSawExpectedRio = false;
sExpectedPio = kNoPio;
AdvanceTime(kMaxRaTxInterval * 1000);
VerifyOrQuit(sRaValidated);
VerifyOrQuit(sSawExpectedRio);
Log("On-link prefix is now expired");
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check Network Data and make sure the the expired local on-link prefix
// is removed.
VerifyOmrPrefixInNetData(localOmr);
VerifyExternalRoutesInNetData({ExternalRoute(onLinkPrefix, NetworkData::kRoutePreferenceMedium)});
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Log("End of TestLocalOnLinkPrefixDeprecation");
testFreeInstance(sInstance);
}
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
int main(void)
@@ -1113,6 +1250,7 @@ int main(void)
TestSamePrefixesFromMultipleRouters();
TestOmrSelection();
TestDefaultRoute();
TestLocalOnLinkPrefixDeprecation();
printf("All tests passed\n");
#else
printf("BORDER_ROUTING feature is not enabled\n");