Skip to content

Commit

Permalink
[routing-manager] update and simplify RA beacon timing (openthread#10309
Browse files Browse the repository at this point in the history
)

This commit updates constants in `RoutingManager`. Timing constants
are now consistently specified as an interval with an associated
jitter, where the actual interval is randomly selected within the
range `[interval - jitter, interval + jitter]`.

The initial transmission of three RAs with a short interval of 16
seconds (± 2 seconds jitter) remains unchanged. However, subsequent
RA transmissions now use a regular beacon interval of 3 minutes (± 15
seconds jitter), replacing the previous random interval selection
within `[200, 600]` seconds.

The selection of 3 minutes as the regular RA beacon interval aligns
the implementation with the latest stub router RFC draft's
`RA_BEACON_INTERVAL` default value.
  • Loading branch information
abtink authored May 31, 2024
1 parent ca7dd82 commit 7b08e9a
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 41 deletions.
30 changes: 20 additions & 10 deletions src/core/border_router/routing_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,8 +508,10 @@ bool RoutingManager::IsInitalPolicyEvaluationDone(void) const

void RoutingManager::ScheduleRoutingPolicyEvaluation(ScheduleMode aMode)
{
TimeMilli now = TimerMilli::GetNow();
uint32_t delay = 0;
TimeMilli now = TimerMilli::GetNow();
uint32_t delay = 0;
uint32_t interval = 0;
uint16_t jitter = 0;
TimeMilli evaluateTime;

VerifyOrExit(mIsRunning);
Expand All @@ -520,26 +522,34 @@ void RoutingManager::ScheduleRoutingPolicyEvaluation(ScheduleMode aMode)
break;

case kForNextRa:
delay = Random::NonCrypto::GetUint32InRange(Time::SecToMsec(kMinRtrAdvInterval),
Time::SecToMsec(kMaxRtrAdvInterval));

if (mTxRaInfo.mTxCount <= kMaxInitRtrAdvertisements && delay > Time::SecToMsec(kMaxInitRtrAdvInterval))
if (mTxRaInfo.mTxCount <= kInitalRaTxCount)
{
delay = Time::SecToMsec(kMaxInitRtrAdvInterval);
interval = kInitalRaInterval;
jitter = kInitialRaJitter;
}
else
{
interval = kRaBeaconInterval;
jitter = kRaBeaconJitter;
}

break;

case kAfterRandomDelay:
delay = Random::NonCrypto::GetUint32InRange(kPolicyEvaluationMinDelay, kPolicyEvaluationMaxDelay);
interval = kEvaluationInterval;
jitter = kEvaluationJitter;
break;

case kToReplyToRs:
delay = Random::NonCrypto::GetUint32InRange(0, kRaReplyJitter);
interval = kRsReplyInterval;
jitter = kRsReplyJitter;
break;
}

delay = Random::NonCrypto::AddJitter(interval, jitter);

// Ensure we wait a min delay after last RA tx
evaluateTime = Max(now + delay, mTxRaInfo.mLastTxTime + kMinDelayBetweenRtrAdvs);
evaluateTime = Max(now + delay, mTxRaInfo.mLastTxTime + kMinDelayBetweenRas);

mRoutingPolicyTimer.FireAtIfEarlier(evaluateTime);

Expand Down
63 changes: 33 additions & 30 deletions src/core/border_router/routing_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -567,27 +567,38 @@ class RoutingManager : public InstanceLocator

static constexpr uint8_t kMaxOnMeshPrefixes = OPENTHREAD_CONFIG_BORDER_ROUTING_MAX_ON_MESH_PREFIXES;

static constexpr uint8_t kOmrPrefixLength = OT_IP6_PREFIX_BITSIZE; // The length of an OMR prefix. In bits.
static constexpr uint8_t kOnLinkPrefixLength = OT_IP6_PREFIX_BITSIZE; // The length of an On-link prefix. In bits.
static constexpr uint8_t kBrUlaPrefixLength = 48; // The length of a BR ULA prefix. In bits.
static constexpr uint8_t kNat64PrefixLength = 96; // The length of a NAT64 prefix. In bits.

static constexpr uint16_t kOmrPrefixSubnetId = 1; // The subnet ID of an OMR prefix within a BR ULA prefix.
static constexpr uint16_t kNat64PrefixSubnetId = 2; // The subnet ID of a NAT64 prefix within a BR ULA prefix.

// The maximum number of initial Router Advertisements.
static constexpr uint32_t kMaxInitRtrAdvertisements = 3;

