[routing-manager] add ScheduleRoutingPolicyEvaluation() (#8115)

This commit adds a new method `ScheduleRoutingPolicyEvaluation()` in
`RoutingManager` which combines the logic from different related
methods. This helps simplify the code. The new method accept an enum
`SchduleMode` input which indicates the rule to use when determining
the next policy evaluation time, e.g., schedule it immediately, or
after a random delay, or after short random jitter time to reply to
a received RS, etc.
This commit is contained in:
Abtin Keshavarzian
2022-09-06 08:49:27 -07:00
committed by GitHub
parent 46c7dccfef
commit f43b9f0332
2 changed files with 51 additions and 43 deletions
+35 -32
View File
@@ -135,7 +135,7 @@ void RoutingManager::SetRouteInfoOptionPreference(RoutePreference aPreference)
mRouteInfoOptionPreference = aPreference;
VerifyOrExit(mIsRunning);
StartRoutingPolicyEvaluationJitter(kRoutingPolicyEvaluationJitterMin, kRoutingPolicyEvaluationJitterMax);
ScheduleRoutingPolicyEvaluation(kAfterRandomDelay);
exit:
return;
@@ -260,7 +260,7 @@ void RoutingManager::UpdateInfraIfNat64Prefix(const Ip6::Prefix &aPrefix)
if (mIsRunning)
{
StartRoutingPolicyEvaluationJitter(kRoutingPolicyEvaluationJitterMin, kRoutingPolicyEvaluationJitterMax);
ScheduleRoutingPolicyEvaluation(kAfterRandomDelay);
}
}
@@ -381,7 +381,7 @@ void RoutingManager::HandleNotifierEvents(Events aEvents)
if (mIsRunning && aEvents.Contains(kEventThreadNetdataChanged))
{
UpdateDiscoveredPrefixTableOnNetDataChange();
StartRoutingPolicyEvaluationJitter(kRoutingPolicyEvaluationJitterMin, kRoutingPolicyEvaluationJitterMax);
ScheduleRoutingPolicyEvaluation(kAfterRandomDelay);
}
if (aEvents.Contains(kEventThreadExtPanIdChanged))
@@ -390,7 +390,7 @@ void RoutingManager::HandleNotifierEvents(Events aEvents)
if (mIsRunning)
{
StartRoutingPolicyEvaluationJitter(kRoutingPolicyEvaluationJitterMin, kRoutingPolicyEvaluationJitterMax);
ScheduleRoutingPolicyEvaluation(kAfterRandomDelay);
}
}
@@ -626,45 +626,49 @@ void RoutingManager::EvaluateRoutingPolicy(void)
LogInfo("Evaluating routing policy");
// 0. Evaluate on-link, OMR and NAT64 prefixes.
EvaluateOnLinkPrefix();
EvaluateOmrPrefix();
#if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
EvaluateNat64Prefix();
#endif
// 1. Send Router Advertisement message if necessary.
SendRouterAdvertisement(kAdvPrefixesFromNetData);
// 2. Schedule routing policy timer with random interval for the next Router Advertisement.
ScheduleRoutingPolicyEvaluation(kForNextRa);
}
void RoutingManager::ScheduleRoutingPolicyEvaluation(ScheduleMode aMode)
{
TimeMilli now = TimerMilli::GetNow();
uint32_t delay = 0;
TimeMilli evaluateTime;
switch (aMode)
{
uint32_t nextSendDelay;
case kImmediately:
break;
nextSendDelay = Random::NonCrypto::GetUint32InRange(kMinRtrAdvInterval, kMaxRtrAdvInterval);
case kForNextRa:
delay = Random::NonCrypto::GetUint32InRange(Time::SecToMsec(kMinRtrAdvInterval),
Time::SecToMsec(kMaxRtrAdvInterval));
if (mRaInfo.mTxCount <= kMaxInitRtrAdvertisements && nextSendDelay > kMaxInitRtrAdvInterval)
if (mRaInfo.mTxCount <= kMaxInitRtrAdvertisements && delay > Time::SecToMsec(kMaxInitRtrAdvInterval))
{
nextSendDelay = kMaxInitRtrAdvInterval;
delay = Time::SecToMsec(kMaxInitRtrAdvInterval);
}
break;
StartRoutingPolicyEvaluationDelay(Time::SecToMsec(nextSendDelay));
case kAfterRandomDelay:
delay = Random::NonCrypto::GetUint32InRange(kPolicyEvaluationMinDelay, kPolicyEvaluationMaxDelay);
break;
case kToReplyToRs:
delay = Random::NonCrypto::GetUint32InRange(0, kRaReplyJitter);
break;
}
}
void RoutingManager::StartRoutingPolicyEvaluationJitter(uint32_t aJitterMilliMin, uint32_t aJitterMilliMax)
{
OT_ASSERT(mIsRunning);
StartRoutingPolicyEvaluationDelay(Random::NonCrypto::GetUint32InRange(aJitterMilliMin, aJitterMilliMax));
}
void RoutingManager::StartRoutingPolicyEvaluationDelay(uint32_t aDelayMilli)
{
TimeMilli now = TimerMilli::GetNow();
TimeMilli evaluateTime = now + aDelayMilli;
TimeMilli earliestTime = mRaInfo.mLastTxTime + kMinDelayBetweenRtrAdvs;
evaluateTime = Max(evaluateTime, earliestTime);
// Ensure we wait a min delay after last RA tx
evaluateTime = Max(now + delay, mRaInfo.mLastTxTime + kMinDelayBetweenRtrAdvs);
LogInfo("Start evaluating routing policy, scheduled in %u milliseconds", evaluateTime - now);
@@ -1022,7 +1026,7 @@ void RoutingManager::HandleRouterSolicitTimer(void)
mRouterSolicitCount = 0;
// Re-evaluate our routing policy and send Router Advertisement if necessary.
StartRoutingPolicyEvaluationDelay(/* aDelayJitter */ 0);
ScheduleRoutingPolicyEvaluation(kImmediately);
}
}
@@ -1065,8 +1069,7 @@ void RoutingManager::HandleRouterSolicit(const InfraIf::Icmp6Packet &aPacket, co
LogInfo("Received Router Solicitation from %s on %s", aSrcAddress.ToString().AsCString(),
mInfraIf.ToString().AsCString());
// Schedule routing policy evaluation with random jitter to respond with Router Advertisement.
StartRoutingPolicyEvaluationJitter(0, kRaReplyJitter);
ScheduleRoutingPolicyEvaluation(kToReplyToRs);
}
void RoutingManager::HandleRouterAdvertisement(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress)
@@ -1181,7 +1184,7 @@ void RoutingManager::HandleDiscoveredPrefixTableChanged(void)
if (newFavoredPrefix != mFavoredDiscoveredOnLinkPrefix)
{
StartRoutingPolicyEvaluationJitter(kRoutingPolicyEvaluationJitterMin, kRoutingPolicyEvaluationJitterMax);
ScheduleRoutingPolicyEvaluation(kAfterRandomDelay);
}
exit:
@@ -1247,7 +1250,7 @@ void RoutingManager::UpdateRouterAdvertHeader(const Ip6::Nd::RouterAdvertMessage
// reevaluate routing policy and send RA message with new
// header.
StartRoutingPolicyEvaluationJitter(kRoutingPolicyEvaluationJitterMin, kRoutingPolicyEvaluationJitterMax);
ScheduleRoutingPolicyEvaluation(kAfterRandomDelay);
}
exit:
+16 -11
View File
@@ -331,13 +331,11 @@ private:
static constexpr uint32_t kMaxRtrAdvInterval = 600; // Max Router Advertisement Interval. In sec.
static constexpr uint32_t kMinRtrAdvInterval = kMaxRtrAdvInterval / 3; // Min RA Interval. In sec.
static constexpr uint32_t kMaxInitRtrAdvInterval = 16; // Max Initial RA Interval. In sec.
static constexpr uint32_t kRaReplyJitter = 500; // Jitter for sending RA after rx RS. In msec.
static constexpr uint32_t kRtrSolicitationInterval = 4; // Interval between RSs. In sec.
static constexpr uint32_t kMaxRtrSolicitationDelay = 1; // Max delay for initial solicitation. In sec.
static constexpr uint32_t kRoutingPolicyEvaluationJitterMin =
2000; // Min jitter for routing policy evaluation. In msec.
static constexpr uint32_t kRoutingPolicyEvaluationJitterMax =
4000; // Max jitter for routing policy evaluation. In msec.
static constexpr uint32_t kRaReplyJitter = 500; // Jitter for sending RA after rx RS. In msec.
static constexpr uint32_t kRtrSolicitationInterval = 4; // Interval between RSs. In sec.
static constexpr uint32_t kMaxRtrSolicitationDelay = 1; // Max delay for initial solicitation. In sec.
static constexpr uint32_t kPolicyEvaluationMinDelay = 2000; // Min delay for policy evaluation. In msec.
static constexpr uint32_t kPolicyEvaluationMaxDelay = 4000; // Max delay for policy evaluation. In msec.
static constexpr uint32_t kRtrSolicitationRetryDelay =
kRtrSolicitationInterval; // The delay before retrying failed RS tx. In Sec.
static constexpr uint32_t kMinDelayBetweenRtrAdvs = 3000; // Min delay (msec) between consecutive RAs.
@@ -355,8 +353,8 @@ private:
static_assert(kDefaultOnLinkPrefixLifetime >= kMaxRtrAdvInterval, "invalid default on-link prefix lifetime");
static_assert(kRtrAdvStaleTime >= 1800 && kRtrAdvStaleTime <= kDefaultOnLinkPrefixLifetime,
"invalid RA STALE time");
static_assert(kRoutingPolicyEvaluationJitterMax > kRoutingPolicyEvaluationJitterMin,
"kRoutingPolicyEvaluationJitterMax must be larger than kRoutingPolicyEvaluationJitterMin");
static_assert(kPolicyEvaluationMaxDelay > kPolicyEvaluationMinDelay,
"kPolicyEvaluationMaxDelay must be larger than kPolicyEvaluationMinDelay");
enum RouterAdvTxMode : uint8_t // Used in `SendRouterAdvertisement()`
{
@@ -364,6 +362,14 @@ private:
kAdvPrefixesFromNetData,
};
enum ScheduleMode : uint8_t // Used in `ScheduleRoutingPolicyEvaluation()`
{
kImmediately,
kForNextRa,
kAfterRandomDelay,
kToReplyToRs,
};
void HandleDiscoveredPrefixTableChanged(void); // Declare early so we can use in `mSignalTask`
class DiscoveredPrefixTable : public InstanceLocator
@@ -662,8 +668,7 @@ private:
#endif
void EvaluateRoutingPolicy(void);
void StartRoutingPolicyEvaluationJitter(uint32_t aJitterMilliMin, uint32_t aJitterMilliMax);
void StartRoutingPolicyEvaluationDelay(uint32_t aDelayMilli);
void ScheduleRoutingPolicyEvaluation(ScheduleMode aMode);
void EvaluateOmrPrefix(void);
Error PublishExternalRoute(const Ip6::Prefix &aPrefix, RoutePreference aRoutePreference, bool aNat64 = false);
void UnpublishExternalRoute(const Ip6::Prefix &aPrefix);