mirror of
https://github.com/espressif/openthread.git
synced 2026-08-15 15:17:46 +00:00
[bbr] remove Backbone Router DUA ND Proxying feature (#13136)
This commit removes all code, configurations, APIs, and tests related to the OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE feature. Specifically, the following changes were made: - Removed DUA ND Proxying Backbone Router configuration option and the related OPENTHREAD_CONFIG_NDPROXY_TABLE_ENTRY_NUM definition. - Removed CLI commands: `bbr mgmt dua` and the proactive backbone notification fake command `/b/ba`. - Removed NdProxyTable and bbr_manager DUA ND Proxying implementation. - Removed public/internal APIs for ND Proxying and proactive backbone notifications. - Deleted ndproxy_table source files and unit tests. - Simplified CMake and GN build files to remove deleted targets.
This commit is contained in:
@@ -170,7 +170,6 @@ ot_option(OT_ANDROID_NDK OPENTHREAD_CONFIG_ANDROID_NDK_ENABLE "enable android ND
|
||||
ot_option(OT_ANYCAST_LOCATOR OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_ENABLE "anycast locator")
|
||||
ot_option(OT_ASSERT OPENTHREAD_CONFIG_ASSERT_ENABLE "assert function OT_ASSERT()")
|
||||
ot_option(OT_BACKBONE_ROUTER OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE "backbone router functionality")
|
||||
ot_option(OT_BACKBONE_ROUTER_DUA_NDPROXYING OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE "BBR DUA ND Proxy")
|
||||
ot_option(OT_BACKBONE_ROUTER_MULTICAST_ROUTING OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE "BBR MR")
|
||||
ot_option(OT_BLE_TCAT OPENTHREAD_CONFIG_BLE_TCAT_ENABLE "Ble based thread commissioning")
|
||||
ot_option(OT_BORDER_ADMITTER OPENTHREAD_CONFIG_BORDER_AGENT_ADMITTER_ENABLE "border agent admitter")
|
||||
|
||||
@@ -186,23 +186,6 @@ void otBackboneRouterSetRegistrationJitter(otInstance *aInstance, uint8_t aJitte
|
||||
*/
|
||||
otError otBackboneRouterGetDomainPrefix(otInstance *aInstance, otBorderRouterConfig *aConfig);
|
||||
|
||||
/**
|
||||
* Configures response status for next DUA registration.
|
||||
*
|
||||
* Note: available only when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled.
|
||||
* Only used for test and certification.
|
||||
*
|
||||
* TODO: (DUA) support coap error code and corresponding process for certification purpose.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aMlIid A pointer to the Mesh Local IID. If NULL, respond with @p aStatus for any
|
||||
* coming DUA.req, otherwise only respond the one with matching @p aMlIid.
|
||||
* @param[in] aStatus The status to respond.
|
||||
*/
|
||||
void otBackboneRouterConfigNextDuaRegistrationResponse(otInstance *aInstance,
|
||||
const otIp6InterfaceIdentifier *aMlIid,
|
||||
uint8_t aStatus);
|
||||
|
||||
/**
|
||||
* Configures the response status for the next Multicast Listener Registration.
|
||||
*
|
||||
@@ -317,64 +300,6 @@ otError otBackboneRouterMulticastListenerGetNext(otInstance
|
||||
otBackboneRouterMulticastListenerIterator *aIterator,
|
||||
otBackboneRouterMulticastListenerInfo *aListenerInfo);
|
||||
|
||||
/**
|
||||
* Represents the ND Proxy events.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
OT_BACKBONE_ROUTER_NDPROXY_ADDED = 0, ///< ND Proxy was added.
|
||||
OT_BACKBONE_ROUTER_NDPROXY_REMOVED = 1, ///< ND Proxy was removed.
|
||||
OT_BACKBONE_ROUTER_NDPROXY_RENEWED = 2, ///< ND Proxy was renewed.
|
||||
OT_BACKBONE_ROUTER_NDPROXY_CLEARED = 3, ///< All ND Proxies were cleared.
|
||||
} otBackboneRouterNdProxyEvent;
|
||||
|
||||
/**
|
||||
* Pointer is called whenever the Nd Proxy changed.
|
||||
*
|
||||
* @param[in] aContext The user context pointer.
|
||||
* @param[in] aEvent The ND Proxy event.
|
||||
* @param[in] aDua The Domain Unicast Address of the ND Proxy, or NULL if @p aEvent is
|
||||
* `OT_BACKBONE_ROUTER_NDPROXY_CLEARED`.
|
||||
*/
|
||||
typedef void (*otBackboneRouterNdProxyCallback)(void *aContext,
|
||||
otBackboneRouterNdProxyEvent aEvent,
|
||||
const otIp6Address *aDua);
|
||||
|
||||
/**
|
||||
* Sets the Backbone Router ND Proxy callback.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aCallback A pointer to the ND Proxy callback.
|
||||
* @param[in] aContext A user context pointer.
|
||||
*/
|
||||
void otBackboneRouterSetNdProxyCallback(otInstance *aInstance,
|
||||
otBackboneRouterNdProxyCallback aCallback,
|
||||
void *aContext);
|
||||
|
||||
/**
|
||||
* Represents the Backbone Router ND Proxy info.
|
||||
*/
|
||||
typedef struct otBackboneRouterNdProxyInfo
|
||||
{
|
||||
otIp6InterfaceIdentifier *mMeshLocalIid; ///< Mesh-local IID
|
||||
uint32_t mTimeSinceLastTransaction; ///< Time since last transaction (Seconds)
|
||||
uint16_t mRloc16; ///< RLOC16
|
||||
} otBackboneRouterNdProxyInfo;
|
||||
|
||||
/**
|
||||
* Gets the Backbone Router ND Proxy info.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aDua The Domain Unicast Address.
|
||||
* @param[out] aNdProxyInfo A pointer to the ND Proxy info.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully got the ND Proxy info.
|
||||
* @retval OT_ERROR_NOT_FOUND Failed to find the Domain Unicast Address in the ND Proxy table.
|
||||
*/
|
||||
otError otBackboneRouterGetNdProxyInfo(otInstance *aInstance,
|
||||
const otIp6Address *aDua,
|
||||
otBackboneRouterNdProxyInfo *aNdProxyInfo);
|
||||
|
||||
/**
|
||||
* Represents the Domain Prefix events.
|
||||
*/
|
||||
|
||||
@@ -52,7 +52,7 @@ extern "C" {
|
||||
*
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (597)
|
||||
#define OPENTHREAD_API_VERSION (598)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -1072,24 +1072,6 @@ void otThreadSendAddressNotification(otInstance *aInstance,
|
||||
otIp6Address *aTarget,
|
||||
otIp6InterfaceIdentifier *aMlIid);
|
||||
|
||||
/**
|
||||
* Sends a Proactive Backbone Notification (PRO_BB.ntf) message on the Backbone link.
|
||||
*
|
||||
* Is only available when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aTarget The target address of the PRO_BB.ntf message.
|
||||
* @param[in] aMlIid The ML-IID of the PRO_BB.ntf message.
|
||||
* @param[in] aTimeSinceLastTransaction Time since last transaction (in seconds).
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully sent PRO_BB.ntf on backbone link.
|
||||
* @retval OT_ERROR_NO_BUFS If insufficient message buffers available.
|
||||
*/
|
||||
otError otThreadSendProactiveBackboneNotification(otInstance *aInstance,
|
||||
otIp6Address *aTarget,
|
||||
otIp6InterfaceIdentifier *aMlIid,
|
||||
uint32_t aTimeSinceLastTransaction);
|
||||
|
||||
/**
|
||||
* Notifies other nodes in the network (if any) and then stops Thread protocol operation.
|
||||
*
|
||||
|
||||
@@ -176,14 +176,6 @@ build_all_features()
|
||||
CFLAGS="${cppflags[*]} ${CFLAGS}" CXXFLAGS="${cppflags[*]} ${CXXFLAGS}" \
|
||||
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_DUA=ON -DOT_FULL_LOGS=ON
|
||||
|
||||
# Build Thread 1.4 Backbone Router without DUA ND Proxying
|
||||
reset_source
|
||||
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_BACKBONE_ROUTER_DUA_NDPROXYING=OFF
|
||||
|
||||
# Build Thread 1.4 Backbone Router without Multicast Routing
|
||||
reset_source
|
||||
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_BACKBONE_ROUTER_MULTICAST_ROUTING=OFF
|
||||
|
||||
# Build with Vendor Extension
|
||||
reset_source
|
||||
"$(dirname "$0")"/cmake-build simulation \
|
||||
|
||||
@@ -3215,20 +3215,6 @@ template <> otError Interpreter::Process<Cmd("fake")>(Arg aArgs[])
|
||||
SuccessOrExit(error = aArgs[3].ParseAsHexString(mlIid.mFields.m8));
|
||||
otThreadSendAddressNotification(GetInstancePtr(), &destination, &target, &mlIid);
|
||||
}
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
else if (aArgs[0] == "/b/ba")
|
||||
{
|
||||
otIp6Address target;
|
||||
otIp6InterfaceIdentifier mlIid;
|
||||
uint32_t timeSinceLastTransaction;
|
||||
|
||||
SuccessOrExit(error = aArgs[1].ParseAsIp6Address(target));
|
||||
SuccessOrExit(error = aArgs[2].ParseAsHexString(mlIid.mFields.m8));
|
||||
SuccessOrExit(error = aArgs[3].ParseAsUint32(timeSinceLastTransaction));
|
||||
|
||||
error = otThreadSendProactiveBackboneNotification(GetInstancePtr(), &target, &mlIid, timeSinceLastTransaction);
|
||||
}
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return error;
|
||||
|
||||
@@ -174,55 +174,6 @@ template <> otError Bbr::Process<Cmd("mgmt")>(Arg aArgs[])
|
||||
ExitNow(error = OT_ERROR_INVALID_COMMAND);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE && OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
/**
|
||||
* @cli bbr mgmt dua
|
||||
* @code
|
||||
* bbr mgmt dua 1 2f7c235e5025a2fd
|
||||
* Done
|
||||
* @endcode
|
||||
* @code
|
||||
* bbr mgmt dua 160
|
||||
* Done
|
||||
* @endcode
|
||||
* @cparam bbr mgmt dua @ca{status|coap-code} [@ca{meshLocalIid}]
|
||||
* For `status` or `coap-code`, use:
|
||||
* * 0: ST_DUA_SUCCESS
|
||||
* * 1: ST_DUA_REREGISTER
|
||||
* * 2: ST_DUA_INVALID
|
||||
* * 3: ST_DUA_DUPLICATE
|
||||
* * 4: ST_DUA_NO_RESOURCES
|
||||
* * 5: ST_DUA_BBR_NOT_PRIMARY
|
||||
* * 6: ST_DUA_GENERAL_FAILURE
|
||||
* * 160: COAP code 5.00
|
||||
* @par
|
||||
* With the `meshLocalIid` included, this command configures the response status
|
||||
* for the next DUA registration. Without `meshLocalIid`, respond to the next
|
||||
* DUA.req with the specified `status` or `coap-code`.
|
||||
* @par
|
||||
* Available when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled.
|
||||
* @sa otBackboneRouterConfigNextDuaRegistrationResponse
|
||||
*/
|
||||
if (aArgs[0] == "dua")
|
||||
{
|
||||
uint8_t status;
|
||||
otIp6InterfaceIdentifier *mlIid = nullptr;
|
||||
otIp6InterfaceIdentifier iid;
|
||||
|
||||
SuccessOrExit(error = aArgs[1].ParseAsUint8(status));
|
||||
|
||||
if (!aArgs[2].IsEmpty())
|
||||
{
|
||||
SuccessOrExit(error = aArgs[2].ParseAsHexString(iid.mFields.m8));
|
||||
mlIid = &iid;
|
||||
VerifyOrExit(aArgs[3].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
|
||||
otBackboneRouterConfigNextDuaRegistrationResponse(GetInstancePtr(), mlIid, status);
|
||||
ExitNow();
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE && OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
if (aArgs[0] == "mlr")
|
||||
{
|
||||
|
||||
@@ -396,8 +396,6 @@ openthread_core_files = [
|
||||
"backbone_router/bbr_manager.hpp",
|
||||
"backbone_router/multicast_listeners_table.cpp",
|
||||
"backbone_router/multicast_listeners_table.hpp",
|
||||
"backbone_router/ndproxy_table.cpp",
|
||||
"backbone_router/ndproxy_table.hpp",
|
||||
"border_router/br_log.cpp",
|
||||
"border_router/br_log.hpp",
|
||||
"border_router/br_tracker.cpp",
|
||||
|
||||
@@ -101,7 +101,6 @@ set(COMMON_SOURCES
|
||||
backbone_router/bbr_local.cpp
|
||||
backbone_router/bbr_manager.cpp
|
||||
backbone_router/multicast_listeners_table.cpp
|
||||
backbone_router/ndproxy_table.cpp
|
||||
border_router/br_log.cpp
|
||||
border_router/br_tracker.cpp
|
||||
border_router/br_types.cpp
|
||||
|
||||
@@ -94,25 +94,6 @@ void otBackboneRouterSetDomainPrefixCallback(otInstance
|
||||
return AsCoreType(aInstance).Get<BackboneRouter::Local>().SetDomainPrefixCallback(aCallback, aContext);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
void otBackboneRouterSetNdProxyCallback(otInstance *aInstance,
|
||||
otBackboneRouterNdProxyCallback aCallback,
|
||||
void *aContext)
|
||||
{
|
||||
AsCoreType(aInstance).Get<BackboneRouter::NdProxyTable>().SetCallback(aCallback, aContext);
|
||||
}
|
||||
|
||||
otError otBackboneRouterGetNdProxyInfo(otInstance *aInstance,
|
||||
const otIp6Address *aDua,
|
||||
otBackboneRouterNdProxyInfo *aNdProxyInfo)
|
||||
{
|
||||
AssertPointerIsNotNull(aNdProxyInfo);
|
||||
|
||||
return AsCoreType(aInstance).Get<BackboneRouter::NdProxyTable>().GetInfo(
|
||||
reinterpret_cast<const Ip6::Address &>(*aDua), *aNdProxyInfo);
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
void otBackboneRouterSetMulticastListenerCallback(otInstance *aInstance,
|
||||
otBackboneRouterMulticastListenerCallback aCallback,
|
||||
@@ -133,15 +114,6 @@ otError otBackboneRouterMulticastListenerGetNext(otInstance
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
void otBackboneRouterConfigNextDuaRegistrationResponse(otInstance *aInstance,
|
||||
const otIp6InterfaceIdentifier *aMlIid,
|
||||
uint8_t aStatus)
|
||||
{
|
||||
AsCoreType(aInstance).Get<BackboneRouter::Manager>().ConfigNextDuaRegistrationResponse(AsCoreTypePtr(aMlIid),
|
||||
aStatus);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
void otBackboneRouterConfigNextMulticastListenerRegistrationResponse(otInstance *aInstance, uint8_t aStatus)
|
||||
|
||||
@@ -344,17 +344,6 @@ void otThreadSendAddressNotification(otInstance *aInstance,
|
||||
nullptr, AsCoreType(aDestination));
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
otError otThreadSendProactiveBackboneNotification(otInstance *aInstance,
|
||||
otIp6Address *aTarget,
|
||||
otIp6InterfaceIdentifier *aMlIid,
|
||||
uint32_t aTimeSinceLastTransaction)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<BackboneRouter::Manager>().SendProactiveBackboneNotification(
|
||||
AsCoreType(aTarget), AsCoreType(aMlIid), aTimeSinceLastTransaction);
|
||||
}
|
||||
#endif
|
||||
|
||||
void otThreadSetCcmEnabled(otInstance *aInstance, bool aEnabled)
|
||||
{
|
||||
AsCoreType(aInstance).Get<Mle::Mle>().SetCcmEnabled(aEnabled);
|
||||
|
||||
@@ -87,11 +87,6 @@ bool BackboneTmfAgent::HandleResource(const char *aUriPath, ot::Coap::Msg &aMsg)
|
||||
|
||||
switch (uri)
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
Case(kUriBackboneQuery, Manager);
|
||||
Case(kUriBackboneAnswer, Manager);
|
||||
#endif
|
||||
|
||||
default:
|
||||
didHandle = false;
|
||||
break;
|
||||
|
||||
@@ -257,9 +257,6 @@ void Leader::UpdateDomainPrefixConfig(void)
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
Get<Local>().HandleDomainPrefixUpdate(event);
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
Get<NdProxyTable>().HandleDomainPrefixUpdate(event);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_DUA_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE)
|
||||
|
||||
@@ -45,28 +45,15 @@ RegisterLogModule("BbrManager");
|
||||
|
||||
Manager::Manager(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
, mNdProxyTable(aInstance)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
, mMulticastListenersTable(aInstance)
|
||||
#endif
|
||||
, mTimer(aInstance)
|
||||
, mBackboneTmfAgent(aInstance)
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
, mDuaResponseStatus(kDuaSuccess)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE && OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
, mMlrResponseStatus(Mlr::kStatusSuccess)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
, mDuaResponseIsSpecified(false)
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
, mMlrResponseIsSpecified(false)
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
@@ -108,14 +95,7 @@ void Manager::HandleNotifierEvents(Events aEvents)
|
||||
}
|
||||
}
|
||||
|
||||
void Manager::HandleTimer(void)
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
mNdProxyTable.HandleTimer();
|
||||
#endif
|
||||
|
||||
mTimer.Start(kTimerInterval);
|
||||
}
|
||||
void Manager::HandleTimer(void) { mTimer.Start(kTimerInterval); }
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
template <> void Manager::HandleTmf<kUriMlr>(Coap::Msg &aMsg)
|
||||
@@ -328,132 +308,7 @@ exit:
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
|
||||
template <> void Manager::HandleTmf<kUriDuaRegistrationRequest>(Coap::Msg &aMsg)
|
||||
{
|
||||
VerifyOrExit(Get<Local>().IsEnabled());
|
||||
HandleDuaRegistration(aMsg);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Manager::HandleDuaRegistration(const Coap::Msg &aMsg)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
DuaStatus status = kDuaSuccess;
|
||||
bool isPrimary = Get<Local>().IsPrimary();
|
||||
uint32_t lastTransactionTime;
|
||||
bool hasLastTransactionTime;
|
||||
Ip6::Address target;
|
||||
Ip6::InterfaceIdentifier meshLocalIid;
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
Coap::Code duaRespCoapCode = Coap::kCodeEmpty;
|
||||
#endif
|
||||
|
||||
VerifyOrExit(aMsg.mMessageInfo.GetPeerAddr().GetIid().IsRoutingLocator(), error = kErrorDrop);
|
||||
VerifyOrExit(aMsg.IsConfirmable(), error = kErrorParse);
|
||||
|
||||
SuccessOrExit(error = Tlv::Find<ThreadTargetTlv>(aMsg.mMessage, target));
|
||||
SuccessOrExit(error = Tlv::Find<ThreadMeshLocalEidTlv>(aMsg.mMessage, meshLocalIid));
|
||||
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
if (mDuaResponseIsSpecified && (mDuaResponseTargetMlIid.IsUnspecified() || mDuaResponseTargetMlIid == meshLocalIid))
|
||||
{
|
||||
mDuaResponseIsSpecified = false;
|
||||
if (mDuaResponseStatus >= Coap::kCodeResponseMin)
|
||||
{
|
||||
duaRespCoapCode = static_cast<Coap::Code>(mDuaResponseStatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = static_cast<DuaStatus>(mDuaResponseStatus);
|
||||
}
|
||||
ExitNow();
|
||||
}
|
||||
#endif
|
||||
|
||||
VerifyOrExit(isPrimary, status = kDuaNotPrimary);
|
||||
VerifyOrExit(Get<Leader>().HasDomainPrefix(), status = kDuaGeneralFailure);
|
||||
VerifyOrExit(Get<Leader>().IsDomainUnicast(target), status = kDuaInvalid);
|
||||
|
||||
hasLastTransactionTime =
|
||||
(Tlv::Find<ThreadLastTransactionTimeTlv>(aMsg.mMessage, lastTransactionTime) == kErrorNone);
|
||||
|
||||
switch (mNdProxyTable.Register(target.GetIid(), meshLocalIid, aMsg.mMessageInfo.GetPeerAddr().GetIid().GetLocator(),
|
||||
hasLastTransactionTime ? &lastTransactionTime : nullptr))
|
||||
{
|
||||
case kErrorNone:
|
||||
// TODO: update its EID-to-RLOC Map Cache based on the pair {DUA, RLOC16-source} which is gleaned from the
|
||||
// DUA.req packet according to Thread Spec. 5.23.3.6.2
|
||||
break;
|
||||
case kErrorDuplicated:
|
||||
status = kDuaDuplicate;
|
||||
break;
|
||||
case kErrorNoBufs:
|
||||
status = kDuaNoResources;
|
||||
break;
|
||||
default:
|
||||
status = kDuaGeneralFailure;
|
||||
break;
|
||||
}
|
||||
|
||||
exit:
|
||||
LogInfo("Received DUA.req on %s: %s", (isPrimary ? "PBBR" : "SBBR"), ErrorToString(error));
|
||||
|
||||
if (error == kErrorNone)
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
if (duaRespCoapCode != Coap::kCodeEmpty)
|
||||
{
|
||||
IgnoreError(Get<Tmf::Agent>().SendAckResponse(aMsg, duaRespCoapCode));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
SendDuaRegistrationResponse(aMsg, target, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Manager::SendDuaRegistrationResponse(const Coap::Msg &aMsg, const Ip6::Address &aTarget, DuaStatus aStatus)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Coap::Message *message;
|
||||
|
||||
message = Get<Tmf::Agent>().AllocateAndInitResponseFor(aMsg.mMessage);
|
||||
VerifyOrExit(message != nullptr, error = kErrorNoBufs);
|
||||
|
||||
SuccessOrExit(Tlv::Append<ThreadStatusTlv>(*message, aStatus));
|
||||
SuccessOrExit(Tlv::Append<ThreadTargetTlv>(*message, aTarget));
|
||||
|
||||
SuccessOrExit(error = Get<Tmf::Agent>().SendMessage(*message, aMsg.mMessageInfo));
|
||||
|
||||
exit:
|
||||
FreeMessageOnError(message, error);
|
||||
LogInfo("Sent DUA.rsp for DUA %s, status %d %s", aTarget.ToString().AsCString(), aStatus, ErrorToString(error));
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
void Manager::ConfigNextDuaRegistrationResponse(const Ip6::InterfaceIdentifier *aMlIid, uint8_t aStatus)
|
||||
{
|
||||
mDuaResponseIsSpecified = true;
|
||||
|
||||
if (aMlIid)
|
||||
{
|
||||
mDuaResponseTargetMlIid = *aMlIid;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDuaResponseTargetMlIid.Clear();
|
||||
}
|
||||
|
||||
mDuaResponseStatus = aStatus;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
void Manager::ConfigNextMulticastListenerRegistrationResponse(Mlr::Status aStatus)
|
||||
@@ -464,272 +319,6 @@ void Manager::ConfigNextMulticastListenerRegistrationResponse(Mlr::Status aStatu
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
NdProxyTable &Manager::GetNdProxyTable(void) { return mNdProxyTable; }
|
||||
|
||||
bool Manager::ShouldForwardDuaToBackbone(const Ip6::Address &aAddress)
|
||||
{
|
||||
bool forwardToBackbone = false;
|
||||
|
||||
VerifyOrExit(Get<Local>().IsPrimary());
|
||||
VerifyOrExit(Get<Leader>().IsDomainUnicast(aAddress));
|
||||
|
||||
// Do not forward to Backbone if the DUA is registered on PBBR
|
||||
VerifyOrExit(!mNdProxyTable.IsRegistered(aAddress.GetIid()));
|
||||
// Do not forward to Backbone if the DUA belongs to a MTD Child (which may have failed in DUA registration)
|
||||
VerifyOrExit(Get<NeighborTable>().FindNeighbor(aAddress) == nullptr);
|
||||
// Forward to Backbone only if the DUA is resolved to the PBBR's RLOC16
|
||||
VerifyOrExit(Get<AddressResolver>().LookUp(aAddress) == Get<Mle::Mle>().GetRloc16());
|
||||
|
||||
forwardToBackbone = true;
|
||||
|
||||
exit:
|
||||
return forwardToBackbone;
|
||||
}
|
||||
|
||||
Error Manager::SendBackboneQuery(const Ip6::Address &aDua, uint16_t aRloc16)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Coap::Message *message = nullptr;
|
||||
Ip6::MessageInfo messageInfo;
|
||||
|
||||
VerifyOrExit(Get<Local>().IsPrimary(), error = kErrorInvalidState);
|
||||
|
||||
message = mBackboneTmfAgent.AllocateAndInitPriorityNonConfirmablePostMessage(kUriBackboneQuery);
|
||||
VerifyOrExit(message != nullptr, error = kErrorNoBufs);
|
||||
|
||||
SuccessOrExit(error = Tlv::Append<ThreadTargetTlv>(*message, aDua));
|
||||
|
||||
if (aRloc16 != Mle::kInvalidRloc16)
|
||||
{
|
||||
SuccessOrExit(error = Tlv::Append<ThreadRloc16Tlv>(*message, aRloc16));
|
||||
}
|
||||
|
||||
messageInfo.SetPeerAddr(Get<Local>().GetAllDomainBackboneRoutersAddress());
|
||||
messageInfo.SetPeerPort(BackboneRouter::kBackboneUdpPort);
|
||||
|
||||
messageInfo.SetHopLimit(kDefaultHoplimit);
|
||||
messageInfo.SetIsHostInterface(true);
|
||||
|
||||
error = mBackboneTmfAgent.SendMessage(*message, messageInfo);
|
||||
|
||||
exit:
|
||||
LogInfo("SendBackboneQuery for %s (rloc16=%04x): %s", aDua.ToString().AsCString(), aRloc16, ErrorToString(error));
|
||||
FreeMessageOnError(message, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> void Manager::HandleTmf<kUriBackboneQuery>(Coap::Msg &aMsg)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Ip6::Address dua;
|
||||
uint16_t rloc16 = Mle::kInvalidRloc16;
|
||||
NdProxyTable::NdProxy *ndProxy;
|
||||
|
||||
VerifyOrExit(aMsg.mMessageInfo.IsHostInterface(), error = kErrorDrop);
|
||||
|
||||
VerifyOrExit(Get<Local>().IsPrimary(), error = kErrorInvalidState);
|
||||
VerifyOrExit(aMsg.IsNonConfirmable(), error = kErrorParse);
|
||||
|
||||
SuccessOrExit(error = Tlv::Find<ThreadTargetTlv>(aMsg.mMessage, dua));
|
||||
|
||||
error = Tlv::Find<ThreadRloc16Tlv>(aMsg.mMessage, rloc16);
|
||||
VerifyOrExit(error == kErrorNone || error == kErrorNotFound);
|
||||
|
||||
LogInfo("Received BB.qry from %s for %s (rloc16=%04x)", aMsg.mMessageInfo.GetPeerAddr().ToString().AsCString(),
|
||||
dua.ToString().AsCString(), rloc16);
|
||||
|
||||
ndProxy = mNdProxyTable.ResolveDua(dua);
|
||||
VerifyOrExit(ndProxy != nullptr && !ndProxy->GetDadFlag(), error = kErrorNotFound);
|
||||
|
||||
error = SendBackboneAnswer(aMsg.mMessageInfo, dua, rloc16, *ndProxy);
|
||||
|
||||
exit:
|
||||
LogInfo("HandleBackboneQuery: %s", ErrorToString(error));
|
||||
}
|
||||
|
||||
template <> void Manager::HandleTmf<kUriBackboneAnswer>(Coap::Msg &aMsg)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
bool proactive;
|
||||
Ip6::Address dua;
|
||||
Ip6::InterfaceIdentifier meshLocalIid;
|
||||
OffsetRange offsetRange;
|
||||
uint32_t timeSinceLastTransaction;
|
||||
uint16_t srcRloc16 = Mle::kInvalidRloc16;
|
||||
|
||||
VerifyOrExit(aMsg.mMessageInfo.IsHostInterface(), error = kErrorDrop);
|
||||
|
||||
VerifyOrExit(Get<Local>().IsPrimary(), error = kErrorInvalidState);
|
||||
|
||||
proactive = !aMsg.IsConfirmable();
|
||||
|
||||
SuccessOrExit(error = Tlv::Find<ThreadTargetTlv>(aMsg.mMessage, dua));
|
||||
SuccessOrExit(error = Tlv::Find<ThreadMeshLocalEidTlv>(aMsg.mMessage, meshLocalIid));
|
||||
SuccessOrExit(error = Tlv::Find<ThreadLastTransactionTimeTlv>(aMsg.mMessage, timeSinceLastTransaction));
|
||||
SuccessOrExit(error = Tlv::FindTlvValueOffsetRange(aMsg.mMessage, ThreadTlv::kNetworkName, offsetRange));
|
||||
|
||||
error = Tlv::Find<ThreadRloc16Tlv>(aMsg.mMessage, srcRloc16);
|
||||
VerifyOrExit(error == kErrorNone || error == kErrorNotFound);
|
||||
|
||||
if (proactive)
|
||||
{
|
||||
HandleProactiveBackboneNotification(dua, meshLocalIid, timeSinceLastTransaction);
|
||||
}
|
||||
else if (srcRloc16 == Mle::kInvalidRloc16)
|
||||
{
|
||||
HandleDadBackboneAnswer(dua, meshLocalIid);
|
||||
}
|
||||
else
|
||||
{
|
||||
HandleExtendedBackboneAnswer(dua, meshLocalIid, timeSinceLastTransaction, srcRloc16);
|
||||
}
|
||||
|
||||
SuccessOrExit(error = mBackboneTmfAgent.SendAckResponse(aMsg));
|
||||
|
||||
exit:
|
||||
LogInfo("HandleBackboneAnswer: %s", ErrorToString(error));
|
||||
}
|
||||
|
||||
Error Manager::SendProactiveBackboneNotification(const Ip6::Address &aDua,
|
||||
const Ip6::InterfaceIdentifier &aMeshLocalIid,
|
||||
uint32_t aTimeSinceLastTransaction)
|
||||
{
|
||||
return SendBackboneAnswer(Get<Local>().GetAllDomainBackboneRoutersAddress(), aDua, aMeshLocalIid,
|
||||
aTimeSinceLastTransaction, Mle::kInvalidRloc16);
|
||||
}
|
||||
|
||||
Error Manager::SendBackboneAnswer(const Ip6::MessageInfo &aQueryMessageInfo,
|
||||
const Ip6::Address &aDua,
|
||||
uint16_t aSrcRloc16,
|
||||
const NdProxyTable::NdProxy &aNdProxy)
|
||||
{
|
||||
return SendBackboneAnswer(aQueryMessageInfo.GetPeerAddr(), aDua, aNdProxy.GetMeshLocalIid(),
|
||||
aNdProxy.GetTimeSinceLastTransaction(), aSrcRloc16);
|
||||
}
|
||||
|
||||
Error Manager::SendBackboneAnswer(const Ip6::Address &aDstAddr,
|
||||
const Ip6::Address &aDua,
|
||||
const Ip6::InterfaceIdentifier &aMeshLocalIid,
|
||||
uint32_t aTimeSinceLastTransaction,
|
||||
uint16_t aSrcRloc16)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Coap::Message *message = nullptr;
|
||||
Ip6::MessageInfo messageInfo;
|
||||
|
||||
message = mBackboneTmfAgent.AllocateAndInitPriorityPostMessageTo(kUriBackboneAnswer, aDstAddr);
|
||||
VerifyOrExit(message != nullptr, error = kErrorNoBufs);
|
||||
|
||||
SuccessOrExit(error = Tlv::Append<ThreadTargetTlv>(*message, aDua));
|
||||
|
||||
SuccessOrExit(error = Tlv::Append<ThreadMeshLocalEidTlv>(*message, aMeshLocalIid));
|
||||
|
||||
SuccessOrExit(error = Tlv::Append<ThreadLastTransactionTimeTlv>(*message, aTimeSinceLastTransaction));
|
||||
|
||||
SuccessOrExit(error = Tlv::Append<ThreadNetworkNameTlv>(
|
||||
*message, Get<MeshCoP::NetworkIdentity>().GetNetworkName().GetAsCString()));
|
||||
|
||||
if (aSrcRloc16 != Mle::kInvalidRloc16)
|
||||
{
|
||||
SuccessOrExit(Tlv::Append<ThreadRloc16Tlv>(*message, aSrcRloc16));
|
||||
}
|
||||
|
||||
messageInfo.SetPeerAddr(aDstAddr);
|
||||
messageInfo.SetPeerPort(BackboneRouter::kBackboneUdpPort);
|
||||
|
||||
messageInfo.SetHopLimit(kDefaultHoplimit);
|
||||
messageInfo.SetIsHostInterface(true);
|
||||
|
||||
error = mBackboneTmfAgent.SendMessage(*message, messageInfo);
|
||||
|
||||
exit:
|
||||
LogInfo("Send %s for %s (rloc16=%04x): %s", aDstAddr.IsMulticast() ? "PRO_BB.ntf" : "BB.ans",
|
||||
aDua.ToString().AsCString(), aSrcRloc16, ErrorToString(error));
|
||||
|
||||
FreeMessageOnError(message, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
void Manager::HandleDadBackboneAnswer(const Ip6::Address &aDua, const Ip6::InterfaceIdentifier &aMeshLocalIid)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
NdProxyTable::NdProxy *ndProxy = mNdProxyTable.ResolveDua(aDua);
|
||||
bool duplicate = false;
|
||||
|
||||
OT_UNUSED_VARIABLE(error);
|
||||
|
||||
VerifyOrExit(ndProxy != nullptr, error = kErrorNotFound);
|
||||
|
||||
duplicate = ndProxy->GetMeshLocalIid() != aMeshLocalIid;
|
||||
|
||||
if (duplicate)
|
||||
{
|
||||
Ip6::Address dest;
|
||||
|
||||
dest.SetToRoutingLocator(Get<Mle::Mle>().GetMeshLocalPrefix(), ndProxy->GetRloc16());
|
||||
Get<AddressResolver>().SendAddressError(aDua, aMeshLocalIid, dest);
|
||||
}
|
||||
|
||||
ot::BackboneRouter::NdProxyTable::NotifyDadComplete(*ndProxy, duplicate);
|
||||
|
||||
exit:
|
||||
LogInfo("HandleDadBackboneAnswer: %s, target=%s, mliid=%s, duplicate=%s", ErrorToString(error),
|
||||
aDua.ToString().AsCString(), aMeshLocalIid.ToString().AsCString(), duplicate ? "Y" : "N");
|
||||
}
|
||||
|
||||
void Manager::HandleExtendedBackboneAnswer(const Ip6::Address &aDua,
|
||||
const Ip6::InterfaceIdentifier &aMeshLocalIid,
|
||||
uint32_t aTimeSinceLastTransaction,
|
||||
uint16_t aSrcRloc16)
|
||||
{
|
||||
Ip6::Address dest;
|
||||
|
||||
dest.SetToRoutingLocator(Get<Mle::Mle>().GetMeshLocalPrefix(), aSrcRloc16);
|
||||
Get<AddressResolver>().SendAddressQueryResponse(aDua, aMeshLocalIid, &aTimeSinceLastTransaction, dest);
|
||||
|
||||
LogInfo("HandleExtendedBackboneAnswer: target=%s, mliid=%s, LTT=%lus, rloc16=%04x", aDua.ToString().AsCString(),
|
||||
aMeshLocalIid.ToString().AsCString(), ToUlong(aTimeSinceLastTransaction), aSrcRloc16);
|
||||
}
|
||||
|
||||
void Manager::HandleProactiveBackboneNotification(const Ip6::Address &aDua,
|
||||
const Ip6::InterfaceIdentifier &aMeshLocalIid,
|
||||
uint32_t aTimeSinceLastTransaction)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
NdProxyTable::NdProxy *ndProxy = mNdProxyTable.ResolveDua(aDua);
|
||||
|
||||
OT_UNUSED_VARIABLE(error);
|
||||
|
||||
VerifyOrExit(ndProxy != nullptr, error = kErrorNotFound);
|
||||
|
||||
if (ndProxy->GetMeshLocalIid() == aMeshLocalIid)
|
||||
{
|
||||
uint32_t localTimeSinceLastTransaction = ndProxy->GetTimeSinceLastTransaction();
|
||||
|
||||
if (aTimeSinceLastTransaction <= localTimeSinceLastTransaction)
|
||||
{
|
||||
BackboneRouter::NdProxyTable::Erase(*ndProxy);
|
||||
}
|
||||
else
|
||||
{
|
||||
IgnoreError(SendProactiveBackboneNotification(aDua, ndProxy->GetMeshLocalIid(),
|
||||
ndProxy->GetTimeSinceLastTransaction()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Duplicated address detected, send ADDR_ERR.ntf to ff03::2 in the Thread network
|
||||
BackboneRouter::NdProxyTable::Erase(*ndProxy);
|
||||
Get<AddressResolver>().SendAddressError(aDua, aMeshLocalIid, Ip6::Address::GetRealmLocalAllRoutersMulticast());
|
||||
}
|
||||
|
||||
exit:
|
||||
LogInfo("HandleProactiveBackboneNotification: %s, target=%s, mliid=%s, LTT=%lus", ErrorToString(error),
|
||||
aDua.ToString().AsCString(), aMeshLocalIid.ToString().AsCString(), ToUlong(aTimeSinceLastTransaction));
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
|
||||
void Manager::LogError(const char *aText, Error aError) const
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aText);
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
#include "backbone_router/backbone_tmf.hpp"
|
||||
#include "backbone_router/bbr_leader.hpp"
|
||||
#include "backbone_router/multicast_listeners_table.hpp"
|
||||
#include "backbone_router/ndproxy_table.hpp"
|
||||
#include "common/locator.hpp"
|
||||
#include "common/non_copyable.hpp"
|
||||
#include "net/netif.hpp"
|
||||
@@ -74,28 +73,7 @@ public:
|
||||
*/
|
||||
explicit Manager(Instance &aInstance);
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
/**
|
||||
* Returns the NdProxy Table.
|
||||
*
|
||||
* @returns The NdProxy Table.
|
||||
*/
|
||||
NdProxyTable &GetNdProxyTable(void);
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
/**
|
||||
* Configures response status for next DUA registration.
|
||||
*
|
||||
* Note: available only when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled.
|
||||
* Only used for test and certification.
|
||||
*
|
||||
* @param[in] aMlIid A pointer to the Mesh Local IID. If `nullptr`, respond with @p aStatus for any
|
||||
* coming DUA.req, otherwise only respond the one with matching @p aMlIid.
|
||||
* @param[in] aStatus The status to respond.
|
||||
*/
|
||||
void ConfigNextDuaRegistrationResponse(const Ip6::InterfaceIdentifier *aMlIid, uint8_t aStatus);
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
/**
|
||||
* Configures response status for next Multicast Listener Registration.
|
||||
@@ -118,17 +96,6 @@ public:
|
||||
MulticastListenersTable &GetMulticastListenersTable(void) { return mMulticastListenersTable; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns if messages destined to a given Domain Unicast Address should be forwarded to the Backbone
|
||||
* link.
|
||||
*
|
||||
* @param aAddress The Domain Unicast Address.
|
||||
*
|
||||
* @retval TRUE If messages destined to the Domain Unicast Address should be forwarded to the Backbone link.
|
||||
* @retval FALSE If messages destined to the Domain Unicast Address should not be forwarded to the Backbone link.
|
||||
*/
|
||||
bool ShouldForwardDuaToBackbone(const Ip6::Address &aAddress);
|
||||
|
||||
/**
|
||||
* Returns a reference to the Backbone TMF agent.
|
||||
*
|
||||
@@ -136,33 +103,6 @@ public:
|
||||
*/
|
||||
BackboneTmfAgent &GetBackboneTmfAgent(void) { return mBackboneTmfAgent; }
|
||||
|
||||
/**
|
||||
* Sends BB.qry on the Backbone link.
|
||||
*
|
||||
* @param[in] aDua The Domain Unicast Address to query.
|
||||
* @param[in] aRloc16 The short address of the address resolution initiator or `Mle::kInvalidRloc16` for
|
||||
* DUA DAD.
|
||||
*
|
||||
* @retval kErrorNone Successfully sent BB.qry on backbone link.
|
||||
* @retval kErrorInvalidState If the Backbone Router is not primary, or not enabled.
|
||||
* @retval kErrorNoBufs If insufficient message buffers available.
|
||||
*/
|
||||
Error SendBackboneQuery(const Ip6::Address &aDua, uint16_t aRloc16 = Mle::kInvalidRloc16);
|
||||
|
||||
/**
|
||||
* Send a Proactive Backbone Notification (PRO_BB.ntf) on the Backbone link.
|
||||
*
|
||||
* @param[in] aDua The Domain Unicast Address to notify.
|
||||
* @param[in] aMeshLocalIid The Mesh-Local IID to notify.
|
||||
* @param[in] aTimeSinceLastTransaction Time since last transaction (in seconds).
|
||||
*
|
||||
* @retval kErrorNone Successfully sent PRO_BB.ntf on backbone link.
|
||||
* @retval kErrorNoBufs If insufficient message buffers available.
|
||||
*/
|
||||
Error SendProactiveBackboneNotification(const Ip6::Address &aDua,
|
||||
const Ip6::InterfaceIdentifier &aMeshLocalIid,
|
||||
uint32_t aTimeSinceLastTransaction);
|
||||
|
||||
private:
|
||||
static constexpr uint8_t kDefaultHoplimit = 1;
|
||||
static constexpr uint32_t kTimerInterval = 1000;
|
||||
@@ -181,27 +121,6 @@ private:
|
||||
uint32_t aTimeout);
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
void HandleDuaRegistration(const Coap::Msg &aMsg);
|
||||
Error SendBackboneAnswer(const Ip6::MessageInfo &aQueryMessageInfo,
|
||||
const Ip6::Address &aDua,
|
||||
uint16_t aSrcRloc16,
|
||||
const NdProxyTable::NdProxy &aNdProxy);
|
||||
Error SendBackboneAnswer(const Ip6::Address &aDstAddr,
|
||||
const Ip6::Address &aDua,
|
||||
const Ip6::InterfaceIdentifier &aMeshLocalIid,
|
||||
uint32_t aTimeSinceLastTransaction,
|
||||
uint16_t aSrcRloc16);
|
||||
void HandleDadBackboneAnswer(const Ip6::Address &aDua, const Ip6::InterfaceIdentifier &aMeshLocalIid);
|
||||
void HandleExtendedBackboneAnswer(const Ip6::Address &aDua,
|
||||
const Ip6::InterfaceIdentifier &aMeshLocalIid,
|
||||
uint32_t aTimeSinceLastTransaction,
|
||||
uint16_t aSrcRloc16);
|
||||
void HandleProactiveBackboneNotification(const Ip6::Address &aDua,
|
||||
const Ip6::InterfaceIdentifier &aMeshLocalIid,
|
||||
uint32_t aTimeSinceLastTransaction);
|
||||
void SendDuaRegistrationResponse(const Coap::Msg &aMsg, const Ip6::Address &aTarget, DuaStatus aStatus);
|
||||
#endif
|
||||
void HandleNotifierEvents(Events aEvents);
|
||||
|
||||
void HandleTimer(void);
|
||||
@@ -210,10 +129,6 @@ private:
|
||||
|
||||
using BbrTimer = TimerMilliIn<Manager, &Manager::HandleTimer>;
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
NdProxyTable mNdProxyTable;
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
MulticastListenersTable mMulticastListenersTable;
|
||||
#endif
|
||||
@@ -221,31 +136,15 @@ private:
|
||||
|
||||
BackboneTmfAgent mBackboneTmfAgent;
|
||||
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
Ip6::InterfaceIdentifier mDuaResponseTargetMlIid;
|
||||
uint8_t mDuaResponseStatus;
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE && OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
Mlr::Status mMlrResponseStatus;
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
bool mDuaResponseIsSpecified : 1;
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
bool mMlrResponseIsSpecified : 1;
|
||||
#endif
|
||||
bool mMlrResponseIsSpecified : 1;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
DeclareTmfHandler(Manager, kUriMlr);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
DeclareTmfHandler(Manager, kUriDuaRegistrationRequest);
|
||||
DeclareTmfHandler(Manager, kUriBackboneQuery);
|
||||
DeclareTmfHandler(Manager, kUriBackboneAnswer);
|
||||
#endif
|
||||
|
||||
} // namespace BackboneRouter
|
||||
|
||||
|
||||
@@ -1,350 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file implements Thread NdProxy Table management.
|
||||
*/
|
||||
|
||||
#include "ndproxy_table.hpp"
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
|
||||
#include "common/array.hpp"
|
||||
#include "common/log.hpp"
|
||||
#include "common/num_utils.hpp"
|
||||
#include "instance/instance.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
||||
namespace BackboneRouter {
|
||||
|
||||
RegisterLogModule("BbrNdProxy");
|
||||
|
||||
void NdProxyTable::NdProxy::Init(const Ip6::InterfaceIdentifier &aAddressIid,
|
||||
const Ip6::InterfaceIdentifier &aMeshLocalIid,
|
||||
uint16_t aRloc16,
|
||||
uint32_t aTimeSinceLastTransaction)
|
||||
{
|
||||
OT_ASSERT(!mValid);
|
||||
|
||||
Clear();
|
||||
|
||||
mValid = true;
|
||||
mAddressIid = aAddressIid;
|
||||
mMeshLocalIid = aMeshLocalIid;
|
||||
mDadFlag = true;
|
||||
|
||||
Update(aRloc16, aTimeSinceLastTransaction);
|
||||
}
|
||||
|
||||
void NdProxyTable::NdProxy::Update(uint16_t aRloc16, uint32_t aTimeSinceLastTransaction)
|
||||
{
|
||||
OT_ASSERT(mValid);
|
||||
|
||||
mRloc16 = aRloc16;
|
||||
aTimeSinceLastTransaction = Min(aTimeSinceLastTransaction, kMaxTimeSinceLastTransaction);
|
||||
mLastRegistrationTime = TimerMilli::GetNow() - TimeMilli::SecToMsec(aTimeSinceLastTransaction);
|
||||
}
|
||||
|
||||
bool NdProxyTable::MatchesFilter(const NdProxy &aProxy, Filter aFilter)
|
||||
{
|
||||
bool rval = false;
|
||||
|
||||
switch (aFilter)
|
||||
{
|
||||
case kFilterInvalid:
|
||||
rval = !aProxy.mValid;
|
||||
break;
|
||||
case kFilterValid:
|
||||
rval = aProxy.mValid;
|
||||
break;
|
||||
case kFilterDadInProcess:
|
||||
rval = aProxy.mValid && aProxy.mDadFlag;
|
||||
break;
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
NdProxyTable::Iterator::Iterator(Instance &aInstance, Filter aFilter)
|
||||
: InstanceLocator(aInstance)
|
||||
, mFilter(aFilter)
|
||||
{
|
||||
NdProxyTable &table = GetInstance().Get<BackboneRouter::NdProxyTable>();
|
||||
|
||||
mItem = &table.mProxies[0];
|
||||
|
||||
if (!MatchesFilter(*mItem, mFilter))
|
||||
{
|
||||
Advance();
|
||||
}
|
||||
}
|
||||
|
||||
NdProxyTable::Iterator::Iterator(Instance &aInstance, NdProxyTable::Iterator::IteratorType)
|
||||
: InstanceLocator(aInstance)
|
||||
{
|
||||
NdProxyTable &table = GetInstance().Get<BackboneRouter::NdProxyTable>();
|
||||
mItem = GetArrayEnd(table.mProxies);
|
||||
}
|
||||
|
||||
void NdProxyTable::Iterator::Advance(void)
|
||||
{
|
||||
NdProxyTable &table = GetInstance().Get<BackboneRouter::NdProxyTable>();
|
||||
|
||||
do
|
||||
{
|
||||
mItem++;
|
||||
} while (mItem < GetArrayEnd(table.mProxies) && !MatchesFilter(*mItem, mFilter));
|
||||
}
|
||||
|
||||
void NdProxyTable::Erase(NdProxy &aNdProxy) { aNdProxy.mValid = false; }
|
||||
|
||||
void NdProxyTable::HandleDomainPrefixUpdate(DomainPrefixEvent aEvent)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aEvent);
|
||||
Clear();
|
||||
}
|
||||
|
||||
void NdProxyTable::Clear(void)
|
||||
{
|
||||
for (NdProxy &proxy : mProxies)
|
||||
{
|
||||
proxy.Clear();
|
||||
}
|
||||
|
||||
mCallback.InvokeIfSet(MapEnum(NdProxy::kCleared), nullptr);
|
||||
|
||||
LogInfo("NdProxyTable::Clear!");
|
||||
}
|
||||
|
||||
Error NdProxyTable::Register(const Ip6::InterfaceIdentifier &aAddressIid,
|
||||
const Ip6::InterfaceIdentifier &aMeshLocalIid,
|
||||
uint16_t aRloc16,
|
||||
const uint32_t *aTimeSinceLastTransaction)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
NdProxy *proxy = FindByAddressIid(aAddressIid);
|
||||
uint32_t timeSinceLastTransaction = aTimeSinceLastTransaction == nullptr ? 0 : *aTimeSinceLastTransaction;
|
||||
|
||||
if (proxy != nullptr)
|
||||
{
|
||||
VerifyOrExit(proxy->mMeshLocalIid == aMeshLocalIid, error = kErrorDuplicated);
|
||||
|
||||
proxy->Update(aRloc16, timeSinceLastTransaction);
|
||||
NotifyDuaRegistrationOnBackboneLink(*proxy, /* aIsRenew */ true);
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
proxy = FindByMeshLocalIid(aMeshLocalIid);
|
||||
if (proxy != nullptr)
|
||||
{
|
||||
TriggerCallback(NdProxy::kRemoved, proxy->mAddressIid);
|
||||
Erase(*proxy);
|
||||
}
|
||||
else
|
||||
{
|
||||
proxy = FindInvalid();
|
||||
|
||||
// TODO: evict stale DUA entries to have room for this new DUA.
|
||||
VerifyOrExit(proxy != nullptr, error = kErrorNoBufs);
|
||||
}
|
||||
|
||||
proxy->Init(aAddressIid, aMeshLocalIid, aRloc16, timeSinceLastTransaction);
|
||||
mIsAnyDadInProcess = true;
|
||||
|
||||
exit:
|
||||
LogInfo("NdProxyTable::Register %s MLIID %s RLOC16 %04x LTT %lu => %s", aAddressIid.ToString().AsCString(),
|
||||
aMeshLocalIid.ToString().AsCString(), aRloc16, ToUlong(timeSinceLastTransaction), ErrorToString(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
NdProxyTable::NdProxy *NdProxyTable::FindByAddressIid(const Ip6::InterfaceIdentifier &aAddressIid)
|
||||
{
|
||||
NdProxy *found = nullptr;
|
||||
|
||||
for (NdProxy &proxy : Iterate(kFilterValid))
|
||||
{
|
||||
if (proxy.mAddressIid == aAddressIid)
|
||||
{
|
||||
ExitNow(found = &proxy);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
LogDebg("NdProxyTable::FindByAddressIid(%s) => %s", aAddressIid.ToString().AsCString(),
|
||||
found ? found->mMeshLocalIid.ToString().AsCString() : "NOT_FOUND");
|
||||
return found;
|
||||
}
|
||||
|
||||
NdProxyTable::NdProxy *NdProxyTable::FindByMeshLocalIid(const Ip6::InterfaceIdentifier &aMeshLocalIid)
|
||||
{
|
||||
NdProxy *found = nullptr;
|
||||
|
||||
for (NdProxy &proxy : Iterate(kFilterValid))
|
||||
{
|
||||
if (proxy.mMeshLocalIid == aMeshLocalIid)
|
||||
{
|
||||
ExitNow(found = &proxy);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
LogDebg("NdProxyTable::FindByMeshLocalIid(%s) => %s", aMeshLocalIid.ToString().AsCString(),
|
||||
found ? found->mAddressIid.ToString().AsCString() : "NOT_FOUND");
|
||||
return found;
|
||||
}
|
||||
|
||||
NdProxyTable::NdProxy *NdProxyTable::FindInvalid(void)
|
||||
{
|
||||
NdProxy *found = nullptr;
|
||||
|
||||
for (NdProxy &proxy : Iterate(kFilterInvalid))
|
||||
{
|
||||
ExitNow(found = &proxy);
|
||||
}
|
||||
|
||||
exit:
|
||||
LogDebg("NdProxyTable::FindInvalid() => %s", found ? "OK" : "NOT_FOUND");
|
||||
return found;
|
||||
}
|
||||
|
||||
void NdProxyTable::HandleTimer(void)
|
||||
{
|
||||
VerifyOrExit(mIsAnyDadInProcess);
|
||||
|
||||
mIsAnyDadInProcess = false;
|
||||
|
||||
for (NdProxy &proxy : Iterate(kFilterDadInProcess))
|
||||
{
|
||||
if (proxy.IsDadAttemptsComplete())
|
||||
{
|
||||
proxy.mDadFlag = false;
|
||||
NotifyDuaRegistrationOnBackboneLink(proxy, /* aIsRenew */ false);
|
||||
}
|
||||
else
|
||||
{
|
||||
mIsAnyDadInProcess = true;
|
||||
|
||||
if (Get<BackboneRouter::Manager>().SendBackboneQuery(GetDua(proxy)) == kErrorNone)
|
||||
{
|
||||
proxy.IncreaseDadAttempts();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void NdProxyTable::TriggerCallback(NdProxy::Event aEvent, const Ip6::InterfaceIdentifier &aAddressIid) const
|
||||
{
|
||||
Ip6::Address dua;
|
||||
const Ip6::Prefix *prefix = Get<BackboneRouter::Leader>().GetDomainPrefix();
|
||||
|
||||
VerifyOrExit(mCallback.IsSet());
|
||||
|
||||
OT_ASSERT(prefix != nullptr);
|
||||
|
||||
dua.SetPrefix(*prefix);
|
||||
dua.SetIid(aAddressIid);
|
||||
|
||||
mCallback.Invoke(MapEnum(aEvent), &dua);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void NdProxyTable::NotifyDadComplete(NdProxyTable::NdProxy &aNdProxy, bool aDuplicated)
|
||||
{
|
||||
if (aDuplicated)
|
||||
{
|
||||
Erase(aNdProxy);
|
||||
}
|
||||
else
|
||||
{
|
||||
aNdProxy.mDadAttempts = kDuaDadRepeats;
|
||||
}
|
||||
}
|
||||
|
||||
Ip6::Address NdProxyTable::GetDua(NdProxy &aNdProxy)
|
||||
{
|
||||
Ip6::Address dua;
|
||||
const Ip6::Prefix *domainPrefix = Get<BackboneRouter::Leader>().GetDomainPrefix();
|
||||
|
||||
OT_ASSERT(domainPrefix != nullptr);
|
||||
|
||||
dua.SetPrefix(*domainPrefix);
|
||||
dua.SetIid(aNdProxy.mAddressIid);
|
||||
|
||||
return dua;
|
||||
}
|
||||
|
||||
NdProxyTable::NdProxy *NdProxyTable::ResolveDua(const Ip6::Address &aDua)
|
||||
{
|
||||
return Get<Leader>().IsDomainUnicast(aDua) ? FindByAddressIid(aDua.GetIid()) : nullptr;
|
||||
}
|
||||
|
||||
void NdProxyTable::NotifyDuaRegistrationOnBackboneLink(NdProxyTable::NdProxy &aNdProxy, bool aIsRenew)
|
||||
{
|
||||
if (!aNdProxy.mDadFlag)
|
||||
{
|
||||
TriggerCallback(aIsRenew ? NdProxy::kRenewed : NdProxy::kAdded, aNdProxy.mAddressIid);
|
||||
|
||||
IgnoreError(Get<BackboneRouter::Manager>().SendProactiveBackboneNotification(
|
||||
GetDua(aNdProxy), aNdProxy.GetMeshLocalIid(), aNdProxy.GetTimeSinceLastTransaction()));
|
||||
}
|
||||
}
|
||||
|
||||
Error NdProxyTable::GetInfo(const Ip6::Address &aDua, otBackboneRouterNdProxyInfo &aNdProxyInfo)
|
||||
{
|
||||
Error error = kErrorNotFound;
|
||||
|
||||
VerifyOrExit(Get<Leader>().IsDomainUnicast(aDua), error = kErrorInvalidArgs);
|
||||
|
||||
for (NdProxy &proxy : Iterate(kFilterValid))
|
||||
{
|
||||
if (proxy.mAddressIid == aDua.GetIid())
|
||||
{
|
||||
aNdProxyInfo.mMeshLocalIid = &proxy.mMeshLocalIid;
|
||||
aNdProxyInfo.mTimeSinceLastTransaction = proxy.GetTimeSinceLastTransaction();
|
||||
aNdProxyInfo.mRloc16 = proxy.mRloc16;
|
||||
|
||||
ExitNow(error = kErrorNone);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
} // namespace BackboneRouter
|
||||
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
@@ -1,308 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* @file
|
||||
* This file includes definitions for NdProxy Table on Thread Backbone Border Router.
|
||||
*/
|
||||
|
||||
#ifndef OT_CORE_BACKBONE_ROUTER_NDPROXY_TABLE_HPP_
|
||||
#define OT_CORE_BACKBONE_ROUTER_NDPROXY_TABLE_HPP_
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
|
||||
#include <openthread/backbone_router_ftd.h>
|
||||
|
||||
#include "backbone_router/bbr_leader.hpp"
|
||||
#include "common/as_core_type.hpp"
|
||||
#include "common/callback.hpp"
|
||||
#include "common/iterator_utils.hpp"
|
||||
#include "common/locator.hpp"
|
||||
#include "common/non_copyable.hpp"
|
||||
#include "common/time.hpp"
|
||||
#include "net/ip6_address.hpp"
|
||||
#include "thread/mle_types.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
||||
namespace BackboneRouter {
|
||||
|
||||
/**
|
||||
* Implements NdProxy Table maintenance on Primary Backbone Router.
|
||||
*/
|
||||
class NdProxyTable : public InstanceLocator, private NonCopyable
|
||||
{
|
||||
public:
|
||||
static constexpr uint8_t kDuaDadRepeats = 3; ///< Number multicast DAD queries by BBR
|
||||
|
||||
/**
|
||||
* Represents a ND Proxy instance.
|
||||
*/
|
||||
class NdProxy : private Clearable<NdProxy>
|
||||
{
|
||||
friend class NdProxyTable;
|
||||
friend class Clearable<NdProxy>;
|
||||
|
||||
public:
|
||||
typedef otBackboneRouterNdProxyCallback Callback; ///< ND Proxy callback.
|
||||
|
||||
/**
|
||||
* Represents the ND Proxy events.
|
||||
*/
|
||||
enum Event
|
||||
{
|
||||
kAdded = OT_BACKBONE_ROUTER_NDPROXY_ADDED, ///< ND Proxy was added.
|
||||
kRemoved = OT_BACKBONE_ROUTER_NDPROXY_REMOVED, ///< ND Proxy was removed.
|
||||
kRenewed = OT_BACKBONE_ROUTER_NDPROXY_RENEWED, ///< ND Proxy was renewed.
|
||||
kCleared = OT_BACKBONE_ROUTER_NDPROXY_CLEARED, ///< All ND Proxies were cleared.
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the Mesh-Local IID of the ND Proxy.
|
||||
*
|
||||
* @returns The Mesh-Local IID.
|
||||
*/
|
||||
const Ip6::InterfaceIdentifier &GetMeshLocalIid(void) const { return mMeshLocalIid; }
|
||||
|
||||
/**
|
||||
* Gets the time since last transaction of the ND Proxy.
|
||||
*
|
||||
* @returns The time since last transaction in seconds.
|
||||
*/
|
||||
uint32_t GetTimeSinceLastTransaction(void) const
|
||||
{
|
||||
return TimeMilli::MsecToSec(TimerMilli::GetNow() - mLastRegistrationTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the short address of the device who sends the DUA registration.
|
||||
*
|
||||
* @returns The RLOC16 value.
|
||||
*/
|
||||
uint16_t GetRloc16(void) const { return mRloc16; }
|
||||
|
||||
/**
|
||||
* Gets the DAD flag of the ND Proxy.
|
||||
*
|
||||
* @returns The DAD flag.
|
||||
*/
|
||||
bool GetDadFlag(void) const { return mDadFlag; }
|
||||
|
||||
private:
|
||||
static constexpr uint32_t kMaxTimeSinceLastTransaction = 10 * 86400; // In seconds (10 days).
|
||||
|
||||
NdProxy(void) { Clear(); }
|
||||
|
||||
void Init(const Ip6::InterfaceIdentifier &aAddressIid,
|
||||
const Ip6::InterfaceIdentifier &aMeshLocalIid,
|
||||
uint16_t aRloc16,
|
||||
uint32_t aTimeSinceLastTransaction);
|
||||
|
||||
void Update(uint16_t aRloc16, uint32_t aTimeSinceLastTransaction);
|
||||
void IncreaseDadAttempts(void) { mDadAttempts++; }
|
||||
bool IsDadAttemptsComplete(void) const { return mDadAttempts == kDuaDadRepeats; }
|
||||
|
||||
Ip6::InterfaceIdentifier mAddressIid;
|
||||
Ip6::InterfaceIdentifier mMeshLocalIid;
|
||||
TimeMilli mLastRegistrationTime; ///< in milliseconds
|
||||
uint16_t mRloc16;
|
||||
uint8_t mDadAttempts : 2;
|
||||
bool mDadFlag : 1;
|
||||
bool mValid : 1;
|
||||
|
||||
static_assert(kDuaDadRepeats < 4, "kDuaDadRepeats does not fit in mDadAttempts field as 2-bit value");
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the `NdProxyTable` object.
|
||||
*
|
||||
* @param[in] aInstance A reference to the OpenThread instance.
|
||||
*/
|
||||
explicit NdProxyTable(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
, mIsAnyDadInProcess(false)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a given IPv6 address IID with related information to the NdProxy table.
|
||||
*
|
||||
* @param[in] aAddressIid The IPv6 address IID.
|
||||
* @param[in] aMeshLocalIid The Mesh-Local IID.
|
||||
* @param[in] aRloc16 The RLOC16.
|
||||
* @param[in] aTimeSinceLastTransaction Time since last transaction (in seconds).
|
||||
*
|
||||
* @retval kErrorNone If registered successfully.
|
||||
* @retval kErrorDuplicated If the IPv6 address IID is a duplicate.
|
||||
* @retval kErrorNoBufs Insufficient buffer space available to register.
|
||||
*/
|
||||
Error Register(const Ip6::InterfaceIdentifier &aAddressIid,
|
||||
const Ip6::InterfaceIdentifier &aMeshLocalIid,
|
||||
uint16_t aRloc16,
|
||||
const uint32_t *aTimeSinceLastTransaction);
|
||||
|
||||
/**
|
||||
* Checks if a given IPv6 address IID was registered.
|
||||
*
|
||||
* @param[in] aAddressIid The IPv6 address IID.
|
||||
*
|
||||
* @retval TRUE If the IPv6 address IID was registered.
|
||||
* @retval FALSE If the IPv6 address IID was not registered.
|
||||
*/
|
||||
bool IsRegistered(const Ip6::InterfaceIdentifier &aAddressIid) { return FindByAddressIid(aAddressIid) != nullptr; }
|
||||
|
||||
/**
|
||||
* Notifies Domain Prefix event.
|
||||
*
|
||||
* @param[in] aEvent The Domain Prefix event.
|
||||
*/
|
||||
void HandleDomainPrefixUpdate(DomainPrefixEvent aEvent);
|
||||
|
||||
/**
|
||||
* Notifies ND Proxy table of the timer tick.
|
||||
*/
|
||||
void HandleTimer(void);
|
||||
|
||||
/**
|
||||
* Gets the ND Proxy info for a given Domain Unicast Address.
|
||||
*
|
||||
* @param[in] aDua The Domain Unicast Address.
|
||||
*
|
||||
* @returns The `NdProxy` instance matching the specified @p aDua, or nullptr if not found.
|
||||
*/
|
||||
NdProxy *ResolveDua(const Ip6::Address &aDua);
|
||||
|
||||
/**
|
||||
* Notifies DAD completed for a given ND Proxy.
|
||||
*
|
||||
* @param[in] aNdProxy The ND Proxy to notify of.
|
||||
* @param[in] aDuplicated Whether duplicate was detected.
|
||||
*/
|
||||
static void NotifyDadComplete(NdProxy &aNdProxy, bool aDuplicated);
|
||||
|
||||
/**
|
||||
* Removes the ND Proxy.
|
||||
*
|
||||
* @param[in] aNdProxy The ND Proxy to remove.
|
||||
*/
|
||||
static void Erase(NdProxy &aNdProxy);
|
||||
|
||||
/*
|
||||
* Sets the ND Proxy callback.
|
||||
*
|
||||
* @param[in] aCallback The callback function.
|
||||
* @param[in] aContext A user context pointer.
|
||||
*/
|
||||
void SetCallback(NdProxy::Callback aCallback, void *aContext) { mCallback.Set(aCallback, aContext); }
|
||||
|
||||
/**
|
||||
* Retrieves the ND Proxy info of the Domain Unicast Address.
|
||||
*
|
||||
* @param[in] aDua The Domain Unicast Address to get info.
|
||||
* @param[in] aNdProxyInfo A pointer to the ND Proxy info.
|
||||
*
|
||||
* @retval kErrorNone Successfully retrieve the ND Proxy info.
|
||||
* @retval kErrorNotFound Failed to find the Domain Unicast Address in the ND Proxy table.
|
||||
*/
|
||||
Error GetInfo(const Ip6::Address &aDua, otBackboneRouterNdProxyInfo &aNdProxyInfo);
|
||||
|
||||
private:
|
||||
static constexpr uint16_t kMaxNdProxyNum = OPENTHREAD_CONFIG_NDPROXY_TABLE_ENTRY_NUM;
|
||||
|
||||
enum Filter : uint8_t
|
||||
{
|
||||
kFilterInvalid,
|
||||
kFilterValid,
|
||||
kFilterDadInProcess,
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents an iterator for iterating through the NdProxy Table.
|
||||
*/
|
||||
class Iterator : public InstanceLocator, public ItemPtrIterator<NdProxy, Iterator>
|
||||
{
|
||||
friend class ItemPtrIterator<NdProxy, Iterator>;
|
||||
friend class NdProxyTable;
|
||||
friend class IteratorBuilder;
|
||||
|
||||
private:
|
||||
enum IteratorType : uint8_t
|
||||
{
|
||||
kEndIterator,
|
||||
};
|
||||
|
||||
Iterator(Instance &aInstance, Filter aFilter);
|
||||
Iterator(Instance &aInstance, IteratorType);
|
||||
|
||||
void Advance(void);
|
||||
|
||||
Filter mFilter;
|
||||
};
|
||||
|
||||
class IteratorBuilder : public InstanceLocator
|
||||
{
|
||||
friend class NdProxyTable;
|
||||
|
||||
private:
|
||||
IteratorBuilder(Instance &aInstance, Filter aFilter)
|
||||
: InstanceLocator(aInstance)
|
||||
, mFilter(aFilter)
|
||||
{
|
||||
}
|
||||
|
||||
Iterator begin(void) { return Iterator(GetInstance(), mFilter); }
|
||||
Iterator end(void) { return Iterator(GetInstance(), Iterator::kEndIterator); }
|
||||
|
||||
Filter mFilter;
|
||||
};
|
||||
|
||||
IteratorBuilder Iterate(Filter aFilter) { return IteratorBuilder(GetInstance(), aFilter); }
|
||||
void Clear(void);
|
||||
static bool MatchesFilter(const NdProxy &aProxy, Filter aFilter);
|
||||
NdProxy *FindByAddressIid(const Ip6::InterfaceIdentifier &aAddressIid);
|
||||
NdProxy *FindByMeshLocalIid(const Ip6::InterfaceIdentifier &aMeshLocalIid);
|
||||
NdProxy *FindInvalid(void);
|
||||
Ip6::Address GetDua(NdProxy &aNdProxy);
|
||||
void NotifyDuaRegistrationOnBackboneLink(NdProxy &aNdProxy, bool aIsRenew);
|
||||
void TriggerCallback(NdProxy::Event aEvent, const Ip6::InterfaceIdentifier &aAddressIid) const;
|
||||
|
||||
NdProxy mProxies[kMaxNdProxyNum];
|
||||
Callback<NdProxy::Callback> mCallback;
|
||||
bool mIsAnyDadInProcess : 1;
|
||||
};
|
||||
|
||||
} // namespace BackboneRouter
|
||||
|
||||
DefineMapEnum(otBackboneRouterNdProxyEvent, BackboneRouter::NdProxyTable::NdProxy::Event);
|
||||
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
|
||||
#endif // OT_CORE_BACKBONE_ROUTER_NDPROXY_TABLE_HPP_
|
||||
@@ -52,21 +52,6 @@
|
||||
#define OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
*
|
||||
* Define to 1 to enable Backbone Router ND Proxying for Thread 1.2 DUA feature.
|
||||
* It's turned on by default for Thread 1.2 Backbone Router.
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
#define OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE && !OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
#error \
|
||||
"OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE is required for OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
*
|
||||
@@ -83,10 +68,9 @@
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
#if !OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE && \
|
||||
!OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
#if !OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
#error \
|
||||
"At least one of OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE and OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE must be enabled for OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE"
|
||||
"OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE must be enabled for OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -104,18 +88,6 @@
|
||||
#define OPENTHREAD_CONFIG_MAX_MULTICAST_LISTENERS 75
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_NDPROXY_TABLE_ENTRY_NUM
|
||||
*
|
||||
* The maximum number of supported DUA that Backbone Router could proxy.
|
||||
*
|
||||
* Note: According to Thread Conformance v1.2.0, a Thread Border Router MUST be able to hold a DUA Devices Table in
|
||||
* memory with at least two hundred and fifty (250) entries.
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_NDPROXY_TABLE_ENTRY_NUM
|
||||
#define OPENTHREAD_CONFIG_NDPROXY_TABLE_ENTRY_NUM 250
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -1242,13 +1242,6 @@ template <> inline BackboneRouter::MulticastListenersTable &Instance::Get(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
template <> inline BackboneRouter::NdProxyTable &Instance::Get(void)
|
||||
{
|
||||
return mBackboneRouterManager.GetNdProxyTable();
|
||||
}
|
||||
#endif
|
||||
|
||||
template <> inline BackboneRouter::BackboneTmfAgent &Instance::Get(void)
|
||||
{
|
||||
return mBackboneRouterManager.GetBackboneTmfAgent();
|
||||
|
||||
@@ -1242,13 +1242,7 @@ void Ip6::DetermineAction(const Message &aMessage,
|
||||
|
||||
if (IsOnLink(aHeader.GetDestination()))
|
||||
{
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
aForwardThread = (!aMessage.IsLoopbackToHostAllowed() ||
|
||||
!Get<BackboneRouter::Manager>().ShouldForwardDuaToBackbone(aHeader.GetDestination()));
|
||||
aForwardHost = !aForwardThread;
|
||||
#else
|
||||
aForwardThread = true;
|
||||
#endif
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
|
||||
@@ -628,17 +628,6 @@ exit:
|
||||
Get<TimeTicker>().RegisterReceiver(TimeTicker::kAddressResolver);
|
||||
FreeMessageOnError(message, error);
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
if (Get<BackboneRouter::Local>().IsPrimary() && Get<BackboneRouter::Leader>().IsDomainUnicast(aEid))
|
||||
{
|
||||
uint16_t selfRloc16 = Get<Mle::Mle>().GetRloc16();
|
||||
|
||||
LogInfo("Extending %s to %s for target %s, rloc16=%04x(self)", UriToString<kUriAddressQuery>(),
|
||||
UriToString<kUriBackboneQuery>(), aEid.ToString().AsCString(), selfRloc16);
|
||||
IgnoreError(Get<BackboneRouter::Manager>().SendBackboneQuery(aEid, selfRloc16));
|
||||
}
|
||||
#endif
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -847,17 +836,6 @@ template <> void AddressResolver::HandleTmf<kUriAddressQuery>(Coap::Msg &aMsg)
|
||||
}
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
if (Get<BackboneRouter::Local>().IsPrimary() && Get<BackboneRouter::Leader>().IsDomainUnicast(target))
|
||||
{
|
||||
uint16_t srcRloc16 = aMsg.mMessageInfo.GetPeerAddr().GetIid().GetLocator();
|
||||
|
||||
LogInfo("Extending %s to %s for target %s rloc16=%04x", UriToString<kUriAddressQuery>(),
|
||||
UriToString<kUriBackboneQuery>(), target.ToString().AsCString(), srcRloc16);
|
||||
IgnoreError(Get<BackboneRouter::Manager>().SendBackboneQuery(target, srcRloc16));
|
||||
}
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -150,9 +150,6 @@ bool Agent::HandleResource(const char *aUriPath, Msg &aMsg)
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
|
||||
Case(kUriMlr, BackboneRouter::Manager);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
Case(kUriDuaRegistrationRequest, BackboneRouter::Manager);
|
||||
#endif
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
|
||||
Case(kUriTcatEnable, MeshCoP::TcatAgent);
|
||||
|
||||
@@ -59,9 +59,7 @@ struct Entry
|
||||
_("a/as", kUriAddressSolicit, "AddrSolicit") \
|
||||
_("a/sd", kUriServerData, "ServerData") \
|
||||
_("a/yl", kUriAnycastLocate, "AnycastLocate") \
|
||||
_("b/ba", kUriBackboneAnswer, "BbAnswer") \
|
||||
_("b/bmr", kUriBackboneMlr, "BbMlr") \
|
||||
_("b/bq", kUriBackboneQuery, "BbQuery") \
|
||||
_("c/ab", kUriAnnounceBegin, "AnnounceBegin") \
|
||||
_("c/ag", kUriActiveGet, "ActiveGet") \
|
||||
_("c/ar", kUriActiveReplace, "ActiveReplace") \
|
||||
|
||||
@@ -52,9 +52,7 @@ enum Uri : uint8_t
|
||||
kUriAddressSolicit, ///< Address Solicit ("a/as")
|
||||
kUriServerData, ///< Server Data Registration ("a/sd")
|
||||
kUriAnycastLocate, ///< Anycast Locate ("a/yl")
|
||||
kUriBackboneAnswer, ///< Backbone Answer / Backbone Notification ("b/ba")
|
||||
kUriBackboneMlr, ///< Backbone Multicast Listener Report ("b/bmr")
|
||||
kUriBackboneQuery, ///< Backbone Query ("b/bq")
|
||||
kUriAnnounceBegin, ///< Announce Begin ("c/ab")
|
||||
kUriActiveGet, ///< MGMT_ACTIVE_GET "c/ag"
|
||||
kUriActiveReplace, ///< MGMT_ACTIVE_REPLACE ("c/ar")
|
||||
@@ -131,9 +129,7 @@ template <> const char *UriToString<kUriAddressRelease>(void);
|
||||
template <> const char *UriToString<kUriAddressSolicit>(void);
|
||||
template <> const char *UriToString<kUriServerData>(void);
|
||||
template <> const char *UriToString<kUriAnycastLocate>(void);
|
||||
template <> const char *UriToString<kUriBackboneAnswer>(void);
|
||||
template <> const char *UriToString<kUriBackboneMlr>(void);
|
||||
template <> const char *UriToString<kUriBackboneQuery>(void);
|
||||
template <> const char *UriToString<kUriAnnounceBegin>(void);
|
||||
template <> const char *UriToString<kUriActiveGet>(void);
|
||||
template <> const char *UriToString<kUriActiveReplace>(void);
|
||||
|
||||
@@ -242,7 +242,6 @@ ot_unit_test(mle)
|
||||
ot_unit_test(msg_backed_array)
|
||||
ot_unit_test(multicast_listeners_table)
|
||||
ot_unit_test(nat64)
|
||||
ot_unit_test(ndproxy_table)
|
||||
ot_unit_test(netif)
|
||||
ot_unit_test(network_data)
|
||||
ot_unit_test(network_name)
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
|
||||
#include "test_platform.h"
|
||||
|
||||
#include <openthread/config.h>
|
||||
#include <openthread/ip6.h>
|
||||
|
||||
#include "test_util.h"
|
||||
#include "backbone_router/ndproxy_table.hpp"
|
||||
#include "common/code_utils.hpp"
|
||||
#include "instance/instance.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
||||
static Instance *sInstance;
|
||||
|
||||
using namespace ot::BackboneRouter;
|
||||
|
||||
Ip6::InterfaceIdentifier generateRandomIid(uint16_t aIndex)
|
||||
{
|
||||
Ip6::InterfaceIdentifier iid;
|
||||
|
||||
Random::NonCrypto::Fill(iid);
|
||||
iid.mFields.m16[3] = aIndex;
|
||||
|
||||
return iid;
|
||||
}
|
||||
|
||||
void TestNdProxyTable(void)
|
||||
{
|
||||
Error error;
|
||||
|
||||
sInstance = testInitInstance();
|
||||
VerifyOrQuit(sInstance != nullptr);
|
||||
|
||||
BackboneRouter::NdProxyTable &table = sInstance->Get<BackboneRouter::NdProxyTable>();
|
||||
|
||||
Ip6::InterfaceIdentifier existedAddressIid = generateRandomIid(0);
|
||||
Ip6::InterfaceIdentifier existedMeshLocalIid = generateRandomIid(0);
|
||||
Ip6::InterfaceIdentifier notExistAddressIid = generateRandomIid(OPENTHREAD_CONFIG_NDPROXY_TABLE_ENTRY_NUM);
|
||||
Ip6::InterfaceIdentifier notExistMeshLocalIid = generateRandomIid(OPENTHREAD_CONFIG_NDPROXY_TABLE_ENTRY_NUM);
|
||||
|
||||
// Reregister address IID when there are enough room should succeed.
|
||||
SuccessOrQuit(table.Register(existedAddressIid, existedMeshLocalIid, 0, nullptr));
|
||||
VerifyOrQuit(table.IsRegistered(existedAddressIid));
|
||||
VerifyOrQuit(!table.IsRegistered(notExistAddressIid));
|
||||
|
||||
for (uint16_t i = 1; i < OPENTHREAD_CONFIG_NDPROXY_TABLE_ENTRY_NUM; i++)
|
||||
{
|
||||
Ip6::InterfaceIdentifier addressIid = generateRandomIid(i);
|
||||
Ip6::InterfaceIdentifier meshLocalIid = generateRandomIid(i);
|
||||
|
||||
// Reregister address IID when there are enough room should succeed.
|
||||
SuccessOrQuit(table.Register(addressIid, meshLocalIid, i, nullptr));
|
||||
|
||||
VerifyOrQuit(table.IsRegistered(addressIid));
|
||||
|
||||
// Reregister the same address IID should always succeed.
|
||||
SuccessOrQuit(table.Register(addressIid, meshLocalIid, i, nullptr));
|
||||
|
||||
// Register the same address IID with a different ML-IID should fail.
|
||||
VerifyOrQuit(table.Register(addressIid, notExistMeshLocalIid, i, nullptr) == kErrorDuplicated);
|
||||
|
||||
VerifyOrQuit(table.IsRegistered(addressIid));
|
||||
}
|
||||
|
||||
// Now the table is full, registering another IID should fail.
|
||||
VerifyOrQuit(table.Register(notExistAddressIid, notExistMeshLocalIid, OPENTHREAD_CONFIG_NDPROXY_TABLE_ENTRY_NUM,
|
||||
nullptr) == kErrorNoBufs);
|
||||
VerifyOrQuit(!table.IsRegistered(notExistAddressIid));
|
||||
}
|
||||
|
||||
} // namespace ot
|
||||
|
||||
int main(void)
|
||||
{
|
||||
ot::TestNdProxyTable();
|
||||
|
||||
printf("\nAll tests passed.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
int main(void) { return 0; }
|
||||
#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
Reference in New Issue
Block a user