[mlr] add MulticastListenersTable on BBR (#5292)

This commit adds the Multicast Listener Table for BBR:

- Implements Multicast Listener Table on BBR
  - Adds registered MAs to MulticastListenerTable
  - Reject when the table is full or the multicast address is invalid
    and return failed status
  - Respond with unsuccessful status along with failed addresses
  - Expire Listeners from MulticastListenerTable per second (using
    MinHeap for better performance)
- MLR enhancement
  - Re-register only failed multicast addresses (used to register all
    registering multicast addresses)
- Reference Device only APIs
  - Some APIs are defined for reference devices and tests.
- Add tests
  - Add unit test: test_multicast_listener_table.cpp (runs for 1.2-bbr
    only)
  - Add functional tests
This commit is contained in:
Simon Lin
2020-08-21 23:40:58 +08:00
committed by GitHub
parent ec0373c354
commit c73320ff3e
28 changed files with 2002 additions and 397 deletions
+68 -2
View File
@@ -527,13 +527,15 @@ void Interpreter::ProcessBackboneRouter(uint8_t aArgsLength, char *aArgs[])
{
unsigned long value;
VerifyOrExit((aArgsLength == 3 || aArgsLength == 4), error = OT_ERROR_INVALID_ARGS);
VerifyOrExit(aArgsLength >= 2, error = OT_ERROR_INVALID_COMMAND);
if (strcmp(aArgs[1], "dua") == 0)
{
otIp6InterfaceIdentifier *mlIid = nullptr;
otIp6InterfaceIdentifier iid;
VerifyOrExit((aArgsLength == 3 || aArgsLength == 4), error = OT_ERROR_INVALID_ARGS);
SuccessOrExit(error = ParseUnsignedLong(aArgs[2], value));
if (aArgsLength == 4)
@@ -546,6 +548,11 @@ void Interpreter::ProcessBackboneRouter(uint8_t aArgsLength, char *aArgs[])
otBackboneRouterConfigNextDuaRegistrationResponse(mInstance, mlIid, static_cast<uint8_t>(value));
ExitNow();
}
else if (strcmp(aArgs[1], "mlr") == 0)
{
error = ProcessBackboneRouterMgmtMlr(aArgsLength - 2, aArgs + 2);
ExitNow();
}
}
#endif // OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
SuccessOrExit(error = ProcessBackboneRouterLocal(aArgsLength, aArgs));
@@ -553,11 +560,70 @@ void Interpreter::ProcessBackboneRouter(uint8_t aArgsLength, char *aArgs[])
exit:
#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
AppendResult(error);
}
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
otError Interpreter::ProcessBackboneRouterMgmtMlr(uint8_t aArgsLength, char **aArgs)
{
OT_UNUSED_VARIABLE(aArgsLength);
OT_UNUSED_VARIABLE(aArgs);
otError error = OT_ERROR_INVALID_COMMAND;
VerifyOrExit(aArgsLength >= 1, OT_NOOP);
if (!strcmp(aArgs[0], "listener"))
{
if (aArgsLength == 1)
{
PrintMulticastListenersTable();
error = OT_ERROR_NONE;
}
else if (!strcmp(aArgs[1], "clear"))
{
otBackboneRouterMulticastListenerClear(mInstance);
error = OT_ERROR_NONE;
}
else if (!strcmp(aArgs[1], "add"))
{
struct otIp6Address address;
unsigned long value;
uint32_t timeout = 0;
VerifyOrExit(aArgsLength == 3 || aArgsLength == 4, error = OT_ERROR_INVALID_ARGS);
SuccessOrExit(error = otIp6AddressFromString(aArgs[2], &address));
if (aArgsLength == 4)
{
SuccessOrExit(error = ParseUnsignedLong(aArgs[3], value));
timeout = static_cast<uint32_t>(value);
}
error = otBackboneRouterMulticastListenerAdd(mInstance, &address, timeout);
}
}
exit:
return error;
}
void Interpreter::PrintMulticastListenersTable(void)
{
otBackboneRouterMulticastListenerIterator iter = OT_BACKBONE_ROUTER_MULTICAST_LISTENER_ITERATOR_INIT;
otBackboneRouterMulticastListenerInfo listenerInfo;
while (otBackboneRouterMulticastListenerGetNext(mInstance, &iter, &listenerInfo) == OT_ERROR_NONE)
{
OutputIp6Address(listenerInfo.mAddress);
OutputFormat(" %u\r\n", listenerInfo.mTimeout);
}
}
#endif // OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
otError Interpreter::ProcessBackboneRouterLocal(uint8_t aArgsLength, char *aArgs[])
{
otError error = OT_ERROR_NONE;