From f43b9f03325a2400f10dd5473d594ba4e212373a Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Tue, 6 Sep 2022 08:49:27 -0700 Subject: [PATCH] [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. --- src/core/border_router/routing_manager.cpp | 67 +++++++++++----------- src/core/border_router/routing_manager.hpp | 27 +++++---- 2 files changed, 51 insertions(+), 43 deletions(-) diff --git a/src/core/border_router/routing_manager.cpp b/src/core/border_router/routing_manager.cpp index 65cc89b1c..642b15f54 100644 --- a/src/core/border_router/routing_manager.cpp +++ b/src/core/border_router/routing_manager.cpp @@ -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: diff --git a/src/core/border_router/routing_manager.hpp b/src/core/border_router/routing_manager.hpp index 4c7d163af..e3a0087cd 100644 --- a/src/core/border_router/routing_manager.hpp +++ b/src/core/border_router/routing_manager.hpp @@ -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);