From 217727ec62850f72be2d04dfaa0a3e781f901889 Mon Sep 17 00:00:00 2001 From: kangping Date: Fri, 7 May 2021 01:08:07 +0800 Subject: [PATCH] [border-router] send RA immediately when RA parameters are updated (#6565) --- .../border_router/router_advertisement.cpp | 6 ++++ .../border_router/router_advertisement.hpp | 24 ++++++++++++++ src/core/border_router/routing_manager.cpp | 32 +++++++++++++------ src/core/border_router/routing_manager.hpp | 1 + .../border_router/test_radvd_coexist.py | 2 +- 5 files changed, 54 insertions(+), 11 deletions(-) diff --git a/src/core/border_router/router_advertisement.cpp b/src/core/border_router/router_advertisement.cpp index d727ce9a6..ce05f3785 100644 --- a/src/core/border_router/router_advertisement.cpp +++ b/src/core/border_router/router_advertisement.cpp @@ -208,6 +208,12 @@ const RouterAdvMessage &RouterAdvMessage::operator=(const RouterAdvMessage &aOth return *this; } +bool RouterAdvMessage::operator==(const RouterAdvMessage &aOther) const +{ + return memcmp(&mHeader.mData, &aOther.mHeader.mData, sizeof(mHeader.mData)) == 0 && + mReachableTime == aOther.mReachableTime && mRetransTimer == aOther.mRetransTimer; +} + RouterSolicitMessage::RouterSolicitMessage(void) { mHeader.Clear(); diff --git a/src/core/border_router/router_advertisement.hpp b/src/core/border_router/router_advertisement.hpp index 11335f10a..970af89ea 100644 --- a/src/core/border_router/router_advertisement.hpp +++ b/src/core/border_router/router_advertisement.hpp @@ -447,6 +447,30 @@ public: */ const RouterAdvMessage &operator=(const RouterAdvMessage &aOther); + /** + * This method overloads operator `==` to evaluate whether or not + * two instances of `RouterAdvMessage` are equal. + * + * @param[in] aOther The other `RouterAdvMessage` instance to compare with. + * + * @retval TRUE If the two `RouterAdvMessage` instances are equal. + * @retval FALSE If the two `RouterAdvMessage` instances are not equal. + * + */ + bool operator==(const RouterAdvMessage &aOther) const; + + /** + * This method overloads operator `!=` to evaluate whether or not + * two instances of `RouterAdvMessage` are equal. + * + * @param[in] aOther The other `RouterAdvMessage` instance to compare with. + * + * @retval TRUE If the two `RouterAdvMessage` instances are not equal. + * @retval FALSE If the two `RouterAdvMessage` instances are equal. + * + */ + bool operator!=(const RouterAdvMessage &aOther) const { return !(*this == aOther); } + private: enum : uint8_t { diff --git a/src/core/border_router/routing_manager.cpp b/src/core/border_router/routing_manager.cpp index 1e8765a91..2aab96726 100644 --- a/src/core/border_router/routing_manager.cpp +++ b/src/core/border_router/routing_manager.cpp @@ -959,16 +959,7 @@ void RoutingManager::HandleRouterAdvertisement(const Ip6::Address &aSrcAddress, // initiated from the infra interface. if (otPlatInfraIfHasAddress(mInfraIfIndex, &aSrcAddress)) { - if (routerAdvMessage->GetRouterLifetime() == 0) - { - mRouterAdvMessage.SetToDefault(); - } - else - { - mRouterAdvMessage = *routerAdvMessage; - // TODO: add a timer for invalidating the learned RA parameters - // for cases that the other RA daemon crashed or is force killed. - } + needReevaluate |= UpdateRouterAdvMessage(*routerAdvMessage); } if (needReevaluate) @@ -1198,6 +1189,27 @@ bool RoutingManager::NetworkDataContainsOmrPrefix(const Ip6::Prefix &aPrefix) co return contain; } +// Update the `mRouterAdvMessage` with given Router Advertisement message. +// Returns a boolean which indicates whether there are changes of `mRouterAdvMessage`. +bool RoutingManager::UpdateRouterAdvMessage(const RouterAdv::RouterAdvMessage &aRouterAdvMessage) +{ + RouterAdv::RouterAdvMessage oldRouterAdvMessage; + + oldRouterAdvMessage = mRouterAdvMessage; + if (aRouterAdvMessage.GetRouterLifetime() == 0) + { + mRouterAdvMessage.SetToDefault(); + } + else + { + mRouterAdvMessage = aRouterAdvMessage; + // TODO: add a timer for invalidating the learned RA parameters + // for cases that the other RA daemon crashed or is force killed. + } + + return (mRouterAdvMessage != oldRouterAdvMessage); +} + } // namespace BorderRouter } // namespace ot diff --git a/src/core/border_router/routing_manager.hpp b/src/core/border_router/routing_manager.hpp index e70ed3400..33307520e 100644 --- a/src/core/border_router/routing_manager.hpp +++ b/src/core/border_router/routing_manager.hpp @@ -232,6 +232,7 @@ private: uint32_t aLifetime, otRoutePreference aRoutePreference = OT_ROUTE_PREFERENCE_MED); bool NetworkDataContainsOmrPrefix(const Ip6::Prefix &aPrefix) const; + bool UpdateRouterAdvMessage(const RouterAdv::RouterAdvMessage &aRouterAdvMessage); static bool IsValidOmrPrefix(const NetworkData::OnMeshPrefixConfig &aOnMeshPrefixConfig); static bool IsValidOmrPrefix(const Ip6::Prefix &aOmrPrefix); diff --git a/tests/scripts/thread-cert/border_router/test_radvd_coexist.py b/tests/scripts/thread-cert/border_router/test_radvd_coexist.py index 3cf391dab..053c0785d 100755 --- a/tests/scripts/thread-cert/border_router/test_radvd_coexist.py +++ b/tests/scripts/thread-cert/border_router/test_radvd_coexist.py @@ -114,7 +114,7 @@ class SingleBorderRouter(thread_cert.TestCase): self.assertTrue(host.ping(router.get_ip6_address(config.ADDRESS_TYPE.OMR)[0], backbone=True)) # Stop the radvd service and wait for the Border Router - # to start adverting on-link prefix on its own. + # to reset the RA parameters. br.stop_radvd_service() self.simulator.go(15)