mirror of
https://github.com/espressif/openthread.git
synced 2026-08-09 04:07:47 +00:00
[netdiag] add support for new BR Diagnostic TLVs (#11951)
This commit introduces new Network Diagnostic TLVs to report Border Router information. It implements the server and client side logic to support these new TLVs: - BR state (38) - `uint8` value as `otBorderRoutingState`. - BR Infra Interface Addresses (39) - list of IPv6 addresses - BR Local OMR Prefix (40) - local (ULA) OMR prefix - BR DHCPv6-PD OMR prefix (41) - DHCPv6-PD prefix (if any) - BR Local On-link Prefix (42) - local on-link prefix - BR Favored On-link Prefix (43) -favored discovered on-link on AIL The various BR prefix TLV values are encoded as a fixed 8 bytes value corresponding to the IPv6 prefix bytes (`/64`) in big-endian order. This commit updates the `networkdiagnostic get` CLI command to display the information from these new TLVs. It also includes a test (added in `test-503-peer-tbr-discovery.py`) to verify the new TLVs and the CLI commands.
This commit is contained in:
@@ -191,10 +191,10 @@ typedef enum
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
OT_BORDER_ROUTING_STATE_UNINITIALIZED, ///< Routing Manager is uninitialized.
|
||||
OT_BORDER_ROUTING_STATE_DISABLED, ///< Routing Manager is initialized but disabled.
|
||||
OT_BORDER_ROUTING_STATE_STOPPED, ///< Routing Manager in initialized and enabled but currently stopped.
|
||||
OT_BORDER_ROUTING_STATE_RUNNING, ///< Routing Manager is initialized, enabled, and running.
|
||||
OT_BORDER_ROUTING_STATE_UNINITIALIZED = 0, ///< Routing Manager is uninitialized.
|
||||
OT_BORDER_ROUTING_STATE_DISABLED = 1, ///< Routing Manager is initialized but disabled.
|
||||
OT_BORDER_ROUTING_STATE_STOPPED = 2, ///< Routing Manager in initialized and enabled but currently stopped.
|
||||
OT_BORDER_ROUTING_STATE_RUNNING = 3, ///< Routing Manager is initialized, enabled, and running.
|
||||
} otBorderRoutingState;
|
||||
|
||||
/**
|
||||
|
||||
@@ -52,7 +52,7 @@ extern "C" {
|
||||
*
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (540)
|
||||
#define OPENTHREAD_API_VERSION (541)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <openthread/border_routing.h>
|
||||
#include <openthread/dataset.h>
|
||||
#include <openthread/error.h>
|
||||
#include <openthread/instance.h>
|
||||
@@ -87,6 +88,12 @@ extern "C" {
|
||||
#define OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_APP_URL 35 ///< Vendor App URL TLV
|
||||
#define OT_NETWORK_DIAGNOSTIC_TLV_NON_PREFERRED_CHANNELS 36 ///< Non-Preferred Channels Mask TLV
|
||||
#define OT_NETWORK_DIAGNOSTIC_TLV_ENHANCED_ROUTE 37 ///< Enhanced Route TLV
|
||||
#define OT_NETWORK_DIAGNOSTIC_TLV_BR_STATE 38 ///< Border Router State TLV
|
||||
#define OT_NETWORK_DIAGNOSTIC_TLV_BR_IF_ADDRS 39 ///< Border Router Infra Interface Addresses TLV
|
||||
#define OT_NETWORK_DIAGNOSTIC_TLV_BR_LOCAL_OMR_PREFIX 40 ///< Border Router Local OMR Prefix TLV
|
||||
#define OT_NETWORK_DIAGNOSTIC_TLV_BR_DHCP6_PD_OMR_PREFIX 41 ///< Border Router DHCPv6-PD OMR Prefix TLV
|
||||
#define OT_NETWORK_DIAGNOSTIC_TLV_BR_LOCAL_OL_PREFIX 42 ///< Border Router Local On-link Prefix TLV
|
||||
#define OT_NETWORK_DIAGNOSTIC_TLV_BR_FAVORED_OL_PREFIX 43 ///< Border Router Favored On-link Prefix TLV
|
||||
|
||||
#define OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_NAME_TLV_LENGTH 32 ///< Max length of Vendor Name TLV.
|
||||
#define OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_MODEL_TLV_LENGTH 32 ///< Max length of Vendor Model TLV.
|
||||
@@ -261,6 +268,11 @@ typedef struct otNetworkDiagChildTable
|
||||
otNetworkDiagChildEntry mTable[OT_NETWORK_BASE_TLV_MAX_LENGTH / sizeof(otNetworkDiagChildEntry)]; ///< Child table.
|
||||
} otNetworkDiagChildTable;
|
||||
|
||||
/**
|
||||
* Represents a Border Router State TLV value.
|
||||
*/
|
||||
typedef otBorderRoutingState otNetworkDiagBrState;
|
||||
|
||||
/**
|
||||
* Represents a Network Diagnostic TLV.
|
||||
*/
|
||||
@@ -295,6 +307,9 @@ typedef struct otNetworkDiagTlv
|
||||
otChannelMask mNonPreferredChannels;
|
||||
otNetworkDiagData mChannelPages;
|
||||
otNetworkDiagChildTable mChildTable;
|
||||
otNetworkDiagBrState mBrState;
|
||||
otNetworkDiagIp6AddrList mBrIfAddrList;
|
||||
otIp6NetworkPrefix mBrPrefix; // This field is shared for various BR prefix TLV (OMR, on-link).
|
||||
} mData;
|
||||
} otNetworkDiagTlv;
|
||||
|
||||
|
||||
+40
-5
@@ -7864,6 +7864,13 @@ template <> otError Interpreter::Process<Cmd("networkdiagnostic")>(Arg aArgs[])
|
||||
* - `34`: MLE Counters TLV
|
||||
* - `35`: Vendor App URL TLV
|
||||
* - `37`: Enhanced Route TLV
|
||||
* - `38`: Border Router State TLV
|
||||
* - `39`: Border Router Infra Interface Addresses TLV
|
||||
* - `40`: Border Router Local OMR Prefix TLV
|
||||
* - `41`: Border Router DHCPv6-PD OMR Prefix TLV
|
||||
* - `42`: Border Router Local On-link Prefix TLV
|
||||
* - `43`: Border Router Favored On-link Prefix TLV
|
||||
*
|
||||
* @par
|
||||
* Sends a network diagnostic request to retrieve specified Type Length Values (TLVs)
|
||||
* for the specified addresses(es).
|
||||
@@ -7986,11 +7993,7 @@ void Interpreter::HandleDiagnosticGetResponse(otError aError,
|
||||
break;
|
||||
case OT_NETWORK_DIAGNOSTIC_TLV_IP6_ADDR_LIST:
|
||||
OutputLine("IP6 Address List:");
|
||||
for (uint16_t i = 0; i < diagTlv.mData.mIp6AddrList.mCount; ++i)
|
||||
{
|
||||
OutputFormat(kIndentSize, "- ");
|
||||
OutputIp6AddressLine(diagTlv.mData.mIp6AddrList.mList[i]);
|
||||
}
|
||||
OutputIp6AddrList(kIndentSize, diagTlv.mData.mIp6AddrList);
|
||||
break;
|
||||
case OT_NETWORK_DIAGNOSTIC_TLV_MAC_COUNTERS:
|
||||
OutputLine("MAC Counters:");
|
||||
@@ -8044,6 +8047,29 @@ void Interpreter::HandleDiagnosticGetResponse(otError aError,
|
||||
case OT_NETWORK_DIAGNOSTIC_TLV_NON_PREFERRED_CHANNELS:
|
||||
OutputLine("Non-preferred Channels Mask: 0x%lx", ToUlong(diagTlv.mData.mNonPreferredChannels));
|
||||
break;
|
||||
case OT_NETWORK_DIAGNOSTIC_TLV_BR_STATE:
|
||||
OutputLine("BR State: %s", BorderRoutingStateToString(diagTlv.mData.mBrState));
|
||||
break;
|
||||
case OT_NETWORK_DIAGNOSTIC_TLV_BR_IF_ADDRS:
|
||||
OutputLine("BR Infra-if IP6 Address List:");
|
||||
OutputIp6AddrList(kIndentSize, diagTlv.mData.mBrIfAddrList);
|
||||
break;
|
||||
case OT_NETWORK_DIAGNOSTIC_TLV_BR_LOCAL_OMR_PREFIX:
|
||||
OutputFormat("BR Local OMR Prefix: ");
|
||||
OutputIp6PrefixLine(diagTlv.mData.mBrPrefix);
|
||||
break;
|
||||
case OT_NETWORK_DIAGNOSTIC_TLV_BR_DHCP6_PD_OMR_PREFIX:
|
||||
OutputFormat("BR DHCPv6-PD OMR Prefix: ");
|
||||
OutputIp6PrefixLine(diagTlv.mData.mBrPrefix);
|
||||
break;
|
||||
case OT_NETWORK_DIAGNOSTIC_TLV_BR_LOCAL_OL_PREFIX:
|
||||
OutputFormat("BR Local On-link Prefix: ");
|
||||
OutputIp6PrefixLine(diagTlv.mData.mBrPrefix);
|
||||
break;
|
||||
case OT_NETWORK_DIAGNOSTIC_TLV_BR_FAVORED_OL_PREFIX:
|
||||
OutputFormat("BR Favored On-link Prefix: ");
|
||||
OutputIp6PrefixLine(diagTlv.mData.mBrPrefix);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -8134,6 +8160,15 @@ void Interpreter::OutputLeaderData(uint8_t aIndentSize, const otLeaderData &aLea
|
||||
OutputLine(aIndentSize, "LeaderRouterId: 0x%02x", aLeaderData.mLeaderRouterId);
|
||||
}
|
||||
|
||||
void Interpreter::OutputIp6AddrList(uint8_t aIndentSize, const otNetworkDiagIp6AddrList &aIp6Addrs)
|
||||
{
|
||||
for (uint8_t i = 0; i < aIp6Addrs.mCount; ++i)
|
||||
{
|
||||
OutputFormat(aIndentSize, "- ");
|
||||
OutputIp6AddressLine(aIp6Addrs.mList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::OutputNetworkDiagMacCounters(uint8_t aIndentSize, const otNetworkDiagMacCounters &aMacCounters)
|
||||
{
|
||||
struct CounterName
|
||||
|
||||
@@ -264,6 +264,7 @@ private:
|
||||
void OutputRouteData(uint8_t aIndentSize, const otNetworkDiagRouteData &aRouteData);
|
||||
void OutputEnhRoute(uint8_t aIndentSize, const otNetworkDiagEnhRoute &aEnhRoute);
|
||||
void OutputLeaderData(uint8_t aIndentSize, const otLeaderData &aLeaderData);
|
||||
void OutputIp6AddrList(uint8_t aIndentSize, const otNetworkDiagIp6AddrList &aIp6Addrs);
|
||||
void OutputNetworkDiagMacCounters(uint8_t aIndentSize, const otNetworkDiagMacCounters &aMacCounters);
|
||||
void OutputNetworkDiagMleCounters(uint8_t aIndentSize, const otNetworkDiagMleCounters &aMleCounters);
|
||||
void OutputChildTableEntry(uint8_t aIndentSize, const otNetworkDiagChildEntry &aChildEntry);
|
||||
|
||||
+1
-14
@@ -145,23 +145,10 @@ exit:
|
||||
*/
|
||||
template <> otError Br::Process<Cmd("state")>(Arg aArgs[])
|
||||
{
|
||||
static const char *const kStateStrings[] = {
|
||||
|
||||
"uninitialized", // (0) OT_BORDER_ROUTING_STATE_UNINITIALIZED
|
||||
"disabled", // (1) OT_BORDER_ROUTING_STATE_DISABLED
|
||||
"stopped", // (2) OT_BORDER_ROUTING_STATE_STOPPED
|
||||
"running", // (3) OT_BORDER_ROUTING_STATE_RUNNING
|
||||
};
|
||||
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
static_assert(0 == OT_BORDER_ROUTING_STATE_UNINITIALIZED, "STATE_UNINITIALIZED value is incorrect");
|
||||
static_assert(1 == OT_BORDER_ROUTING_STATE_DISABLED, "STATE_DISABLED value is incorrect");
|
||||
static_assert(2 == OT_BORDER_ROUTING_STATE_STOPPED, "STATE_STOPPED value is incorrect");
|
||||
static_assert(3 == OT_BORDER_ROUTING_STATE_RUNNING, "STATE_RUNNING value is incorrect");
|
||||
|
||||
VerifyOrExit(aArgs[0].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
|
||||
OutputLine("%s", Stringify(otBorderRoutingGetState(GetInstancePtr()), kStateStrings));
|
||||
OutputLine("%s", BorderRoutingStateToString(otBorderRoutingGetState(GetInstancePtr())));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
|
||||
@@ -810,5 +810,22 @@ const char *Utils::AddressOriginToString(uint8_t aOrigin)
|
||||
return Stringify(aOrigin, kOriginStrings);
|
||||
}
|
||||
|
||||
const char *Utils::BorderRoutingStateToString(otBorderRoutingState aState)
|
||||
{
|
||||
static const char *const kStateStrings[] = {
|
||||
"uninitialized", // (0) OT_BORDER_ROUTING_STATE_UNINITIALIZED
|
||||
"disabled", // (1) OT_BORDER_ROUTING_STATE_DISABLED
|
||||
"stopped", // (2) OT_BORDER_ROUTING_STATE_STOPPED
|
||||
"running", // (3) OT_BORDER_ROUTING_STATE_RUNNING
|
||||
};
|
||||
|
||||
static_assert(0 == OT_BORDER_ROUTING_STATE_UNINITIALIZED, "STATE_UNINITIALIZED value is incorrect");
|
||||
static_assert(1 == OT_BORDER_ROUTING_STATE_DISABLED, "STATE_DISABLED value is incorrect");
|
||||
static_assert(2 == OT_BORDER_ROUTING_STATE_STOPPED, "STATE_STOPPED value is incorrect");
|
||||
static_assert(3 == OT_BORDER_ROUTING_STATE_RUNNING, "STATE_RUNNING value is incorrect");
|
||||
|
||||
return Stringify(aState, kStateStrings);
|
||||
}
|
||||
|
||||
} // namespace Cli
|
||||
} // namespace ot
|
||||
|
||||
@@ -718,6 +718,15 @@ public:
|
||||
*/
|
||||
static const char *AddressOriginToString(uint8_t aOrigin);
|
||||
|
||||
/**
|
||||
* Converts a given `otBorderRoutingState` value (`OT_BORDER_ROUTING_STATE_*`) to human-readable string.
|
||||
*
|
||||
* @param[in] aState The BR state to convert.
|
||||
*
|
||||
* @returns A human-readable string representation of @p aState.
|
||||
*/
|
||||
static const char *BorderRoutingStateToString(otBorderRoutingState aState);
|
||||
|
||||
protected:
|
||||
void OutputFormatV(const char *aFormat, va_list aArguments);
|
||||
|
||||
|
||||
@@ -48,6 +48,17 @@ Error NetworkPrefix::GenerateRandomUla(void)
|
||||
return Random::Crypto::FillBuffer(&m8[1], kSize - 1);
|
||||
}
|
||||
|
||||
Error NetworkPrefix::SetFrom(const Prefix &aPrefix)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(aPrefix.GetLength() == kLength, error = kErrorInvalidArgs);
|
||||
memcpy(m8, aPrefix.GetBytes(), kSize);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// Prefix methods
|
||||
|
||||
|
||||
@@ -61,6 +61,8 @@ namespace Ip6 {
|
||||
* @{
|
||||
*/
|
||||
|
||||
class Prefix;
|
||||
|
||||
/**
|
||||
* Represents the Network Prefix of an IPv6 address (most significant 64 bits of the address).
|
||||
*/
|
||||
@@ -80,6 +82,16 @@ public:
|
||||
*/
|
||||
Error GenerateRandomUla(void);
|
||||
|
||||
/**
|
||||
* Sets the Network Prefix from a given `Prefix`.
|
||||
*
|
||||
* @param[in] aPrefix The prefix to use to set the Network Prefix.
|
||||
*
|
||||
* @retval kErrorNone Successfully set the Network Prefix from @p aPrefix.
|
||||
* @retval kErrorInvalidArgs The @p aPrefix length is not valid (must be `kLength`).
|
||||
*/
|
||||
Error SetFrom(const Prefix &aPrefix);
|
||||
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
|
||||
@@ -327,6 +327,82 @@ Error Server::AppendMacCounters(Message &aMessage)
|
||||
return tlv.AppendTo(aMessage);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
Error Server::AppendBorderRouterIfAddrs(Message &aMessage)
|
||||
{
|
||||
Error error;
|
||||
Tlv tlv;
|
||||
uint16_t offset;
|
||||
uint16_t length = 0;
|
||||
BorderRouter::PrefixTableIterator iterator;
|
||||
BorderRouter::IfAddrEntry ifAddr;
|
||||
|
||||
tlv.SetType(Tlv::kBrIfAddrs);
|
||||
|
||||
offset = aMessage.GetLength();
|
||||
SuccessOrExit(error = aMessage.Append(tlv));
|
||||
|
||||
Get<BorderRouter::RoutingManager>().InitPrefixTableIterator(iterator);
|
||||
|
||||
while (Get<BorderRouter::RoutingManager>().GetNextIfAddrEntry(iterator, ifAddr) == kErrorNone)
|
||||
{
|
||||
if (length + sizeof(Ip6::Address) > Tlv::kBaseTlvMaxLength)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
SuccessOrExit(error = aMessage.Append(ifAddr.mAddress));
|
||||
length += sizeof(Ip6::Address);
|
||||
}
|
||||
|
||||
tlv.SetLength(ClampToUint8(length));
|
||||
aMessage.Write(offset, tlv);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error Server::AppendBrPrefixTlv(uint8_t aTlvType, Message &aMessage)
|
||||
{
|
||||
Ip6::Prefix prefix;
|
||||
Ip6::NetworkPrefix netPrefix;
|
||||
|
||||
netPrefix.Clear();
|
||||
|
||||
switch (aTlvType)
|
||||
{
|
||||
case Tlv::kBrLocalOmrPrefix:
|
||||
SuccessOrExit(Get<BorderRouter::RoutingManager>().GetOmrPrefix(prefix));
|
||||
break;
|
||||
case Tlv::kBrLocalOnlinkPrefix:
|
||||
SuccessOrExit(Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(prefix));
|
||||
break;
|
||||
case Tlv::kBrFavoredOnLinkPrefix:
|
||||
SuccessOrExit(Get<BorderRouter::RoutingManager>().GetFavoredOnLinkPrefix(prefix));
|
||||
break;
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
|
||||
case Tlv::kBrDhcp6PdOmrPrefix:
|
||||
{
|
||||
BorderRouter::Dhcp6PdPrefix pdPrefix;
|
||||
|
||||
SuccessOrExit(Get<BorderRouter::RoutingManager>().GetDhcp6PdOmrPrefix(pdPrefix));
|
||||
prefix = AsCoreType(&pdPrefix.mPrefix);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
IgnoreError(netPrefix.SetFrom(prefix));
|
||||
|
||||
exit:
|
||||
return Tlv::AppendTlv(aMessage, aTlvType, &netPrefix, sizeof(netPrefix));
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
Error Server::AppendRequestedTlvs(const Message &aRequest, Message &aResponse)
|
||||
{
|
||||
Error error;
|
||||
@@ -566,6 +642,25 @@ Error Server::AppendDiagTlv(uint8_t aTlvType, Message &aMessage)
|
||||
|
||||
#endif // OPENTHREAD_FTD
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
case Tlv::kBrState:
|
||||
error = Tlv::Append<BrStateTlv>(aMessage, Get<BorderRouter::RoutingManager>().GetState());
|
||||
break;
|
||||
|
||||
case Tlv::kBrIfAddrs:
|
||||
error = AppendBorderRouterIfAddrs(aMessage);
|
||||
break;
|
||||
|
||||
case Tlv::kBrLocalOmrPrefix:
|
||||
case Tlv::kBrDhcp6PdOmrPrefix:
|
||||
case Tlv::kBrLocalOnlinkPrefix:
|
||||
case Tlv::kBrFavoredOnLinkPrefix:
|
||||
error = AppendBrPrefixTlv(aTlvType, aMessage);
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1232,7 +1327,7 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
static inline void ParseMacCounters(const MacCountersTlv &aMacCountersTlv, otNetworkDiagMacCounters &aMacCounters)
|
||||
void Client::ParseMacCounters(const MacCountersTlv &aMacCountersTlv, otNetworkDiagMacCounters &aMacCounters)
|
||||
{
|
||||
aMacCounters.mIfInUnknownProtos = aMacCountersTlv.GetIfInUnknownProtos();
|
||||
aMacCounters.mIfInErrors = aMacCountersTlv.GetIfInErrors();
|
||||
@@ -1245,6 +1340,19 @@ static inline void ParseMacCounters(const MacCountersTlv &aMacCountersTlv, otNet
|
||||
aMacCounters.mIfOutDiscards = aMacCountersTlv.GetIfOutDiscards();
|
||||
}
|
||||
|
||||
void Client::ParseIp6AddrList(Ip6AddrList &aIp6Addrs, const Message &aMessage, OffsetRange aOffsetRange)
|
||||
{
|
||||
aIp6Addrs.mCount = 0;
|
||||
|
||||
while (aOffsetRange.Contains(sizeof(Ip6::Address)) && (aIp6Addrs.mCount < GetArrayLength(aIp6Addrs.mList)))
|
||||
{
|
||||
IgnoreError(aMessage.Read(aOffsetRange, aIp6Addrs.mList[aIp6Addrs.mCount]));
|
||||
aOffsetRange.AdvanceOffset(sizeof(Ip6::Address));
|
||||
|
||||
aIp6Addrs.mCount++;
|
||||
}
|
||||
}
|
||||
|
||||
Error Client::GetNextDiagTlv(const Coap::Message &aMessage, Iterator &aIterator, TlvInfo &aTlvInfo)
|
||||
{
|
||||
Error error;
|
||||
@@ -1346,29 +1454,8 @@ Error Client::GetNextDiagTlv(const Coap::Message &aMessage, Iterator &aIterator,
|
||||
break;
|
||||
|
||||
case Tlv::kIp6AddressList:
|
||||
{
|
||||
uint16_t addrListLength = GetArrayLength(aTlvInfo.mData.mIp6AddrList.mList);
|
||||
Ip6::Address *addrEntry = AsCoreTypePtr(&aTlvInfo.mData.mIp6AddrList.mList[0]);
|
||||
uint8_t &addrCount = aTlvInfo.mData.mIp6AddrList.mCount;
|
||||
|
||||
VerifyOrExit((valueOffsetRange.GetLength() % Ip6::Address::kSize) == 0, error = kErrorParse);
|
||||
|
||||
// `TlvInfo` has a fixed array for IPv6 addresses. If there
|
||||
// are more addresses in the message, we read and return as
|
||||
// many as can fit in array and ignore the rest.
|
||||
|
||||
addrCount = 0;
|
||||
|
||||
while (!valueOffsetRange.IsEmpty() && (addrCount < addrListLength))
|
||||
{
|
||||
SuccessOrExit(error = aMessage.Read(valueOffsetRange, *addrEntry));
|
||||
addrCount++;
|
||||
addrEntry++;
|
||||
valueOffsetRange.AdvanceOffset(Ip6::Address::kSize);
|
||||
}
|
||||
|
||||
ParseIp6AddrList(aTlvInfo.mData.mIp6AddrList, aMessage, valueOffsetRange);
|
||||
break;
|
||||
}
|
||||
|
||||
case Tlv::kMacCounters:
|
||||
{
|
||||
@@ -1476,6 +1563,26 @@ Error Client::GetNextDiagTlv(const Coap::Message &aMessage, Iterator &aIterator,
|
||||
aTlvInfo.mData.mNonPreferredChannels));
|
||||
break;
|
||||
|
||||
case Tlv::kBrState:
|
||||
{
|
||||
uint8_t state;
|
||||
|
||||
SuccessOrExit(error = Tlv::Read<BrStateTlv>(aMessage, offset, state));
|
||||
aTlvInfo.mData.mBrState = static_cast<BrState>(state);
|
||||
break;
|
||||
}
|
||||
|
||||
case Tlv::kBrIfAddrs:
|
||||
ParseIp6AddrList(aTlvInfo.mData.mBrIfAddrList, aMessage, valueOffsetRange);
|
||||
break;
|
||||
|
||||
case Tlv::kBrLocalOmrPrefix:
|
||||
case Tlv::kBrLocalOnlinkPrefix:
|
||||
case Tlv::kBrFavoredOnLinkPrefix:
|
||||
case Tlv::kBrDhcp6PdOmrPrefix:
|
||||
SuccessOrExit(error = aMessage.Read(valueOffsetRange, aTlvInfo.mData.mBrPrefix));
|
||||
break;
|
||||
|
||||
default:
|
||||
// Skip unrecognized TLVs.
|
||||
skipTlv = true;
|
||||
|
||||
@@ -265,6 +265,10 @@ private:
|
||||
const Ip6::MessageInfo *aMessageInfo,
|
||||
Error aResult);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
Error AppendBorderRouterIfAddrs(Message &aMessage);
|
||||
Error AppendBrPrefixTlv(uint8_t aTlvType, Message &aMessage);
|
||||
#endif
|
||||
|
||||
template <Uri kUri> void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
@@ -357,6 +361,9 @@ public:
|
||||
uint16_t GetLastQueryId(void) const { return mQueryId; }
|
||||
|
||||
private:
|
||||
typedef otNetworkDiagIp6AddrList Ip6AddrList;
|
||||
typedef otNetworkDiagMacCounters MacCounters;
|
||||
|
||||
Error SendCommand(Uri aUri,
|
||||
Message::Priority aPriority,
|
||||
const Ip6::Address &aDestination,
|
||||
@@ -373,6 +380,9 @@ private:
|
||||
|
||||
template <Uri kUri> void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
static void ParseIp6AddrList(Ip6AddrList &aIp6Addrs, const Message &aMessage, OffsetRange aOffsetRange);
|
||||
static void ParseMacCounters(const MacCountersTlv &aMacCountersTlv, MacCounters &aMacCounters);
|
||||
|
||||
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
|
||||
static const char *UriToString(Uri aUri);
|
||||
#endif
|
||||
|
||||
@@ -66,37 +66,43 @@ public:
|
||||
*/
|
||||
enum Type : uint8_t
|
||||
{
|
||||
kExtMacAddress = OT_NETWORK_DIAGNOSTIC_TLV_EXT_ADDRESS,
|
||||
kAddress16 = OT_NETWORK_DIAGNOSTIC_TLV_SHORT_ADDRESS,
|
||||
kMode = OT_NETWORK_DIAGNOSTIC_TLV_MODE,
|
||||
kTimeout = OT_NETWORK_DIAGNOSTIC_TLV_TIMEOUT,
|
||||
kConnectivity = OT_NETWORK_DIAGNOSTIC_TLV_CONNECTIVITY,
|
||||
kRoute = OT_NETWORK_DIAGNOSTIC_TLV_ROUTE,
|
||||
kLeaderData = OT_NETWORK_DIAGNOSTIC_TLV_LEADER_DATA,
|
||||
kNetworkData = OT_NETWORK_DIAGNOSTIC_TLV_NETWORK_DATA,
|
||||
kIp6AddressList = OT_NETWORK_DIAGNOSTIC_TLV_IP6_ADDR_LIST,
|
||||
kMacCounters = OT_NETWORK_DIAGNOSTIC_TLV_MAC_COUNTERS,
|
||||
kBatteryLevel = OT_NETWORK_DIAGNOSTIC_TLV_BATTERY_LEVEL,
|
||||
kSupplyVoltage = OT_NETWORK_DIAGNOSTIC_TLV_SUPPLY_VOLTAGE,
|
||||
kChildTable = OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE,
|
||||
kChannelPages = OT_NETWORK_DIAGNOSTIC_TLV_CHANNEL_PAGES,
|
||||
kTypeList = OT_NETWORK_DIAGNOSTIC_TLV_TYPE_LIST,
|
||||
kMaxChildTimeout = OT_NETWORK_DIAGNOSTIC_TLV_MAX_CHILD_TIMEOUT,
|
||||
kEui64 = OT_NETWORK_DIAGNOSTIC_TLV_EUI64,
|
||||
kVersion = OT_NETWORK_DIAGNOSTIC_TLV_VERSION,
|
||||
kVendorName = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_NAME,
|
||||
kVendorModel = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_MODEL,
|
||||
kVendorSwVersion = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_SW_VERSION,
|
||||
kThreadStackVersion = OT_NETWORK_DIAGNOSTIC_TLV_THREAD_STACK_VERSION,
|
||||
kChild = OT_NETWORK_DIAGNOSTIC_TLV_CHILD,
|
||||
kChildIp6AddressList = OT_NETWORK_DIAGNOSTIC_TLV_CHILD_IP6_ADDR_LIST,
|
||||
kRouterNeighbor = OT_NETWORK_DIAGNOSTIC_TLV_ROUTER_NEIGHBOR,
|
||||
kAnswer = OT_NETWORK_DIAGNOSTIC_TLV_ANSWER,
|
||||
kQueryId = OT_NETWORK_DIAGNOSTIC_TLV_QUERY_ID,
|
||||
kMleCounters = OT_NETWORK_DIAGNOSTIC_TLV_MLE_COUNTERS,
|
||||
kVendorAppUrl = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_APP_URL,
|
||||
kNonPreferredChannels = OT_NETWORK_DIAGNOSTIC_TLV_NON_PREFERRED_CHANNELS,
|
||||
kEnhancedRoute = OT_NETWORK_DIAGNOSTIC_TLV_ENHANCED_ROUTE,
|
||||
kExtMacAddress = OT_NETWORK_DIAGNOSTIC_TLV_EXT_ADDRESS,
|
||||
kAddress16 = OT_NETWORK_DIAGNOSTIC_TLV_SHORT_ADDRESS,
|
||||
kMode = OT_NETWORK_DIAGNOSTIC_TLV_MODE,
|
||||
kTimeout = OT_NETWORK_DIAGNOSTIC_TLV_TIMEOUT,
|
||||
kConnectivity = OT_NETWORK_DIAGNOSTIC_TLV_CONNECTIVITY,
|
||||
kRoute = OT_NETWORK_DIAGNOSTIC_TLV_ROUTE,
|
||||
kLeaderData = OT_NETWORK_DIAGNOSTIC_TLV_LEADER_DATA,
|
||||
kNetworkData = OT_NETWORK_DIAGNOSTIC_TLV_NETWORK_DATA,
|
||||
kIp6AddressList = OT_NETWORK_DIAGNOSTIC_TLV_IP6_ADDR_LIST,
|
||||
kMacCounters = OT_NETWORK_DIAGNOSTIC_TLV_MAC_COUNTERS,
|
||||
kBatteryLevel = OT_NETWORK_DIAGNOSTIC_TLV_BATTERY_LEVEL,
|
||||
kSupplyVoltage = OT_NETWORK_DIAGNOSTIC_TLV_SUPPLY_VOLTAGE,
|
||||
kChildTable = OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE,
|
||||
kChannelPages = OT_NETWORK_DIAGNOSTIC_TLV_CHANNEL_PAGES,
|
||||
kTypeList = OT_NETWORK_DIAGNOSTIC_TLV_TYPE_LIST,
|
||||
kMaxChildTimeout = OT_NETWORK_DIAGNOSTIC_TLV_MAX_CHILD_TIMEOUT,
|
||||
kEui64 = OT_NETWORK_DIAGNOSTIC_TLV_EUI64,
|
||||
kVersion = OT_NETWORK_DIAGNOSTIC_TLV_VERSION,
|
||||
kVendorName = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_NAME,
|
||||
kVendorModel = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_MODEL,
|
||||
kVendorSwVersion = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_SW_VERSION,
|
||||
kThreadStackVersion = OT_NETWORK_DIAGNOSTIC_TLV_THREAD_STACK_VERSION,
|
||||
kChild = OT_NETWORK_DIAGNOSTIC_TLV_CHILD,
|
||||
kChildIp6AddressList = OT_NETWORK_DIAGNOSTIC_TLV_CHILD_IP6_ADDR_LIST,
|
||||
kRouterNeighbor = OT_NETWORK_DIAGNOSTIC_TLV_ROUTER_NEIGHBOR,
|
||||
kAnswer = OT_NETWORK_DIAGNOSTIC_TLV_ANSWER,
|
||||
kQueryId = OT_NETWORK_DIAGNOSTIC_TLV_QUERY_ID,
|
||||
kMleCounters = OT_NETWORK_DIAGNOSTIC_TLV_MLE_COUNTERS,
|
||||
kVendorAppUrl = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_APP_URL,
|
||||
kNonPreferredChannels = OT_NETWORK_DIAGNOSTIC_TLV_NON_PREFERRED_CHANNELS,
|
||||
kEnhancedRoute = OT_NETWORK_DIAGNOSTIC_TLV_ENHANCED_ROUTE,
|
||||
kBrState = OT_NETWORK_DIAGNOSTIC_TLV_BR_STATE,
|
||||
kBrIfAddrs = OT_NETWORK_DIAGNOSTIC_TLV_BR_IF_ADDRS,
|
||||
kBrLocalOmrPrefix = OT_NETWORK_DIAGNOSTIC_TLV_BR_LOCAL_OMR_PREFIX,
|
||||
kBrDhcp6PdOmrPrefix = OT_NETWORK_DIAGNOSTIC_TLV_BR_DHCP6_PD_OMR_PREFIX,
|
||||
kBrLocalOnlinkPrefix = OT_NETWORK_DIAGNOSTIC_TLV_BR_LOCAL_OL_PREFIX,
|
||||
kBrFavoredOnLinkPrefix = OT_NETWORK_DIAGNOSTIC_TLV_BR_FAVORED_OL_PREFIX,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -235,6 +241,41 @@ typedef TlvInfo<Tlv::kChildIp6AddressList> ChildIp6AddressListTlv;
|
||||
*/
|
||||
typedef UintTlvInfo<Tlv::kQueryId, uint16_t> QueryIdTlv;
|
||||
|
||||
/**
|
||||
* Defines BR State TLV constants and types.
|
||||
*/
|
||||
typedef UintTlvInfo<Tlv::kBrState, uint8_t> BrStateTlv;
|
||||
|
||||
/**
|
||||
* Represents a BR State TLV value.
|
||||
*/
|
||||
typedef otNetworkDiagBrState BrState;
|
||||
|
||||
/**
|
||||
* Defines BR Infra-if Address List TLV constants and types.
|
||||
*/
|
||||
typedef TlvInfo<Tlv::kBrIfAddrs> BrIfAddrsTlv;
|
||||
|
||||
/**
|
||||
* Defines BR Local OMR Prefix TLV constants and types.
|
||||
*/
|
||||
typedef SimpleTlvInfo<Tlv::kBrLocalOmrPrefix, Ip6::NetworkPrefix> BrLocalOmrPrefixTlv;
|
||||
|
||||
/**
|
||||
* Defines BR DHCPv6-PD Prefix TLV constants and types.
|
||||
*/
|
||||
typedef SimpleTlvInfo<Tlv::kBrDhcp6PdOmrPrefix, Ip6::NetworkPrefix> BrDhcp6PdOmrPrefixTlv;
|
||||
|
||||
/**
|
||||
* Defines BR Local On-link Prefix TLV constants and types.
|
||||
*/
|
||||
typedef SimpleTlvInfo<Tlv::kBrLocalOnlinkPrefix, Ip6::NetworkPrefix> BrLocalOnlinkPrefixTlv;
|
||||
|
||||
/**
|
||||
* Defines BR Favored On-link Prefix TLV constants and types.
|
||||
*/
|
||||
typedef SimpleTlvInfo<Tlv::kBrFavoredOnLinkPrefix, Ip6::NetworkPrefix> BrFavoredOnLinkPrefixTlv;
|
||||
|
||||
typedef otNetworkDiagConnectivity Connectivity; ///< Network Diagnostic Connectivity value.
|
||||
|
||||
/**
|
||||
|
||||
@@ -71,6 +71,13 @@ verify(br3.get_state() == 'router')
|
||||
# -----------------------------------------------------------------------------------------------------------------------
|
||||
# Test implementation
|
||||
|
||||
BR_STATE_TLV = 38
|
||||
BR_IF_ADDRS_TLV = 39
|
||||
BR_LOCAL_OMR_PREFIX_TLV = 40
|
||||
BR_DHCP6_PD_OMR_PREFIX_TLV = 41
|
||||
BR_LOCAL_OL_PREFIX_TLV = 42
|
||||
BR_FAVORED_OL_PREFIX_TLV = 43
|
||||
|
||||
# Start first border router `br1`
|
||||
|
||||
br1.srp_server_set_addr_mode('unicast')
|
||||
@@ -114,7 +121,7 @@ for br in all_brs:
|
||||
verify(int(br.br_count_peers().split()[0]) == 2)
|
||||
peers = br.br_get_peer_brs()
|
||||
verify(len(peers) == 2)
|
||||
other_brs = all_brs
|
||||
other_brs = [br1, br2, br3]
|
||||
other_brs.remove(br)
|
||||
for other_br in other_brs:
|
||||
rloc16 = other_br.get_rloc16()
|
||||
@@ -123,6 +130,38 @@ for br in all_brs:
|
||||
verify(len(ifaddrs) == 1)
|
||||
verify(ifaddrs[0].startswith('fe80:'))
|
||||
|
||||
# Validate network diagnostic BR TLVs, query BR2 from BR1.
|
||||
|
||||
br2_rloc = br2.get_rloc_ip_addr()
|
||||
result = br1.cli('networkdiagnostic get', br2_rloc, BR_STATE_TLV)
|
||||
verify(len(result) == 2)
|
||||
verify(result[1] == 'BR State: running')
|
||||
|
||||
result = br1.cli('networkdiagnostic get', br2_rloc, BR_IF_ADDRS_TLV)
|
||||
verify(len(result) > 2)
|
||||
verify(result[1] == 'BR Infra-if IP6 Address List:')
|
||||
verify(result[2].startswith(' - fe80:'))
|
||||
|
||||
result = br1.cli('networkdiagnostic get', br2_rloc, BR_LOCAL_OMR_PREFIX_TLV)
|
||||
verify(len(result) == 2)
|
||||
verify(result[1].startswith('BR Local OMR Prefix: '))
|
||||
verify(result[1].split(': ')[1].strip() == br2.br_get_local_omrprefix())
|
||||
|
||||
result = br1.cli('networkdiagnostic get', br2_rloc, BR_DHCP6_PD_OMR_PREFIX_TLV)
|
||||
verify(len(result) == 2)
|
||||
verify(result[1].startswith('BR DHCPv6-PD OMR Prefix:'))
|
||||
verify(result[1].split(': ')[1].strip() == '0:0:0:0::/64')
|
||||
|
||||
result = br1.cli('networkdiagnostic get', br2_rloc, BR_LOCAL_OL_PREFIX_TLV)
|
||||
verify(len(result) == 2)
|
||||
verify(result[1].startswith('BR Local On-link Prefix: '))
|
||||
verify(result[1].split(': ')[1].strip() == br2.br_get_local_onlinkprefix())
|
||||
|
||||
result = br1.cli('networkdiagnostic get', br2_rloc, BR_FAVORED_OL_PREFIX_TLV)
|
||||
verify(len(result) == 2)
|
||||
verify(result[1].startswith('BR Favored On-link Prefix: '))
|
||||
verify(result[1].split(': ')[1].strip() == br2.br_get_favored_onlinkprefix())
|
||||
|
||||
# Disable BR3 and validate that BR1 and BR2 detect this.
|
||||
# BR3 itself should continue to detect BR1 and BR2
|
||||
|
||||
|
||||
Reference in New Issue
Block a user