static constexpr uint32_t kDefaultOmrPrefixLifetime = 1800; // The default OMR prefix valid lifetime. In sec.
static constexpr uint32_t kDefaultOnLinkPrefixLifetime = 1800; // The default on-link prefix valid lifetime. In sec.
static constexpr uint32_t kDefaultNat64PrefixLifetime = 300; // The default NAT64 prefix valid lifetime. In sec.
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 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 kMinDelayBetweenRtrAdvs = 3000; // Min delay (msec) between consecutive RAs.
// Prefix length in bits.
static constexpr uint8_t kOmrPrefixLength = 64;
static constexpr uint8_t kOnLinkPrefixLength = 64;
static constexpr uint8_t kBrUlaPrefixLength = 48;
static constexpr uint8_t kNat64PrefixLength = 96;

// Subnet IDs for OMR and NAT64 prefixes.
static constexpr uint16_t kOmrPrefixSubnetId = 1;
static constexpr uint16_t kNat64PrefixSubnetId = 2;

// Default valid lifetime. In seconds.
static constexpr uint32_t kDefaultOmrPrefixLifetime = 1800;
static constexpr uint32_t kDefaultOnLinkPrefixLifetime = 1800;
static constexpr uint32_t kDefaultNat64PrefixLifetime = 300;

// RA transmission constants (in milliseconds). Initially, three
// RAs are sent with a short interval of 16 seconds (± 2 seconds
// jitter). Subsequently, a longer, regular RA beacon interval of
// 3 minutes (± 15 seconds jitter) is used. The actual interval is
// randomly selected within the range [interval - jitter,
// interval + jitter].

static constexpr uint32_t kInitalRaTxCount = 3;
static constexpr uint32_t kInitalRaInterval = Time::kOneSecondInMsec * 16;
static constexpr uint16_t kInitialRaJitter = Time::kOneSecondInMsec * 2;
static constexpr uint32_t kRaBeaconInterval = Time::kOneSecondInMsec * 180; // 3 minutes
static constexpr uint16_t kRaBeaconJitter = Time::kOneSecondInMsec * 15;
static constexpr uint32_t kMinDelayBetweenRas = Time::kOneSecondInMsec * 3;
static constexpr uint32_t kRsReplyInterval = 250;
static constexpr uint16_t kRsReplyJitter = 250;
static constexpr uint32_t kEvaluationInterval = Time::kOneSecondInMsec * 3;
static constexpr uint16_t kEvaluationJitter = Time::kOneSecondInMsec * 1;

// The STALE_RA_TIME in seconds. The Routing Manager will consider the prefixes
// and learned RA parameters STALE when they are not refreshed in STALE_RA_TIME
Expand All @@ -597,14 +608,6 @@ class RoutingManager : public InstanceLocator
// The value is chosen in range of [`kMaxRtrAdvInterval` upper bound (1800s), `kDefaultOnLinkPrefixLifetime`].
static constexpr uint32_t kRtrAdvStaleTime = 1800;

static_assert(kMinRtrAdvInterval <= 3 * kMaxRtrAdvInterval / 4, "invalid RA intervals");
static_assert(kDefaultOmrPrefixLifetime >= kMaxRtrAdvInterval, "invalid default OMR prefix lifetime");
static_assert(kDefaultOnLinkPrefixLifetime >= kMaxRtrAdvInterval, "invalid default on-link prefix lifetime");
static_assert(kRtrAdvStaleTime >= 1800 && kRtrAdvStaleTime <= kDefaultOnLinkPrefixLifetime,
"invalid RA STALE time");
static_assert(kPolicyEvaluationMaxDelay > kPolicyEvaluationMinDelay,
"kPolicyEvaluationMaxDelay must be larger than kPolicyEvaluationMinDelay");

//------------------------------------------------------------------------------------------------------------------
// Typedefs

Expand Down Expand Up @@ -1251,7 +1254,7 @@ class RoutingManager : public InstanceLocator

TxRaInfo(void)
: mTxCount(0)
, mLastTxTime(TimerMilli::GetNow() - kMinDelayBetweenRtrAdvs)
, mLastTxTime(TimerMilli::GetNow() - kMinDelayBetweenRas)
, mLastHashIndex(0)
{
}
Expand Down
8 changes: 7 additions & 1 deletion src/core/common/random.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,15 @@ void FillBuffer(uint8_t *aBuffer, uint16_t aSize)

uint32_t AddJitter(uint32_t aValue, uint16_t aJitter)
{
uint32_t delay = 0;

VerifyOrExit(aValue != 0);

aJitter = (aJitter <= aValue) ? aJitter : static_cast<uint16_t>(aValue);
delay = aValue + GetUint32InRange(0, 2 * aJitter + 1) - aJitter;

return aValue + GetUint32InRange(0, 2 * aJitter + 1) - aJitter;
exit:
return delay;
}

} // namespace NonCrypto
Expand Down

0 comments on commit 7b08e9a

Please sign in to comment.