Skip to content

Commit 3701e48

Browse files
committed
[routing-manager] defer OMR prefix removal with a randomized delay
When `OmrPrefixManager` yields to a more-favored peer prefix, `RemoveLocalFromNetData()` is called immediately, producing back-to-back Network Data version bumps. According to the OMR section in Thread spec, cooperative (preference-based) removal should use a randomized delay, and not an immediate withdrawal. This change adds `kToRemove` to `LocalPrefixState` completing the delayed-removal path in openthread#12753.
1 parent 06e210f commit 3701e48

2 files changed

Lines changed: 49 additions & 12 deletions

File tree

src/core/border_router/routing_manager.cpp

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,11 @@ void RoutingManager::OmrPrefixManager::Evaluate(void)
995995
break;
996996
}
997997

998+
case kToRemove:
999+
// No favored prefix; cancel the pending removal and re-add our local prefix.
1000+
AddLocalToNetData();
1001+
break;
1002+
9981003
case kAdded:
9991004
case kToAdd:
10001005
break;
@@ -1013,19 +1018,44 @@ void RoutingManager::OmrPrefixManager::Evaluate(void)
10131018
// we remove our local prefix if it is added or scheduled to be added.
10141019

10151020
SetFavoredPrefix(favoredPrefix);
1016-
RemoveLocalFromNetData();
1021+
1022+
switch (mLocalInNetDataState)
1023+
{
1024+
case kAdded:
1025+
{
1026+
uint32_t delay = Random::NonCrypto::GenerateInClosedRange(kMinDelayToRemove, kMaxDelayToRemove);
1027+
1028+
mLocalInNetDataState = kToRemove;
1029+
mTimer.Start(delay);
1030+
LogInfo("Will remove %s from NetData in %lu msec", LocalToString().AsCString(), ToUlong(delay));
1031+
break;
1032+
}
1033+
1034+
case kToAdd:
1035+
// Prefix not yet in Network Data; cancel the pending add.
1036+
mTimer.Stop();
1037+
mLocalInNetDataState = kNotAdded;
1038+
break;
1039+
1040+
case kToRemove:
1041+
case kNotAdded:
1042+
break;
1043+
}
10171044

10181045
exit:
10191046
return;
10201047
}
10211048

10221049
void RoutingManager::OmrPrefixManager::HandleTimer(void)
10231050
{
1024-
VerifyOrExit(mLocalInNetDataState == kToAdd);
1025-
AddLocalToNetData();
1026-
1027-
exit:
1028-
return;
1051+
if (mLocalInNetDataState == kToAdd)
1052+
{
1053+
AddLocalToNetData();
1054+
}
1055+
else if (mLocalInNetDataState == kToRemove)
1056+
{
1057+
RemoveLocalFromNetData();
1058+
}
10291059
}
10301060

10311061
bool RoutingManager::OmrPrefixManager::ShouldAdvertiseLocalAsRio(void) const
@@ -1113,6 +1143,8 @@ void RoutingManager::OmrPrefixManager::RemoveLocalFromNetData(void)
11131143
switch (mLocalInNetDataState)
11141144
{
11151145
case kAdded:
1146+
case kToRemove:
1147+
mTimer.Stop();
11161148
IgnoreError(Get<NetworkData::Local>().RemoveOnMeshPrefix(mLocalPrefix.GetPrefix()));
11171149
Get<NetworkData::Notifier>().HandleServerDataUpdated();
11181150
LogInfo("Removed %s from NetData", LocalToString().AsCString());

src/core/border_router/routing_manager.hpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -643,12 +643,16 @@ class RoutingManager : public InstanceLocator
643643
#endif
644644

645645
private:
646-
// All times are in msec
647-
static constexpr uint32_t kMinDelayToAdd = 250;
648-
static constexpr uint32_t kMaxDelayToAdd = kMinDelayToAdd + 3500;
649-
static constexpr uint32_t kRetryDelay = 1500;
650-
static constexpr uint16_t kRetryJitter = 150;
651-
static constexpr uint16_t kInfoStringSize = 85;
646+
// All times are in msec.
647+
static constexpr uint32_t kMinDelayToAdd = 250;
648+
static constexpr uint32_t kMaxDelayToAdd =
649+
kMinDelayToAdd + OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_DELAY_TO_ADD;
650+
static constexpr uint32_t kMinDelayToRemove =
651+
kMaxDelayToAdd; // never remove before the peer's add window closes
652+
static constexpr uint32_t kMaxDelayToRemove = OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_DELAY_TO_REMOVE;
653+
static constexpr uint32_t kRetryDelay = 1500;
654+
static constexpr uint16_t kRetryJitter = 150;
655+
static constexpr uint16_t kInfoStringSize = 85;
652656

653657
typedef String<kInfoStringSize> InfoString;
654658

@@ -664,6 +668,7 @@ class RoutingManager : public InstanceLocator
664668
kNotAdded,
665669
kToAdd,
666670
kAdded,
671+
kToRemove,
667672
};
668673

669674
void SetFavoredPrefix(const OmrPrefix &aOmrPrefix);

0 commit comments

Comments
 (0)