mirror of
https://github.com/espressif/openthread.git
synced 2026-08-13 14:17:47 +00:00
[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:
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user