mirror of
https://github.com/espressif/openthread.git
synced 2026-09-24 09:57:38 +00:00
[cli] netdata show to support filtering by RLOC16 (#9969)
This commit updates the CLI `netdata show` command to allow an optional RLOC16 as input. Providing an RLOC16 filters the output to display prefix, route, and service entries associated specifically with the specified RLOC16. This is helpful for checking entries added by a specific border router. `test-011-network-data-timeout.py` is updated to validate the new CLI functionality.
This commit is contained in:
@@ -334,10 +334,12 @@ Done
|
||||
|
||||
### show
|
||||
|
||||
Usage: `netdata show [local] [-x]`
|
||||
Usage: `netdata show [local] [-x] [\<rloc16\>]`
|
||||
|
||||
Print entries in Network Data, on-mesh prefixes, external routes, services, and 6LoWPAN context information.
|
||||
|
||||
If the optional `rloc16` input is specified, prints the entries associated with the given RLOC16 only. The RLOC16 filtering can be used when `-x` or `local` are not used.
|
||||
|
||||
On-mesh prefixes are listed under `Prefixes` header:
|
||||
|
||||
- The on-mesh prefix
|
||||
@@ -406,6 +408,19 @@ Commissioning:
|
||||
Done
|
||||
```
|
||||
|
||||
Print Network Data entries from the Leader associated with `0xa00` RLOC16.
|
||||
|
||||
```bash
|
||||
> netdata show 0xa00
|
||||
Prefixes:
|
||||
fd00:dead:beef:cafe::/64 paros med a000
|
||||
Routes:
|
||||
fd00:1234:0:0::/64 s med a000
|
||||
Services:
|
||||
44970 5d fddead00beef00007bad0069ce45948504d2 s a000
|
||||
Done
|
||||
```
|
||||
|
||||
Print Network Data received from the Leader as hex-encoded TLVs.
|
||||
|
||||
```bash
|
||||
|
||||
@@ -564,7 +564,7 @@ otError NetworkData::GetNextPrefix(otNetworkDataIterator *aIterator, otBorderRou
|
||||
return error;
|
||||
}
|
||||
|
||||
void NetworkData::OutputNetworkData(bool aLocal)
|
||||
void NetworkData::OutputNetworkData(bool aLocal, uint16_t aRloc16)
|
||||
{
|
||||
otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
|
||||
otBorderRouterConfig prefix;
|
||||
@@ -577,7 +577,10 @@ void NetworkData::OutputNetworkData(bool aLocal)
|
||||
|
||||
while (GetNextPrefix(&iterator, &prefix, aLocal) == OT_ERROR_NONE)
|
||||
{
|
||||
OutputPrefix(prefix);
|
||||
if ((aRloc16 == kAnyRloc16) || (aRloc16 == prefix.mRloc16))
|
||||
{
|
||||
OutputPrefix(prefix);
|
||||
}
|
||||
}
|
||||
|
||||
OutputLine("Routes:");
|
||||
@@ -585,7 +588,10 @@ void NetworkData::OutputNetworkData(bool aLocal)
|
||||
|
||||
while (GetNextRoute(&iterator, &route, aLocal) == OT_ERROR_NONE)
|
||||
{
|
||||
OutputRoute(route);
|
||||
if ((aRloc16 == kAnyRloc16) || (aRloc16 == route.mRloc16))
|
||||
{
|
||||
OutputRoute(route);
|
||||
}
|
||||
}
|
||||
|
||||
OutputLine("Services:");
|
||||
@@ -593,10 +599,14 @@ void NetworkData::OutputNetworkData(bool aLocal)
|
||||
|
||||
while (GetNextService(&iterator, &service, aLocal) == OT_ERROR_NONE)
|
||||
{
|
||||
OutputService(service);
|
||||
if ((aRloc16 == kAnyRloc16) || (aRloc16 == service.mServerConfig.mRloc16))
|
||||
{
|
||||
OutputService(service);
|
||||
}
|
||||
}
|
||||
|
||||
VerifyOrExit(!aLocal);
|
||||
VerifyOrExit(aRloc16 == kAnyRloc16);
|
||||
|
||||
OutputLine("Contexts:");
|
||||
iterator = OT_NETWORK_DATA_ITERATOR_INIT;
|
||||
@@ -716,8 +726,16 @@ exit:
|
||||
* 08040b02174703140040fd00deadbeefcafe0504dc00330007021140
|
||||
* Done
|
||||
* @endcode
|
||||
* @cparam netdata show [@ca{-x}]
|
||||
* @code
|
||||
* netdata show 0xdc00
|
||||
* Prefixes:
|
||||
* fd00:dead:beef:cafe::/64 paros med dc00
|
||||
* Routes:
|
||||
* Services:
|
||||
* Done
|
||||
* @cparam netdata show [@ca{-x}|@ca{rloc16}]
|
||||
* * The optional `-x` argument gets Network Data as hex-encoded TLVs.
|
||||
* * The optional `rloc16` argument gets all prefix/route/service entries associated with a given RLOC16.
|
||||
* @par
|
||||
* `netdata show` from OT CLI gets full Network Data received from the Leader. This command uses several
|
||||
* API functions to combine prefixes, routes, and services, including #otNetDataGetNextOnMeshPrefix,
|
||||
@@ -774,9 +792,10 @@ exit:
|
||||
*/
|
||||
template <> otError NetworkData::Process<Cmd("show")>(Arg aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_INVALID_ARGS;
|
||||
bool local = false;
|
||||
bool binary = false;
|
||||
otError error = OT_ERROR_INVALID_ARGS;
|
||||
uint16_t rloc16 = kAnyRloc16;
|
||||
bool local = false;
|
||||
bool binary = false;
|
||||
|
||||
for (uint8_t i = 0; !aArgs[i].IsEmpty(); i++)
|
||||
{
|
||||
@@ -811,17 +830,22 @@ template <> otError NetworkData::Process<Cmd("show")>(Arg aArgs[])
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||
SuccessOrExit(error = aArgs[i].ParseAsUint16(rloc16));
|
||||
}
|
||||
}
|
||||
|
||||
if (local || binary)
|
||||
{
|
||||
VerifyOrExit(rloc16 == kAnyRloc16, error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
|
||||
if (binary)
|
||||
{
|
||||
error = OutputBinary(local);
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputNetworkData(local);
|
||||
OutputNetworkData(local, rloc16);
|
||||
error = OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
|
||||
@@ -130,6 +130,8 @@ public:
|
||||
private:
|
||||
using Command = CommandEntry<NetworkData>;
|
||||
|
||||
static constexpr uint16_t kAnyRloc16 = 0xffff;
|
||||
|
||||
template <CommandId kCommandId> otError Process(Arg aArgs[]);
|
||||
|
||||
otError GetNextPrefix(otNetworkDataIterator *aIterator, otBorderRouterConfig *aConfig, bool aLocal);
|
||||
@@ -137,7 +139,7 @@ private:
|
||||
otError GetNextService(otNetworkDataIterator *aIterator, otServiceConfig *aConfig, bool aLocal);
|
||||
|
||||
otError OutputBinary(bool aLocal);
|
||||
void OutputNetworkData(bool aLocal);
|
||||
void OutputNetworkData(bool aLocal, uint16_t aRloc16);
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL
|
||||
static void HandleNetdataFull(void *aContext) { static_cast<NetworkData *>(aContext)->HandleNetdataFull(); }
|
||||
|
||||
+11
-7
@@ -398,19 +398,23 @@ class Node(object):
|
||||
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
# netdata
|
||||
|
||||
def get_netdata(self):
|
||||
outputs = self.cli('netdata show')
|
||||
def get_netdata(self, rloc16=None):
|
||||
outputs = self.cli('netdata show', rloc16)
|
||||
outputs = [line.strip() for line in outputs]
|
||||
routes_index = outputs.index('Routes:')
|
||||
services_index = outputs.index('Services:')
|
||||
contexts_index = outputs.index('Contexts:')
|
||||
commissioning_index = outputs.index('Commissioning:')
|
||||
if rloc16 is None:
|
||||
contexts_index = outputs.index('Contexts:')
|
||||
commissioning_index = outputs.index('Commissioning:')
|
||||
result = {}
|
||||
result['prefixes'] = outputs[1:routes_index]
|
||||
result['routes'] = outputs[routes_index + 1:services_index]
|
||||
result['services'] = outputs[services_index + 1:contexts_index]
|
||||
result['contexts'] = outputs[contexts_index + 1:commissioning_index]
|
||||
result['commissioning'] = outputs[commissioning_index + 1:]
|
||||
if rloc16 is None:
|
||||
result['services'] = outputs[services_index + 1:contexts_index]
|
||||
result['contexts'] = outputs[contexts_index + 1:commissioning_index]
|
||||
result['commissioning'] = outputs[commissioning_index + 1:]
|
||||
else:
|
||||
result['services'] = outputs[services_index + 1:]
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@@ -89,11 +89,6 @@ nodes = [r1, r2, c2]
|
||||
# -----------------------------------------------------------------------------------------------------------------------
|
||||
# Test Implementation
|
||||
|
||||
common_prefix = 'fd00:cafe::'
|
||||
prefix1 = 'fd00:1::'
|
||||
prefix2 = 'fd00:2::'
|
||||
prefix3 = 'fd00:3::'
|
||||
|
||||
# Each node adds its own prefix.
|
||||
r1.add_prefix('fd00:1::/64', 'paros', 'med')
|
||||
r2.add_prefix('fd00:2::/64', 'paros', 'med')
|
||||
@@ -104,6 +99,9 @@ r1.add_prefix('fd00:abba::/64', 'paros', 'high')
|
||||
r2.add_prefix('fd00:abba::/64', 'paros', 'med')
|
||||
c2.add_prefix('fd00:abba::/64', 'paros', 'low')
|
||||
|
||||
r1.add_route('fd00:cafe::/64', 's', 'med')
|
||||
r2.add_route('fd00:cafe::/64', 's', 'med')
|
||||
|
||||
r1.register_netdata()
|
||||
r2.register_netdata()
|
||||
c2.register_netdata()
|
||||
@@ -112,12 +110,19 @@ c2.register_netdata()
|
||||
def check_netdata_on_all_nodes():
|
||||
for node in nodes:
|
||||
netdata = node.get_netdata()
|
||||
prefixes = netdata['prefixes']
|
||||
verify(len(prefixes) == 6)
|
||||
verify(len(netdata['prefixes']) == 6)
|
||||
verify(len(netdata['routes']) == 2)
|
||||
|
||||
|
||||
verify_within(check_netdata_on_all_nodes, 10)
|
||||
|
||||
# Check netdata filtering for r1 entries only.
|
||||
|
||||
r1_rloc = int(r1.get_rloc16(), 16)
|
||||
netdata = r1.get_netdata(r1_rloc)
|
||||
verify(len(netdata['prefixes']) == 2)
|
||||
verify(len(netdata['routes']) == 1)
|
||||
|
||||
# Remove `r2`. This should trigger all the prefixes added by it or its
|
||||
# child to timeout and be removed.
|
||||
|
||||
@@ -127,8 +132,11 @@ r2.interface_down()
|
||||
|
||||
def check_netdata_on_r1():
|
||||
netdata = r1.get_netdata()
|
||||
prefixes = netdata['prefixes']
|
||||
verify(len(prefixes) == 2)
|
||||
verify(len(netdata['prefixes']) == 2)
|
||||
verify(len(netdata['routes']) == 1)
|
||||
netdata = r1.get_netdata(r1_rloc)
|
||||
verify(len(netdata['prefixes']) == 2)
|
||||
verify(len(netdata['routes']) == 1)
|
||||
|
||||
|
||||
verify_within(check_netdata_on_r1, 120)
|
||||
|
||||
Reference in New Issue
Block a user