[telemetry] border routing packet counters (#8280)

This commit introduces `otBorderRoutingCounters` which contains the
number of packets and bytes forwarded via border routing.

The counters have 4 categories: inbound unicast, inbound multicast,
outbound unicast, outbound multicast.

I've verified this feature locally on a BR device by ping command in
following scenarios:
- A host pings an ED's OMR.
- An ED pings a host's onlink address.
- A host pings a multicast address which an ED subscribes to.
- An ED pings a multicast address which a host subscribes to.
This commit is contained in:
whd
2022-11-04 00:13:10 -07:00
committed by GitHub
parent a532ce6e57
commit df20f3d91a
6 changed files with 133 additions and 1 deletions
+1 -1
View File
@@ -53,7 +53,7 @@ extern "C" {
* @note This number versions both OpenThread platform and user APIs.
*
*/
#define OPENTHREAD_API_VERSION (259)
#define OPENTHREAD_API_VERSION (260)
/**
* @addtogroup api-instance
+34
View File
@@ -851,6 +851,40 @@ otError otIp6SetMeshLocalIid(otInstance *aInstance, const otIp6InterfaceIdentifi
*/
const char *otIp6ProtoToString(uint8_t aIpProto);
/**
* This structure represents the counters for packets and bytes.
*
*/
typedef struct otPacketsAndBytes
{
uint64_t mPackets; ///< The number of packets.
uint64_t mBytes; ///< The number of bytes.
} otPacketsAndBytes;
/**
* This structure represents the counters of packets forwarded via Border Routing.
*
*/
typedef struct otBorderRoutingCounters
{
otPacketsAndBytes mInboundUnicast; ///< The counters for inbound unicast.
otPacketsAndBytes mInboundMulticast; ///< The counters for inbound multicast.
otPacketsAndBytes mOutboundUnicast; ///< The counters for outbound unicast.
otPacketsAndBytes mOutboundMulticast; ///< The counters for outbound multicast.
} otBorderRoutingCounters;
/**
* Gets the Border Routing counters.
*
* This function requires the build-time feature `OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE` to be enabled.
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
* @returns A pointer to the Border Routing counters.
*
*/
const otBorderRoutingCounters *otIp6GetBorderRoutingCounters(otInstance *aInstance);
/**
* @}
*
+7
View File
@@ -294,3 +294,10 @@ const char *otIp6ProtoToString(uint8_t aIpProto)
{
return Ip6::Ip6::IpProtoToString(aIpProto);
}
#if OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
const otBorderRoutingCounters *otIp6GetBorderRoutingCounters(otInstance *aInstance)
{
return &AsCoreType(aInstance).Get<Ip6::Ip6>().GetBorderRoutingCounters();
}
#endif
+12
View File
@@ -35,6 +35,8 @@
#ifndef CONFIG_IP6_H_
#define CONFIG_IP6_H_
#include "config/border_routing.h"
/**
* @def OPENTHREAD_CONFIG_IP6_MAX_EXT_UCAST_ADDRS
*
@@ -180,4 +182,14 @@
#define OPENTHREAD_CONFIG_IP6_ALLOW_LOOP_BACK_HOST_DATAGRAMS 1
#endif
/**
* @def OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
*
* Define as 1 to enable IPv6 Border Routing counters.
*
*/
#ifndef OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
#define OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
#endif
#endif // CONFIG_IP6_H_
+62
View File
@@ -1019,6 +1019,11 @@ Error Ip6::ProcessReceiveCallback(Message & aMessage,
{
Error error = kErrorNone;
Message *message = &aMessage;
#if OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
Header header;
IgnoreError(header.ParseFrom(aMessage));
#endif
VerifyOrExit(aOrigin != kFromHostDisallowLoopBack, error = kErrorNoRoute);
@@ -1103,6 +1108,10 @@ Error Ip6::ProcessReceiveCallback(Message & aMessage,
mReceiveIp6DatagramCallback(message, mReceiveIp6DatagramCallbackContext);
#if OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
UpdateBorderRoutingCounters(header, aMessage.GetLength(), /* aIsInbound */ false);
#endif
exit:
if ((error != kErrorNone) && (aMessageOwnership == Message::kTakeCustody))
@@ -1135,6 +1144,10 @@ Error Ip6::SendRaw(Message &aMessage, bool aAllowLoopBackToHost)
error = HandleDatagram(aMessage, aAllowLoopBackToHost ? kFromHostAllowLoopBack : kFromHostDisallowLoopBack);
freed = true;
#if OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
UpdateBorderRoutingCounters(header, aMessage.GetLength(), /* aIsInbound */ true);
#endif
exit:
if (!freed)
@@ -1492,6 +1505,55 @@ exit:
return rval;
}
#if OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
void Ip6::UpdateBorderRoutingCounters(const Header &aHeader, uint16_t aMessageLength, bool aIsInbound)
{
otPacketsAndBytes *counter = nullptr;
VerifyOrExit(!aHeader.GetSource().IsLinkLocal());
VerifyOrExit(!aHeader.GetDestination().IsLinkLocal());
VerifyOrExit(aHeader.GetSource().GetPrefix() != Get<Mle::Mle>().GetMeshLocalPrefix());
VerifyOrExit(aHeader.GetDestination().GetPrefix() != Get<Mle::Mle>().GetMeshLocalPrefix());
if (aIsInbound)
{
VerifyOrExit(!Get<Netif>().HasUnicastAddress(aHeader.GetSource()));
if (aHeader.GetDestination().IsMulticast())
{
VerifyOrExit(aHeader.GetDestination().IsMulticastLargerThanRealmLocal());
counter = &mBorderRoutingCounters.mInboundMulticast;
}
else
{
counter = &mBorderRoutingCounters.mInboundUnicast;
}
}
else
{
VerifyOrExit(!Get<Netif>().HasUnicastAddress(aHeader.GetDestination()));
if (aHeader.GetDestination().IsMulticast())
{
VerifyOrExit(aHeader.GetDestination().IsMulticastLargerThanRealmLocal());
counter = &mBorderRoutingCounters.mOutboundMulticast;
}
else
{
counter = &mBorderRoutingCounters.mOutboundUnicast;
}
}
exit:
if (counter)
{
counter->mPackets += 1;
counter->mBytes += aMessageLength;
}
}
#endif
// LCOV_EXCL_START
const char *Ip6::IpProtoToString(uint8_t aIpProto)
+17
View File
@@ -340,6 +340,16 @@ public:
*/
static const char *EcnToString(Ecn aEcn);
#if OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
/**
* This method returns a reference to the Border Routing counters.
*
* @returns A reference to the Border Routing counters.
*
*/
const otBorderRoutingCounters &GetBorderRoutingCounters(void) const { return mBorderRoutingCounters; }
#endif
private:
static constexpr uint8_t kDefaultHopLimit = OPENTHREAD_CONFIG_IP6_HOP_LIMIT_DEFAULT;
static constexpr uint8_t kIp6ReassemblyTimeout = OPENTHREAD_CONFIG_IP6_REASSEMBLY_TIMEOUT;
@@ -384,6 +394,9 @@ private:
Message::Ownership aMessageOwnership);
bool ShouldForwardToThread(const MessageInfo &aMessageInfo, MessageOrigin aOrigin) const;
bool IsOnLink(const Address &aAddress) const;
#if OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
void UpdateBorderRoutingCounters(const Header &aHeader, uint16_t aMessageLength, bool aIsInbound);
#endif
using SendQueueTask = TaskletIn<Ip6, &Ip6::HandleSendQueue>;
@@ -411,6 +424,10 @@ private:
#if OPENTHREAD_CONFIG_IP6_FRAGMENTATION_ENABLE
MessageQueue mReassemblyList;
#endif
#if OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
otBorderRoutingCounters mBorderRoutingCounters;
#endif
};
/**