diff --git a/include/openthread/border_routing.h b/include/openthread/border_routing.h index 3fd95c6ad..5236f0d9d 100644 --- a/include/openthread/border_routing.h +++ b/include/openthread/border_routing.h @@ -118,6 +118,17 @@ typedef struct otBorderRoutingPrefixTableEntry uint32_t mPreferredLifetime; ///< Preferred lifetime of the on-link prefix when `mIsOnLink`. } otBorderRoutingPrefixTableEntry; +/** + * Represents a group of data of platform-generated RA messages processed. + * + */ +typedef struct otPdProcessedRaInfo +{ + uint32_t mNumPlatformRaReceived; ///< The number of platform generated RA handled by ProcessPlatfromGeneratedRa. + uint32_t mNumPlatformPioProcessed; ///< The number of PIO processed for adding OMR prefixes. + uint32_t mLastPlatformRaMsec; ///< The timestamp of last processed RA message. +} otPdProcessedRaInfo; + /** * Represents the state of Border Routing Manager. * @@ -307,6 +318,21 @@ otError otBorderRoutingGetOmrPrefix(otInstance *aInstance, otIp6Prefix *aPrefix) */ otError otBorderRoutingGetPdOmrPrefix(otInstance *aInstance, otBorderRoutingPrefixTableEntry *aPrefixInfo); +/** + * Gets the data of platform generated RA message processed.. + * + * `OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE` must be enabled. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * @param[out] aPrefixInfo A pointer to where the prefix info will be output to. + * + * @retval OT_ERROR_NONE Successfully retrieved the Info. + * @retval OT_ERROR_INVALID_STATE The Border Routing Manager is not initialized yet. + * @retval OT_ERROR_NOT_FOUND There are no valid Info on this BR. + * + */ +otError otBorderRoutingGetPdProcessedRaInfo(otInstance *aInstance, otPdProcessedRaInfo *aPdProcessedRaInfo); + /** * Gets the currently favored Off-Mesh-Routable (OMR) Prefix. * diff --git a/include/openthread/instance.h b/include/openthread/instance.h index ebc3fe122..3a668cffe 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -53,7 +53,7 @@ extern "C" { * @note This number versions both OpenThread platform and user APIs. * */ -#define OPENTHREAD_API_VERSION (382) +#define OPENTHREAD_API_VERSION (383) /** * @addtogroup api-instance diff --git a/include/openthread/ip6.h b/include/openthread/ip6.h index 8b32d7ca4..8301ff93d 100644 --- a/include/openthread/ip6.h +++ b/include/openthread/ip6.h @@ -907,6 +907,8 @@ typedef struct otBorderRoutingCounters otPacketsAndBytes mInboundMulticast; ///< The counters for inbound multicast. otPacketsAndBytes mOutboundUnicast; ///< The counters for outbound unicast. otPacketsAndBytes mOutboundMulticast; ///< The counters for outbound multicast. + otPacketsAndBytes mInboundInternet; ///< The counters for inbound Internet when DHCPv6 PD enabled. + otPacketsAndBytes mOutboundInternet; ///< The counters for outbound Internet when DHCPv6 PD enabled. uint32_t mRaRx; ///< The number of received RA packets. uint32_t mRaTxSuccess; ///< The number of RA packets successfully transmitted. uint32_t mRaTxFailure; ///< The number of RA packets failed to transmit. diff --git a/src/core/api/border_routing_api.cpp b/src/core/api/border_routing_api.cpp index 9fbfbcb4b..b62ee7041 100644 --- a/src/core/api/border_routing_api.cpp +++ b/src/core/api/border_routing_api.cpp @@ -104,6 +104,13 @@ otError otBorderRoutingGetPdOmrPrefix(otInstance *aInstance, otBorderRoutingPref return AsCoreType(aInstance).Get().GetPdOmrPrefix(*aPrefixInfo); } + +otError otBorderRoutingGetPdProcessedRaInfo(otInstance *aInstance, otPdProcessedRaInfo *aPdProcessedRaInfo) +{ + AssertPointerIsNotNull(aPdProcessedRaInfo); + + return AsCoreType(aInstance).Get().GetPdProcessedRaInfo(*aPdProcessedRaInfo); +} #endif otError otBorderRoutingGetFavoredOmrPrefix(otInstance *aInstance, otIp6Prefix *aPrefix, otRoutePreference *aPreference) diff --git a/src/core/border_router/routing_manager.cpp b/src/core/border_router/routing_manager.cpp index e48536819..e981af508 100644 --- a/src/core/border_router/routing_manager.cpp +++ b/src/core/border_router/routing_manager.cpp @@ -211,6 +211,17 @@ Error RoutingManager::GetPdOmrPrefix(PrefixTableEntry &aPrefixInfo) const VerifyOrExit(IsInitialized(), error = kErrorInvalidState); error = mPdPrefixManager.GetPrefixInfo(aPrefixInfo); +exit: + return error; +} + +Error RoutingManager::GetPdProcessedRaInfo(PdProcessedRaInfo &aPdProcessedRaInfo) +{ + Error error = kErrorNone; + + VerifyOrExit(IsInitialized(), error = kErrorInvalidState); + error = mPdPrefixManager.GetProcessedRaInfo(aPdProcessedRaInfo); + exit: return error; } @@ -3453,6 +3464,9 @@ RoutingManager::PdPrefixManager::PdPrefixManager(Instance &aInstance) : InstanceLocator(aInstance) , mEnabled(false) , mIsRunning(false) + , mNumPlatformPioProcessed(0) + , mNumPlatformRaReceived(0) + , mLastPlatformRaTime(0) , mTimer(aInstance) { mPrefix.Clear(); @@ -3519,6 +3533,20 @@ exit: return error; } +Error RoutingManager::PdPrefixManager::GetProcessedRaInfo(PdProcessedRaInfo &aPdProcessedRaInfo) const +{ + Error error = kErrorNone; + + VerifyOrExit(IsRunning() && HasPrefix(), error = kErrorNotFound); + + aPdProcessedRaInfo.mNumPlatformRaReceived = mNumPlatformRaReceived; + aPdProcessedRaInfo.mNumPlatformPioProcessed = mNumPlatformPioProcessed; + aPdProcessedRaInfo.mLastPlatformRaMsec = TimerMilli::GetNow() - mLastPlatformRaTime; + +exit: + return error; +} + void RoutingManager::PdPrefixManager::WithdrawPrefix(void) { VerifyOrExit(HasPrefix()); @@ -3542,6 +3570,8 @@ void RoutingManager::PdPrefixManager::ProcessPlatformGeneratedRa(const uint8_t * VerifyOrExit(IsRunning(), LogWarn("Ignore platform generated RA since PD is disabled or not running.")); packet.Init(aRouterAdvert, aLength); error = Process(Ip6::Nd::RouterAdvertMessage(packet)); + mNumPlatformRaReceived++; + mLastPlatformRaTime = TimerMilli::GetNow(); exit: if (error != kErrorNone) @@ -3568,7 +3598,7 @@ Error RoutingManager::PdPrefixManager::Process(const Ip6::Nd::RouterAdvertMessag { continue; } - + mNumPlatformPioProcessed++; entry.SetFrom(static_cast(option)); if (!IsValidPdPrefix(entry.GetPrefix())) diff --git a/src/core/border_router/routing_manager.hpp b/src/core/border_router/routing_manager.hpp index 10062e8f6..95a86f0e0 100644 --- a/src/core/border_router/routing_manager.hpp +++ b/src/core/border_router/routing_manager.hpp @@ -88,6 +88,7 @@ public: typedef otBorderRoutingPrefixTableIterator PrefixTableIterator; ///< Prefix Table Iterator. typedef otBorderRoutingPrefixTableEntry PrefixTableEntry; ///< Prefix Table Entry. typedef otBorderRoutingRouterEntry RouterEntry; ///< Router Entry. + typedef otPdProcessedRaInfo PdProcessedRaInfo; ///< Data of PdProcessedRaInfo. /** * This constant specifies the maximum number of route prefixes that may be published by `RoutingManager` @@ -292,6 +293,18 @@ public: * */ Error GetPdOmrPrefix(PrefixTableEntry &aPrefixInfo) const; + + /** + * Returns platform generated RA message processed information. + * + * @param[out] aPdProcessedRaInfo A reference to where the PD processed RA info will be output to. + * + * @retval kErrorNone Successfully retrieved the Info. + * @retval kErrorNotFound There are no valid RA process info on this BR. + * @retval kErrorInvalidState The Border Routing Manager is not initialized yet. + * + */ + Error GetPdProcessedRaInfo(PdProcessedRaInfo &aPdProcessedRaInfo); #endif /** @@ -1178,6 +1191,7 @@ private: void ProcessPlatformGeneratedRa(const uint8_t *aRouterAdvert, uint16_t aLength); Error GetPrefixInfo(PrefixTableEntry &aInfo) const; + Error GetProcessedRaInfo(PdProcessedRaInfo &aPdProcessedRaInfo) const; void HandleTimer(void) { WithdrawPrefix(); } static const char *StateToString(Dhcp6PdState aState); @@ -1199,6 +1213,9 @@ private: bool mEnabled; bool mIsRunning; + uint32_t mNumPlatformPioProcessed; + uint32_t mNumPlatformRaReceived; + TimeMilli mLastPlatformRaTime; PlatformOmrPrefixTimer mTimer; DiscoveredPrefixTable::Entry mPrefix; }; diff --git a/src/core/net/ip6.cpp b/src/core/net/ip6.cpp index d5ddeecad..4f3b077e0 100644 --- a/src/core/net/ip6.cpp +++ b/src/core/net/ip6.cpp @@ -1456,7 +1456,9 @@ Error Ip6::RouteLookup(const Address &aSource, const Address &aDestination) cons #if OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE void Ip6::UpdateBorderRoutingCounters(const Header &aHeader, uint16_t aMessageLength, bool aIsInbound) { - otPacketsAndBytes *counter = nullptr; + static constexpr uint8_t kPrefixLength = 48; + otPacketsAndBytes *counter = nullptr; + otPacketsAndBytes *internetCounter = nullptr; VerifyOrExit(!aHeader.GetSource().IsLinkLocal()); VerifyOrExit(!aHeader.GetDestination().IsLinkLocal()); @@ -1466,7 +1468,10 @@ void Ip6::UpdateBorderRoutingCounters(const Header &aHeader, uint16_t aMessageLe if (aIsInbound) { VerifyOrExit(!Get().HasUnicastAddress(aHeader.GetSource())); - + if (!aHeader.GetSource().MatchesPrefix(aHeader.GetDestination().GetPrefix().m8, kPrefixLength)) + { + internetCounter = &mBorderRoutingCounters.mInboundInternet; + } if (aHeader.GetDestination().IsMulticast()) { VerifyOrExit(aHeader.GetDestination().IsMulticastLargerThanRealmLocal()); @@ -1480,7 +1485,10 @@ void Ip6::UpdateBorderRoutingCounters(const Header &aHeader, uint16_t aMessageLe else { VerifyOrExit(!Get().HasUnicastAddress(aHeader.GetDestination())); - + if (!aHeader.GetSource().MatchesPrefix(aHeader.GetDestination().GetPrefix().m8, kPrefixLength)) + { + internetCounter = &mBorderRoutingCounters.mOutboundInternet; + } if (aHeader.GetDestination().IsMulticast()) { VerifyOrExit(aHeader.GetDestination().IsMulticastLargerThanRealmLocal()); @@ -1499,6 +1507,11 @@ exit: counter->mPackets += 1; counter->mBytes += aMessageLength; } + if (internetCounter) + { + internetCounter->mPackets += 1; + internetCounter->mBytes += aMessageLength; + } } #endif