diff --git a/src/core/border_router/routing_manager.cpp b/src/core/border_router/routing_manager.cpp index f4684ac46..85ba1e804 100644 --- a/src/core/border_router/routing_manager.cpp +++ b/src/core/border_router/routing_manager.cpp @@ -852,19 +852,25 @@ void RoutingManager::HandleRouterSolicitTimer(void) Error error; error = SendRouterSolicitation(); - ++mRouterSolicitCount; if (error == kErrorNone) { otLogDebgBr("Successfully sent %uth Router Solicitation", mRouterSolicitCount); + ++mRouterSolicitCount; + nextSolicitationDelay = + (mRouterSolicitCount == kMaxRtrSolicitations) ? kMaxRtrSolicitationDelay : kRtrSolicitationInterval; } else { otLogCritBr("Failed to send %uth Router Solicitation: %s", mRouterSolicitCount, ErrorToString(error)); - } - nextSolicitationDelay = - (mRouterSolicitCount == kMaxRtrSolicitations) ? kMaxRtrSolicitationDelay : kRtrSolicitationInterval; + // It's unexpected that RS will fail and we will retry sending RS messages in 60 seconds. + // Notice that `mRouterSolicitCount` is not incremented for failed RS and thus we will + // not start configuring on-link prefixes before `kMaxRtrSolicitations` successful RS + // messages have been sent. + nextSolicitationDelay = kRtrSolicitationRetryDelay; + mRouterSolicitCount = 0; + } otLogDebgBr("Router solicitation timer scheduled in %u seconds", nextSolicitationDelay); mRouterSolicitTimer.Start(Time::SecToMsec(nextSolicitationDelay)); diff --git a/src/core/border_router/routing_manager.hpp b/src/core/border_router/routing_manager.hpp index 0deee14f4..4d26d2628 100644 --- a/src/core/border_router/routing_manager.hpp +++ b/src/core/border_router/routing_manager.hpp @@ -198,6 +198,7 @@ private: 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 kMaxRoutingPolicyDelay = 1; // Max delay for routing policy evaluation. In sec. + static constexpr uint32_t kRtrSolicitationRetryDelay = 60; // The delay before retrying failed RS tx. In Sec. // 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 diff --git a/tests/scripts/thread-cert/border_router/test_single_border_router.py b/tests/scripts/thread-cert/border_router/test_single_border_router.py index 51afe1b0a..756786c70 100755 --- a/tests/scripts/thread-cert/border_router/test_single_border_router.py +++ b/tests/scripts/thread-cert/border_router/test_single_border_router.py @@ -267,8 +267,9 @@ class SingleBorderRouter(thread_cert.TestCase): br.enable_ether() - # It takes around 10 seconds to start sending RA messages. - self.simulator.go(15) + # The routing manager may fail to send RS and will wait for 60 seconds + # before retrying. + self.simulator.go(80) self.collect_ipaddrs() logging.info("BR addrs: %r", br.get_addrs())