diff --git a/src/core/border_router/infra_if.cpp b/src/core/border_router/infra_if.cpp index e5edcc3a0..eae389b08 100644 --- a/src/core/border_router/infra_if.cpp +++ b/src/core/border_router/infra_if.cpp @@ -107,14 +107,30 @@ Error InfraIf::Send(const Icmp6Packet &aPacket, const Ip6::Address &aDestination void InfraIf::HandledReceived(uint32_t aIfIndex, const Ip6::Address &aSource, const Icmp6Packet &aPacket) { - Error error = kErrorNone; + Error error = kErrorNone; + const Ip6::Icmp::Header *icmp6Header; VerifyOrExit(mInitialized && mIsRunning, error = kErrorInvalidState); VerifyOrExit(aIfIndex == mIfIndex, error = kErrorDrop); VerifyOrExit(aPacket.GetBytes() != nullptr, error = kErrorInvalidArgs); VerifyOrExit(aPacket.GetLength() >= sizeof(Ip6::Icmp::Header), error = kErrorParse); - Get().HandleReceived(aPacket, aSource); + icmp6Header = reinterpret_cast(aPacket.GetBytes()); + + switch (icmp6Header->GetType()) + { + case Ip6::Icmp::Header::kTypeRouterAdvert: + Get().HandleRouterAdvertisement(aPacket, aSource); + break; + case Ip6::Icmp::Header::kTypeNeighborAdvert: + Get().HandleNeighborAdvertisement(aPacket); + break; + case Ip6::Icmp::Header::kTypeRouterSolicit: + Get().HandleRouterSolicit(aPacket, aSource); + break; + default: + break; + } exit: if (error != kErrorNone) diff --git a/src/core/border_router/routing_manager.cpp b/src/core/border_router/routing_manager.cpp index 5be18e5fc..ae5ba8afa 100644 --- a/src/core/border_router/routing_manager.cpp +++ b/src/core/border_router/routing_manager.cpp @@ -348,33 +348,6 @@ exit: } #endif -void RoutingManager::HandleReceived(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress) -{ - const Ip6::Icmp::Header *icmp6Header; - - VerifyOrExit(mIsRunning); - - icmp6Header = reinterpret_cast(aPacket.GetBytes()); - - switch (icmp6Header->GetType()) - { - case Ip6::Icmp::Header::kTypeRouterAdvert: - HandleRouterAdvertisement(aPacket, aSrcAddress); - break; - case Ip6::Icmp::Header::kTypeRouterSolicit: - HandleRouterSolicit(aPacket, aSrcAddress); - break; - case Ip6::Icmp::Header::kTypeNeighborAdvert: - HandleNeighborAdvertisement(aPacket); - break; - default: - break; - } - -exit: - return; -} - void RoutingManager::HandleNotifierEvents(Events aEvents) { if (aEvents.Contains(kEventThreadRoleChanged)) @@ -608,48 +581,12 @@ void RoutingManager::HandleRouterSolicit(const InfraIf::Icmp6Packet &aPacket, co OT_UNUSED_VARIABLE(aPacket); OT_UNUSED_VARIABLE(aSrcAddress); + VerifyOrExit(mIsRunning); + Get().GetBorderRoutingCounters().mRsRx++; LogInfo("Received RS from %s on %s", aSrcAddress.ToString().AsCString(), Get().ToString().AsCString()); ScheduleRoutingPolicyEvaluation(kToReplyToRs); -} - -void RoutingManager::HandleNeighborAdvertisement(const InfraIf::Icmp6Packet &aPacket) -{ - const NeighborAdvertMessage *naMsg; - - VerifyOrExit(aPacket.GetLength() >= sizeof(NeighborAdvertMessage)); - naMsg = reinterpret_cast(aPacket.GetBytes()); - - Get().ProcessNeighborAdvertMessage(*naMsg); - -exit: - return; -} - -void RoutingManager::HandleRouterAdvertisement(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress) -{ - RouterAdvert::RxMessage raMsg(aPacket); - RxRaTracker::RouterAdvOrigin raOrigin = RxRaTracker::kAnotherRouter; - - OT_ASSERT(mIsRunning); - - VerifyOrExit(raMsg.IsValid()); - - Get().GetBorderRoutingCounters().mRaRx++; - - if (Get().HasAddress(aSrcAddress)) - { - raOrigin = - mTxRaInfo.IsRaFromManager(raMsg) ? RxRaTracker::kThisBrRoutingManager : RxRaTracker::kThisBrOtherEntity; - } - - LogInfo("Received RA from %s on %s %s", aSrcAddress.ToString().AsCString(), Get().ToString().AsCString(), - RouterAdvOriginToString(raOrigin)); - - DumpDebg("[BR-CERT] direction=recv | type=RA |", aPacket.GetBytes(), aPacket.GetLength()); - - Get().ProcessRouterAdvertMessage(raMsg, aSrcAddress, raOrigin); exit: return; @@ -767,29 +704,6 @@ exit: #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_REACHABILITY_CHECK_ICMP6_ERROR_ENABLE -#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) - -const char *RoutingManager::RouterAdvOriginToString(RxRaTracker::RouterAdvOrigin aRaOrigin) -{ - static const char *const kOriginStrings[] = { - "", // (0) kAnotherRouter - "(this BR routing-manager)", // (1) kThisBrRoutingManager - "(this BR other sw entity)", // (2) kThisBrOtherEntity - }; - - struct EnumCheck - { - InitEnumValidatorCounter(); - ValidateNextEnum(RxRaTracker::kAnotherRouter); - ValidateNextEnum(RxRaTracker::kThisBrRoutingManager); - ValidateNextEnum(RxRaTracker::kThisBrOtherEntity); - }; - - return kOriginStrings[aRaOrigin]; -} - -#endif // OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) - //--------------------------------------------------------------------------------------------------------------------- // OmrPrefixManager diff --git a/src/core/border_router/routing_manager.hpp b/src/core/border_router/routing_manager.hpp index e050902ce..e70fee240 100644 --- a/src/core/border_router/routing_manager.hpp +++ b/src/core/border_router/routing_manager.hpp @@ -422,14 +422,27 @@ public: #endif // OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE /** - * Processes a received ICMPv6 message from the infrastructure interface. + * Indicates whether or not a received Router Advertisement message is generated by the `RoutingManager` itself. + * + * @param[in] aRaMessage The RA message to check. + * + * @retval TRUE The @p aRaMessage is generated by the `RoutingManager`. + * @retval FALSE The @p aRaMessage is not generated by the `RoutingManager`. + */ + bool IsRouterAdvertFromManager(const RouterAdvert::RxMessage &aRaMessage) const + { + return mTxRaInfo.IsRaFromManager(aRaMessage); + } + + /** + * Processes a received Router Solicit message from the infrastructure interface. * * Malformed or undesired messages are dropped silently. * * @param[in] aPacket The received ICMPv6 packet. * @param[in] aSrcAddress The source address this message is sent from. */ - void HandleReceived(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress); + void HandleRouterSolicit(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress); /** * Handles infrastructure interface state changes. @@ -1011,9 +1024,6 @@ private: void ScheduleRoutingPolicyEvaluation(ScheduleMode aMode); void SendRouterAdvertisement(RouterAdvTxMode aRaTxMode); - void HandleRouterAdvertisement(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress); - void HandleRouterSolicit(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress); - void HandleNeighborAdvertisement(const InfraIf::Icmp6Packet &aPacket); bool NetworkDataContainsUlaRoute(void) const; void HandleRxRaTrackerDecisionFactorChanged(void); @@ -1021,8 +1031,6 @@ private: static bool IsValidBrUlaPrefix(const Ip6::Prefix &aBrUlaPrefix); - static const char *RouterAdvOriginToString(RxRaTracker::RouterAdvOrigin aRaOrigin); - //------------------------------------------------------------------------------------------------------------------ // Variables diff --git a/src/core/border_router/rx_ra_tracker.cpp b/src/core/border_router/rx_ra_tracker.cpp index ebf2fde24..981dc226a 100644 --- a/src/core/border_router/rx_ra_tracker.cpp +++ b/src/core/border_router/rx_ra_tracker.cpp @@ -137,15 +137,31 @@ void RxRaTracker::HandleRsSenderFinished(TimeMilli aStartTime) Get().ScheduleRoutingPolicyEvaluation(RoutingManager::kImmediately); } -void RxRaTracker::ProcessRouterAdvertMessage(const RouterAdvert::RxMessage &aRaMessage, - const Ip6::Address &aSrcAddress, - RouterAdvOrigin aRaOrigin) +void RxRaTracker::HandleRouterAdvertisement(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress) { - // Process a received RA message and update the prefix table. + RouterAdvert::RxMessage raMsg(aPacket); + RouterAdvOrigin origin = kAnotherRouter; + Router *router; - Router *router; + VerifyOrExit(mIsRunning); - switch (aRaOrigin) + VerifyOrExit(raMsg.IsValid()); + + Get().GetBorderRoutingCounters().mRaRx++; + + if (Get().HasAddress(aSrcAddress)) + { + origin = Get().IsRouterAdvertFromManager(raMsg) ? kThisBrRoutingManager : kThisBrOtherEntity; + } + + LogInfo("Received RA from %s on %s %s", aSrcAddress.ToString().AsCString(), Get().ToString().AsCString(), + RouterAdvOriginToString(origin)); + + DumpDebg("[BR-CERT] direction=recv | type=RA |", aPacket.GetBytes(), aPacket.GetLength()); + + // Process the received RA message. + + switch (origin) { case kThisBrOtherEntity: case kThisBrRoutingManager: @@ -155,7 +171,7 @@ void RxRaTracker::ProcessRouterAdvertMessage(const RouterAdvert::RxMessage &aRaM break; } - VerifyOrExit(aRaOrigin != kThisBrRoutingManager); + VerifyOrExit(origin != kThisBrRoutingManager); router = mRouters.FindMatching(aSrcAddress); @@ -183,9 +199,9 @@ void RxRaTracker::ProcessRouterAdvertMessage(const RouterAdvert::RxMessage &aRaM // in a `::/0` RIO override the preference and lifetime values in // the RA header (per RFC 4191 section 3.1). - ProcessRaHeader(aRaMessage.GetHeader(), *router, aRaOrigin); + ProcessRaHeader(raMsg.GetHeader(), *router, origin); - for (const Option &option : aRaMessage) + for (const Option &option : raMsg) { switch (option.GetType()) { @@ -206,7 +222,7 @@ void RxRaTracker::ProcessRouterAdvertMessage(const RouterAdvert::RxMessage &aRaM } } - router->mIsLocalDevice = (aRaOrigin == kThisBrOtherEntity); + router->mIsLocalDevice = (origin == kThisBrOtherEntity); router->ResetReachabilityState(); @@ -880,13 +896,19 @@ void RxRaTracker::HandleSignalTask(void) { Get().HandleRxRaTrack void RxRaTracker::HandleRdnssAddrTask(void) { mRdnssCallback.InvokeIfSet(); } -void RxRaTracker::ProcessNeighborAdvertMessage(const NeighborAdvertMessage &aNaMessage) +void RxRaTracker::HandleNeighborAdvertisement(const InfraIf::Icmp6Packet &aPacket) { - Router *router; + const NeighborAdvertMessage *naMsg; + Router *router; - VerifyOrExit(aNaMessage.IsValid()); + VerifyOrExit(mIsRunning); - router = mRouters.FindMatching(aNaMessage.GetTargetAddress()); + VerifyOrExit(aPacket.GetLength() >= sizeof(NeighborAdvertMessage)); + naMsg = reinterpret_cast(aPacket.GetBytes()); + + VerifyOrExit(naMsg->IsValid()); + + router = mRouters.FindMatching(naMsg->GetTargetAddress()); VerifyOrExit(router != nullptr); LogInfo("Received NA from router %s", router->mAddress.ToString().AsCString()); @@ -1184,6 +1206,29 @@ exit: #endif // OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE +#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) + +const char *RxRaTracker::RouterAdvOriginToString(RouterAdvOrigin aRaOrigin) +{ + static const char *const kOriginStrings[] = { + "", // (0) kAnotherRouter + "(this BR routing-manager)", // (1) kThisBrRoutingManager + "(this BR other sw entity)", // (2) kThisBrOtherEntity + }; + + struct EnumCheck + { + InitEnumValidatorCounter(); + ValidateNextEnum(kAnotherRouter); + ValidateNextEnum(kThisBrRoutingManager); + ValidateNextEnum(kThisBrOtherEntity); + }; + + return kOriginStrings[aRaOrigin]; +} + +#endif // OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) + //--------------------------------------------------------------------------------------------------------------------- // RxRaTracker::Iterator diff --git a/src/core/border_router/rx_ra_tracker.hpp b/src/core/border_router/rx_ra_tracker.hpp index d42098607..1426bdcae 100644 --- a/src/core/border_router/rx_ra_tracker.hpp +++ b/src/core/border_router/rx_ra_tracker.hpp @@ -77,16 +77,6 @@ class RxRaTracker : public InstanceLocator friend class InfraIf; public: - /** - * Represents the origin of a received Router Advertisement message. - */ - enum RouterAdvOrigin : uint8_t - { - kAnotherRouter, ///< From another router on the infrastructure interface. - kThisBrRoutingManager, ///< From this Border Router, generated by `RoutingManager` itself. - kThisBrOtherEntity, ///< From this Border Router, generated by another software entity. - }; - /** * Represents an entity requesting to enable/disable the `RxRaTracker`. */ @@ -128,24 +118,6 @@ public: */ bool IsRsTxInProgress(void) const { return mRsSender.IsInProgress(); } - /** - * Processes a received Router Advertisement (RA) message. - * - * @param[in] aRaMessage The received RA message. - * @param[in] aSrcAddress The source address of the RA message. - * @param[in] aRaOrigin The origin of the RA message. - */ - void ProcessRouterAdvertMessage(const RouterAdvert::RxMessage &aRaMessage, - const Ip6::Address &aSrcAddress, - RouterAdvOrigin aRaOrigin); - - /** - * Processes a received Neighbor Advertisement (NA) message. - * - * @param[in] aNaMessage The received NA message. - */ - void ProcessNeighborAdvertMessage(const NeighborAdvertMessage &aNaMessage); - /** * Initializes a `PrefixTableIterator`. * @@ -312,6 +284,15 @@ private: //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + enum RouterAdvOrigin : uint8_t + { + kAnotherRouter, // From another router on the infrastructure interface. + kThisBrRoutingManager, // From this Border Router, generated by `RoutingManager` itself. + kThisBrOtherEntity, // From this Border Router, generated by another software entity. + }; + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + template struct Entry : public Type, public LinkedListEntry>, @@ -566,8 +547,10 @@ private: void HandleNotifierEvents(Events aEvents); void HandleNetDataChange(void); - // Callback from `InfraIf` + // Callbacks from `InfraIf` void HandleInfraIfStateChanged(void) { UpdateState(); } + void HandleRouterAdvertisement(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress); + void HandleNeighborAdvertisement(const InfraIf::Icmp6Packet &aPacket); // Tasklet or timer callbacks void HandleSignalTask(void); @@ -583,6 +566,8 @@ private: template Entry *AllocateEntry(void); #endif + static const char *RouterAdvOriginToString(RouterAdvOrigin aRaOrigin); + using SignalTask = TaskletIn; using RdnssAddrTask = TaskletIn; using ExpirationTimer = TimerMilliIn;