[bbr] fix primary BBR registration flakiness on leader (#12783)

This commit fixes an intermittent failure in the Nexus test
1_2_BBR_TC_2 by ensuring that the Backbone Router (BBR) service
is registered immediately when a node assumes the Leader role and
no primary BBR is active.

Previously, BbrLeader only tracked network data changes, and
BbrLocal applied a mandatory jitter delay before registration.
This created a race condition where another node could register
its BBR service before the new Leader, causing the Leader to
incorrectly skip its own registration.

Changes:
- Update BbrLeader to monitor role changes (kEventThreadRoleChanged).
- Modify BbrLocal to bypass registration jitter if the node is
  the Leader and there is no existing primary BBR.
This commit is contained in:
Jonathan Hui
2026-03-27 16:42:01 -05:00
committed by GitHub
parent d630934857
commit c5108df3e3
2 changed files with 11 additions and 8 deletions
+1 -1
View File
@@ -127,7 +127,7 @@ const char *Leader::DomainPrefixEventToString(DomainPrefixEvent aEvent)
void Leader::HandleNotifierEvents(Events aEvents)
{
if (aEvents.Contains(kEventThreadNetdataChanged))
if (aEvents.ContainsAny(kEventThreadNetdataChanged | kEventThreadRoleChanged))
{
UpdateBackboneRouterPrimary();
UpdateDomainPrefixConfig();
+10 -7
View File
@@ -246,15 +246,18 @@ void Local::HandleBackboneRouterPrimaryUpdate(Leader::State aState, const Config
// Wait some jitter before trying to Register.
if (aConfig.mServer16 == Mle::kInvalidRloc16)
{
mRegistrationTimeout = 1;
if (!Get<Mle::Mle>().IsLeader())
if (Get<Mle::Mle>().IsLeader())
{
mRegistrationTimeout +=
Random::NonCrypto::GetUint16InRange(0, static_cast<uint16_t>(mRegistrationJitter) + 1);
mRegistrationTimeout = 0;
Get<TimeTicker>().UnregisterReceiver(TimeTicker::kBbrLocal);
IgnoreError(AddService(kDecideBasedOnState));
}
else
{
mRegistrationTimeout =
1 + Random::NonCrypto::GetUint16InRange(0, static_cast<uint16_t>(mRegistrationJitter));
Get<TimeTicker>().RegisterReceiver(TimeTicker::kBbrLocal);
}
Get<TimeTicker>().RegisterReceiver(TimeTicker::kBbrLocal);
}
else if (aConfig.mServer16 != Get<Mle::Mle>().GetRloc16())
{