diff --git a/Android.mk b/Android.mk index 4d09fcc91..a13194cd2 100644 --- a/Android.mk +++ b/Android.mk @@ -220,7 +220,7 @@ LOCAL_SRC_FILES := \ src/core/backbone_router/bbr_manager.cpp \ src/core/backbone_router/multicast_listeners_table.cpp \ src/core/backbone_router/ndproxy_table.cpp \ - src/core/border_router/infra_if_platform.cpp \ + src/core/border_router/infra_if.cpp \ src/core/border_router/router_advertisement.cpp \ src/core/border_router/routing_manager.cpp \ src/core/coap/coap.cpp \ diff --git a/src/core/BUILD.gn b/src/core/BUILD.gn index 1518546d5..8b2b2c05e 100644 --- a/src/core/BUILD.gn +++ b/src/core/BUILD.gn @@ -363,7 +363,8 @@ openthread_core_files = [ "backbone_router/multicast_listeners_table.hpp", "backbone_router/ndproxy_table.cpp", "backbone_router/ndproxy_table.hpp", - "border_router/infra_if_platform.cpp", + "border_router/infra_if.cpp", + "border_router/infra_if.hpp", "border_router/router_advertisement.cpp", "border_router/router_advertisement.hpp", "border_router/routing_manager.cpp", diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index e09f7e5f2..a9cc62329 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -86,7 +86,7 @@ set(COMMON_SOURCES backbone_router/bbr_manager.cpp backbone_router/multicast_listeners_table.cpp backbone_router/ndproxy_table.cpp - border_router/infra_if_platform.cpp + border_router/infra_if.cpp border_router/router_advertisement.cpp border_router/routing_manager.cpp coap/coap.cpp diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 850228d49..a63ab7e77 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -176,7 +176,7 @@ SOURCES_COMMON = \ backbone_router/bbr_manager.cpp \ backbone_router/multicast_listeners_table.cpp \ backbone_router/ndproxy_table.cpp \ - border_router/infra_if_platform.cpp \ + border_router/infra_if.cpp \ border_router/router_advertisement.cpp \ border_router/routing_manager.cpp \ coap/coap.cpp \ @@ -415,6 +415,7 @@ HEADERS_COMMON = \ backbone_router/bbr_manager.hpp \ backbone_router/multicast_listeners_table.hpp \ backbone_router/ndproxy_table.hpp \ + border_router/infra_if.hpp \ border_router/router_advertisement.hpp \ border_router/routing_manager.hpp \ coap/coap.hpp \ diff --git a/src/core/border_router/infra_if.cpp b/src/core/border_router/infra_if.cpp new file mode 100644 index 000000000..7fe20c942 --- /dev/null +++ b/src/core/border_router/infra_if.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2022, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file implements infrastructure network interface. + */ + +#include "infra_if.hpp" + +#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE + +#include "border_router/routing_manager.hpp" +#include "common/as_core_type.hpp" +#include "common/instance.hpp" +#include "common/locator_getters.hpp" +#include "common/logging.hpp" +#include "net/icmp6.hpp" + +namespace ot { +namespace BorderRouter { + +RegisterLogModule("InfraIf"); + +InfraIf::InfraIf(Instance &aInstance) + : InstanceLocator(aInstance) + , mInitialized(false) + , mIsRunning(false) + , mIfIndex(0) +{ +} + +Error InfraIf::Init(uint32_t aIfIndex) +{ + Error error = kErrorNone; + + VerifyOrExit(!mInitialized, error = kErrorInvalidState); + VerifyOrExit(aIfIndex > 0, error = kErrorInvalidArgs); + + mIfIndex = aIfIndex; + mInitialized = true; + + LogInfo("Init %s", ToString().AsCString()); + +exit: + return error; +} + +void InfraIf::Deinit(void) +{ + mInitialized = false; + mIsRunning = false; + mIfIndex = 0; + + LogInfo("Deinit"); +} + +bool InfraIf::HasAddress(const Ip6::Address &aAddress) +{ + OT_ASSERT(mInitialized); + + return otPlatInfraIfHasAddress(mIfIndex, &aAddress); +} + +Error InfraIf::Send(const Icmp6Packet &aPacket, const Ip6::Address &aDestination) +{ + OT_ASSERT(mInitialized); + + return otPlatInfraIfSendIcmp6Nd(mIfIndex, &aDestination, aPacket.GetBytes(), aPacket.GetLength()); +} + +void InfraIf::HandledReceived(uint32_t aIfIndex, const Ip6::Address &aSource, const Icmp6Packet &aPacket) +{ + Error error = kErrorNone; + + 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); + +exit: + if (error != kErrorNone) + { + LogDebg("Dropped ICMPv6 message: %s", ErrorToString(error)); + } +} + +Error InfraIf::HandleStateChanged(uint32_t aIfIndex, bool aIsRunning) +{ + Error error = kErrorNone; + + VerifyOrExit(mInitialized, error = kErrorInvalidState); + VerifyOrExit(aIfIndex == mIfIndex, error = kErrorInvalidArgs); + + VerifyOrExit(aIsRunning != mIsRunning); + LogInfo("State changed: %sRUNNING -> %sRUNNING", mIsRunning ? "" : "NOT ", aIsRunning ? "" : "NOT "); + + mIsRunning = aIsRunning; + + Get().HandleInfraIfStateChanged(); + +exit: + return error; +} + +InfraIf::InfoString InfraIf::ToString(void) const +{ + InfoString string; + + string.Append("infra netif %u", mIfIndex); + return string; +} + +//--------------------------------------------------------------------------------------------------------------------- + +extern "C" void otPlatInfraIfRecvIcmp6Nd(otInstance * aInstance, + uint32_t aInfraIfIndex, + const otIp6Address *aSrcAddress, + const uint8_t * aBuffer, + uint16_t aBufferLength) +{ + InfraIf::Icmp6Packet packet; + + packet.Init(aBuffer, aBufferLength); + AsCoreType(aInstance).Get().HandledReceived(aInfraIfIndex, AsCoreType(aSrcAddress), packet); +} + +extern "C" otError otPlatInfraIfStateChanged(otInstance *aInstance, uint32_t aInfraIfIndex, bool aIsRunning) +{ + return AsCoreType(aInstance).Get().HandleStateChanged(aInfraIfIndex, aIsRunning); +} + +} // namespace BorderRouter +} // namespace ot + +#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE diff --git a/src/core/border_router/infra_if.hpp b/src/core/border_router/infra_if.hpp new file mode 100644 index 000000000..b67009e81 --- /dev/null +++ b/src/core/border_router/infra_if.hpp @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2022, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file includes definitions for infrastructure network interface. + * + */ + +#ifndef INFRA_IF_HPP_ +#define INFRA_IF_HPP_ + +#include "openthread-core-config.h" + +#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE + +#include + +#include "common/data.hpp" +#include "common/error.hpp" +#include "common/locator.hpp" +#include "common/string.hpp" +#include "net/ip6.hpp" + +namespace ot { +namespace BorderRouter { + +/** + * This class represents the infrastructure network interface on a border router. + * + */ +class InfraIf : public InstanceLocator +{ +public: + static constexpr uint16_t kInfoStringSize = 20; ///< Max chars for the info string (`ToString()`). + + typedef String InfoString; ///< String type returned from `ToString()`. + typedef Data Icmp6Packet; ///< An IMCPv6 packet (data containing the IP payload) + + /** + * This constructor initializes the `InfraIf`. + * + * @param[in] aInstance A OpenThread instance. + * + */ + explicit InfraIf(Instance &aInstance); + + /** + * This method initializes the `InfraIf`. + * + * @param[in] aIfIndex The infrastructure interface index. + * + * @retval kErrorNone Successfully initialized the `InfraIf`. + * @retval kErrorInvalidArgs The index of the infra interface is not valid. + * @retval kErrorInvalidState The `InfraIf` is already initialized. + * + */ + Error Init(uint32_t aIfIndex); + + /** + * This method deinitilaizes the `InfraIf`. + * + */ + void Deinit(void); + + /** + * This method indicates whether or not the `InfraIf` is initialized. + * + * @retval TRUE The `InfraIf` is initialized. + * @retval FALSE The `InfraIf` is not initialized. + * + */ + bool IsInitialized(void) const { return mInitialized; } + + /** + * This method indicates whether or not the infra interface is running. + * + * @retval TRUE The infrastructure interface is running. + * @retval FALSE The infrastructure interface is not running. + * + */ + bool IsRunning(void) const { return mIsRunning; } + + /** + * This method returns the infrastructure interface index. + * + * @returns The interface index or zero if not initialized. + * + */ + uint32_t GetIfIndex(void) const { return mIfIndex; } + + /** + * This method indicates whether or not the infra interface has the given IPv6 address assigned. + * + * This method MUST be used when interface is initialized. + * + * @param[in] aAddress The IPv6 address. + * + * @retval TRUE The infrastructure interface has @p aAddress. + * @retval FALSE The infrastructure interface does not have @p aAddress. + * + */ + bool HasAddress(const Ip6::Address &aAddress); + + /** + * This method sends an ICMPv6 Neighbor Discovery packet on the infrastructure interface. + * + * This method MUST be used when interface is initialized. + * + * @param[in] aPacket The ICMPv6 packet to send. + * @param[in] aDestination The destination address. + * + * @retval kErrorNone Successfully sent the ICMPv6 message. + * @retval kErrorFailed Failed to send the ICMPv6 message. + * + */ + Error Send(const Icmp6Packet &aPacket, const Ip6::Address &aDestination); + + /** + * This method processes a received ICMPv6 Neighbor Discovery packet from an infrastructure interface. + * + * @param[in] aIfIndex The infrastructure interface index on which the ICMPv6 message is received. + * @param[in] aSource The IPv6 source address. + * @param[in] aPacket The ICMPv6 packet. + * + */ + void HandledReceived(uint32_t aIfIndex, const Ip6::Address &aSource, const Icmp6Packet &aPacket); + + /** + * This method handles infrastructure interface state changes. + * + * @param[in] aIfIndex The infrastructure interface index. + * @param[in] aIsRunning A boolean that indicates whether the infrastructure interface is running. + * + * @retval kErrorNone Successfully updated the infra interface status. + * @retval kErrorInvalidState The `InfraIf` is not initialized. + * @retval kErrorInvalidArgs The @p IfIndex does not match the interface index of `InfraIf`. + * + */ + Error HandleStateChanged(uint32_t aIfIndex, bool aIsRunning); + + /** + * This method converts the `InfraIf` to a human-readable string. + * + * @returns The string representation of `InfraIf`. + * + */ + InfoString ToString(void) const; + +private: + bool mInitialized : 1; + bool mIsRunning : 1; + uint32_t mIfIndex; +}; + +} // namespace BorderRouter +} // namespace ot + +#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE + +#endif // INFRA_IF_HPP_ diff --git a/src/core/border_router/infra_if_platform.cpp b/src/core/border_router/infra_if_platform.cpp deleted file mode 100644 index 33e0c4c7b..000000000 --- a/src/core/border_router/infra_if_platform.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2020, The OpenThread Authors. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @file - * This file implements infrastructure interface platform APIs. - */ - -#include "openthread-core-config.h" - -#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE - -#include - -#include "border_router/routing_manager.hpp" -#include "common/as_core_type.hpp" -#include "common/instance.hpp" - -using namespace ot; - -extern "C" void otPlatInfraIfRecvIcmp6Nd(otInstance * aInstance, - uint32_t aInfraIfIndex, - const otIp6Address *aSrcAddress, - const uint8_t * aBuffer, - uint16_t aBufferLength) -{ - AsCoreType(aInstance).Get().RecvIcmp6Message(aInfraIfIndex, AsCoreType(aSrcAddress), - aBuffer, aBufferLength); -} - -extern "C" otError otPlatInfraIfStateChanged(otInstance *aInstance, uint32_t aInfraIfIndex, bool aIsRunning) -{ - return AsCoreType(aInstance).Get().HandleInfraIfStateChanged(aInfraIfIndex, - aIsRunning); -} - -#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE diff --git a/src/core/border_router/routing_manager.cpp b/src/core/border_router/routing_manager.cpp index 01bbee4f8..509ea838f 100644 --- a/src/core/border_router/routing_manager.cpp +++ b/src/core/border_router/routing_manager.cpp @@ -63,8 +63,7 @@ RoutingManager::RoutingManager(Instance &aInstance) : InstanceLocator(aInstance) , mIsRunning(false) , mIsEnabled(false) - , mInfraIfIsRunning(false) - , mInfraIfIndex(0) + , mInfraIf(aInstance) , mIsAdvertisingLocalOnLinkPrefix(false) , mOnLinkPrefixDeprecateTimer(aInstance, HandleOnLinkPrefixDeprecateTimer) , mIsAdvertisingLocalNat64Prefix(false) @@ -94,8 +93,7 @@ Error RoutingManager::Init(uint32_t aInfraIfIndex, bool aInfraIfIsRunning) { Error error; - VerifyOrExit(!IsInitialized(), error = kErrorInvalidState); - VerifyOrExit(aInfraIfIndex > 0, error = kErrorInvalidArgs); + SuccessOrExit(error = mInfraIf.Init(aInfraIfIndex)); SuccessOrExit(error = LoadOrGenerateRandomBrUlaPrefix()); GenerateOmrPrefix(); @@ -104,16 +102,14 @@ Error RoutingManager::Init(uint32_t aInfraIfIndex, bool aInfraIfIsRunning) #endif GenerateOnLinkPrefix(); - mInfraIfIndex = aInfraIfIndex; - - // Initialize the infra interface status. - SuccessOrExit(error = HandleInfraIfStateChanged(mInfraIfIndex, aInfraIfIsRunning)); + error = mInfraIf.HandleStateChanged(mInfraIf.GetIfIndex(), aInfraIfIsRunning); exit: if (error != kErrorNone) { - mInfraIfIndex = 0; + mInfraIf.Deinit(); } + return error; } @@ -239,7 +235,7 @@ void RoutingManager::GenerateOnLinkPrefix(void) void RoutingManager::EvaluateState(void) { - if (mIsEnabled && Get().IsAttached() && mInfraIfIsRunning) + if (mIsEnabled && Get().IsAttached() && mInfraIf.IsRunning()) { Start(); } @@ -312,55 +308,28 @@ exit: return; } -void RoutingManager::RecvIcmp6Message(uint32_t aInfraIfIndex, - const Ip6::Address &aSrcAddress, - const uint8_t * aBuffer, - uint16_t aBufferLength) +void RoutingManager::HandleReceived(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress) { - Error error = kErrorNone; const Ip6::Icmp::Header *icmp6Header; - VerifyOrExit(IsInitialized() && mIsRunning, error = kErrorDrop); - VerifyOrExit(aInfraIfIndex == mInfraIfIndex, error = kErrorDrop); - VerifyOrExit(aBuffer != nullptr && aBufferLength >= sizeof(Ip6::Icmp::Header), error = kErrorParse); + VerifyOrExit(mIsRunning); - icmp6Header = reinterpret_cast(aBuffer); + icmp6Header = reinterpret_cast(aPacket.GetBytes()); switch (icmp6Header->GetType()) { case Ip6::Icmp::Header::kTypeRouterAdvert: - HandleRouterAdvertisement(aSrcAddress, aBuffer, aBufferLength); + HandleRouterAdvertisement(aPacket, aSrcAddress); break; case Ip6::Icmp::Header::kTypeRouterSolicit: - HandleRouterSolicit(aSrcAddress, aBuffer, aBufferLength); + HandleRouterSolicit(aPacket, aSrcAddress); break; default: break; } exit: - if (error != kErrorNone) - { - LogDebg("Dropped ICMPv6 message: %s", ErrorToString(error)); - } -} - -Error RoutingManager::HandleInfraIfStateChanged(uint32_t aInfraIfIndex, bool aIsRunning) -{ - Error error = kErrorNone; - - VerifyOrExit(IsInitialized(), error = kErrorInvalidState); - VerifyOrExit(aInfraIfIndex == mInfraIfIndex, error = kErrorInvalidArgs); - VerifyOrExit(aIsRunning != mInfraIfIsRunning); - - LogInfo("Infra interface (%u) state changed: %sRUNNING -> %sRUNNING", aInfraIfIndex, - (mInfraIfIsRunning ? "" : "NOT "), (aIsRunning ? "" : "NOT ")); - - mInfraIfIsRunning = aIsRunning; - EvaluateState(); - -exit: - return error; + return; } void RoutingManager::HandleNotifierEvents(Events aEvents) @@ -630,8 +599,8 @@ const Ip6::Prefix *RoutingManager::EvaluateOnLinkPrefix(void) } else { - LogInfo("EvaluateOnLinkPrefix: There is already smaller on-link prefix %s on interface %u", - smallestOnLinkPrefix->ToString().AsCString(), mInfraIfIndex); + LogInfo("EvaluateOnLinkPrefix: There is already smaller on-link prefix %s on %s", + smallestOnLinkPrefix->ToString().AsCString(), mInfraIf.ToString().AsCString()); DeprecateOnLinkPrefix(); } } @@ -815,12 +784,14 @@ Error RoutingManager::SendRouterSolicitation(void) { Ip6::Address destAddress; RouterAdv::RouterSolicitMessage routerSolicit; + InfraIf::Icmp6Packet packet; OT_ASSERT(IsInitialized()); + packet.InitFrom(routerSolicit); destAddress.SetToLinkLocalAllRoutersMulticast(); - return otPlatInfraIfSendIcmp6Nd(mInfraIfIndex, &destAddress, reinterpret_cast(&routerSolicit), - sizeof(routerSolicit)); + + return mInfraIf.Send(packet, destAddress); } // This method sends Router Advertisement messages to advertise on-link prefix and route for OMR prefix. @@ -857,8 +828,8 @@ void RoutingManager::SendRouterAdvertisement(const OmrPrefixArray &aNewOmrPrefix if (!mIsAdvertisingLocalOnLinkPrefix) { - LogInfo("Start advertising new on-link prefix %s on interface %u", aNewOnLinkPrefix->ToString().AsCString(), - mInfraIfIndex); + LogInfo("Start advertising new on-link prefix %s on %s", aNewOnLinkPrefix->ToString().AsCString(), + mInfraIf.ToString().AsCString()); } LogInfo("Send on-link prefix %s in PIO (preferred lifetime = %u seconds, valid lifetime = %u seconds)", @@ -909,8 +880,8 @@ void RoutingManager::SendRouterAdvertisement(const OmrPrefixArray &aNewOmrPrefix bufferLength += rio->GetSize(); - LogInfo("Stop advertising OMR prefix %s on interface %u", advertisedOmrPrefix.ToString().AsCString(), - mInfraIfIndex); + LogInfo("Stop advertising OMR prefix %s on %s", advertisedOmrPrefix.ToString().AsCString(), + mInfraIf.ToString().AsCString()); } } @@ -936,23 +907,27 @@ void RoutingManager::SendRouterAdvertisement(const OmrPrefixArray &aNewOmrPrefix // Send the message only when there are options. if (bufferLength > sizeof(mRouterAdvMessage)) { - Error error; - Ip6::Address destAddress; + Error error; + Ip6::Address destAddress; + InfraIf::Icmp6Packet packet; ++mRouterAdvertisementCount; + packet.Init(buffer, bufferLength); destAddress.SetToLinkLocalAllNodesMulticast(); - error = otPlatInfraIfSendIcmp6Nd(mInfraIfIndex, &destAddress, buffer, bufferLength); + + error = mInfraIf.Send(packet, destAddress); if (error == kErrorNone) { mLastRouterAdvertisementSendTime = TimerMilli::GetNow(); - LogInfo("Sent Router Advertisement on interface %u", mInfraIfIndex); + LogInfo("Sent Router Advertisement on %s", mInfraIf.ToString().AsCString()); DumpDebg("[BR-CERT] direction=send | type=RA |", buffer, bufferLength); } else { - LogWarn("Failed to send Router Advertisement on interface %u: %s", mInfraIfIndex, ErrorToString(error)); + LogWarn("Failed to send Router Advertisement on %s: %s", mInfraIf.ToString().AsCString(), + ErrorToString(error)); } } } @@ -1108,15 +1083,13 @@ void RoutingManager::HandleRoutingPolicyTimer(Timer &aTimer) aTimer.Get().EvaluateRoutingPolicy(); } -void RoutingManager::HandleRouterSolicit(const Ip6::Address &aSrcAddress, - const uint8_t * aBuffer, - uint16_t aBufferLength) +void RoutingManager::HandleRouterSolicit(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress) { + OT_UNUSED_VARIABLE(aPacket); OT_UNUSED_VARIABLE(aSrcAddress); - OT_UNUSED_VARIABLE(aBuffer); - OT_UNUSED_VARIABLE(aBufferLength); - LogInfo("Received Router Solicitation from %s on interface %u", aSrcAddress.ToString().AsCString(), mInfraIfIndex); + LogInfo("Received Router Solicitation from %s on %s", aSrcAddress.ToString().AsCString(), + mInfraIf.ToString().AsCString()); #if OPENTHREAD_CONFIG_BORDER_ROUTING_VICARIOUS_RS_ENABLE if (!mVicariousRouterSolicitTimer.IsRunning()) @@ -1146,9 +1119,7 @@ uint32_t RoutingManager::ExternalPrefix::GetPrefixExpireDelay(uint32_t aValidLif return delay; } -void RoutingManager::HandleRouterAdvertisement(const Ip6::Address &aSrcAddress, - const uint8_t * aBuffer, - uint16_t aBufferLength) +void RoutingManager::HandleRouterAdvertisement(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress) { OT_ASSERT(mIsRunning); OT_UNUSED_VARIABLE(aSrcAddress); @@ -1164,14 +1135,15 @@ void RoutingManager::HandleRouterAdvertisement(const Ip6::Address &aSrcAddress, const Option * option; const RouterAdvMessage *routerAdvMessage; - VerifyOrExit(aBufferLength >= sizeof(RouterAdvMessage)); + VerifyOrExit(aPacket.GetLength() >= sizeof(RouterAdvMessage)); - LogInfo("Received Router Advertisement from %s on interface %u", aSrcAddress.ToString().AsCString(), mInfraIfIndex); - DumpDebg("[BR-CERT] direction=recv | type=RA |", aBuffer, aBufferLength); + LogInfo("Received Router Advertisement from %s on %s", aSrcAddress.ToString().AsCString(), + mInfraIf.ToString().AsCString()); + DumpDebg("[BR-CERT] direction=recv | type=RA |", aPacket.GetBytes(), aPacket.GetLength()); - routerAdvMessage = reinterpret_cast(aBuffer); - optionsBegin = aBuffer + sizeof(RouterAdvMessage); - optionsLength = aBufferLength - sizeof(RouterAdvMessage); + routerAdvMessage = reinterpret_cast(aPacket.GetBytes()); + optionsBegin = aPacket.GetBytes() + sizeof(RouterAdvMessage); + optionsLength = aPacket.GetLength() - sizeof(RouterAdvMessage); option = nullptr; while ((option = Option::GetNextOption(option, optionsBegin, optionsLength)) != nullptr) @@ -1207,7 +1179,7 @@ void RoutingManager::HandleRouterAdvertisement(const Ip6::Address &aSrcAddress, // Remember the header and parameters of RA messages which are // initiated from the infra interface. - if (otPlatInfraIfHasAddress(mInfraIfIndex, &aSrcAddress)) + if (mInfraIf.HasAddress(aSrcAddress)) { needReevaluate |= UpdateRouterAdvMessage(routerAdvMessage); } @@ -1241,8 +1213,8 @@ bool RoutingManager::UpdateDiscoveredOnLinkPrefix(const RouterAdv::PrefixInfoOpt VerifyOrExit(!mIsAdvertisingLocalOnLinkPrefix || prefix != mLocalOnLinkPrefix); - LogInfo("Discovered on-link prefix (%s, %u seconds) from interface %u", prefix.ToString().AsCString(), - aPio.GetValidLifetime(), mInfraIfIndex); + LogInfo("Discovered on-link prefix (%s, %u seconds) from %s", prefix.ToString().AsCString(), + aPio.GetValidLifetime(), mInfraIf.ToString().AsCString()); onLinkPrefix.mIsOnLinkPrefix = true; onLinkPrefix.mPrefix = prefix; @@ -1349,8 +1321,8 @@ void RoutingManager::UpdateDiscoveredOmrPrefix(const RouterAdv::RouteInfoOption VerifyOrExit(!mAdvertisedOmrPrefixes.Contains(prefix)); VerifyOrExit(!NetworkDataContainsOmrPrefix(prefix)); - LogInfo("Discovered OMR prefix (%s, %u seconds) from interface %u", prefix.ToString().AsCString(), - aRio.GetRouteLifetime(), mInfraIfIndex); + LogInfo("Discovered OMR prefix (%s, %u seconds) from %s", prefix.ToString().AsCString(), aRio.GetRouteLifetime(), + mInfraIf.ToString().AsCString()); if (aRio.GetRouteLifetime() == 0) { diff --git a/src/core/border_router/routing_manager.hpp b/src/core/border_router/routing_manager.hpp index d447d4f3c..02c68de5c 100644 --- a/src/core/border_router/routing_manager.hpp +++ b/src/core/border_router/routing_manager.hpp @@ -48,8 +48,8 @@ #endif #include -#include +#include "border_router/infra_if.hpp" #include "border_router/router_advertisement.hpp" #include "common/array.hpp" #include "common/error.hpp" @@ -73,6 +73,7 @@ namespace BorderRouter { class RoutingManager : public InstanceLocator { friend class ot::Notifier; + friend class ot::Instance; public: /** @@ -155,35 +156,21 @@ public: #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE /** - * This method receives an ICMPv6 message on the infrastructure interface. + * This method processes a received ICMPv6 message from the infrastructure interface. * * Malformed or undesired messages are dropped silently. * - * @param[in] aInfraIfIndex The infrastructure interface index. + * @param[in] aPacket The received ICMPv6 packet. * @param[in] aSrcAddress The source address this message is sent from. - * @param[in] aBuffer THe ICMPv6 message buffer. - * @param[in] aLength The length of the ICMPv6 message buffer. * */ - void RecvIcmp6Message(uint32_t aInfraIfIndex, - const Ip6::Address &aSrcAddress, - const uint8_t * aBuffer, - uint16_t aBufferLength); + void HandleReceived(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress); /** * This method handles infrastructure interface state changes. * - * @param[in] aInfraIfIndex The index of the infrastructure interface. - * @param[in] aIsRunning A boolean that indicates whether the infrastructure - * interface is running. - * - * @retval kErrorNone Successfully updated the infra interface status. - * @retval kErrorInvalidState The Routing Manager is not initialized. - * @retval kErrorInvalidArgs The @p aInfraIfIndex doesn't match the infra interface - * the Routing Manager is initialized with. - * */ - Error HandleInfraIfStateChanged(uint32_t aInfraIfIndex, bool aIsRunning); + void HandleInfraIfStateChanged(void) { EvaluateState(); } /** * This method checks if the on-mesh prefix configuration is a valid OMR prefix. @@ -313,7 +300,7 @@ private: void Start(void); void Stop(void); void HandleNotifierEvents(Events aEvents); - bool IsInitialized(void) const { return mInfraIfIndex != 0; } + bool IsInitialized(void) const { return mInfraIf.IsInitialized(); } bool IsEnabled(void) const { return mIsEnabled; } Error LoadOrGenerateRandomBrUlaPrefix(void); void GenerateOmrPrefix(void); @@ -355,8 +342,8 @@ private: static void HandleOnLinkPrefixDeprecateTimer(Timer &aTimer); void DeprecateOnLinkPrefix(void); - void HandleRouterSolicit(const Ip6::Address &aSrcAddress, const uint8_t *aBuffer, uint16_t aBufferLength); - void HandleRouterAdvertisement(const Ip6::Address &aSrcAddress, const uint8_t *aBuffer, uint16_t aBufferLength); + void HandleRouterSolicit(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress); + void HandleRouterAdvertisement(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress); bool UpdateDiscoveredOnLinkPrefix(const RouterAdv::PrefixInfoOption &aPio); void UpdateDiscoveredOmrPrefix(const RouterAdv::RouteInfoOption &aRio); void InvalidateDiscoveredPrefixes(const Ip6::Prefix *aPrefix = nullptr, bool aIsOnLinkPrefix = true); @@ -376,13 +363,7 @@ private: // Manager will be stopped if we are disabled. bool mIsEnabled; - // Indicates whether the infra interface is running. The Routing - // Manager will be stopped when the Infra interface is not running. - bool mInfraIfIsRunning; - - // The index of the infra interface on which Router Advertisement - // messages will be sent. - uint32_t mInfraIfIndex; + InfraIf mInfraIf; // The /48 BR ULA prefix loaded from local persistent storage or // randomly generated if none is found in persistent storage. diff --git a/src/core/common/instance.hpp b/src/core/common/instance.hpp index caba4dd37..ff0e37243 100644 --- a/src/core/common/instance.hpp +++ b/src/core/common/instance.hpp @@ -972,6 +972,11 @@ template <> inline BorderRouter::RoutingManager &Instance::Get(void) { return mRoutingManager; } + +template <> inline BorderRouter::InfraIf &Instance::Get(void) +{ + return mRoutingManager.mInfraIf; +} #endif #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE