mirror of
https://github.com/espressif/openthread.git
synced 2026-07-25 13:34:06 +00:00
[dua] add NdProxy table on Backbone Router (#5422)
This commit is contained in:
@@ -180,6 +180,7 @@ LOCAL_SRC_FILES := \
|
||||
src/core/backbone_router/bbr_local.cpp \
|
||||
src/core/backbone_router/bbr_manager.cpp \
|
||||
src/core/backbone_router/multicast_listeners_table.cpp \
|
||||
src/core/backbone_router/ndproxy_table.cpp \
|
||||
src/core/coap/coap.cpp \
|
||||
src/core/coap/coap_message.cpp \
|
||||
src/core/coap/coap_secure.cpp \
|
||||
|
||||
@@ -327,6 +327,8 @@ 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",
|
||||
"coap/coap.cpp",
|
||||
"coap/coap.hpp",
|
||||
"coap/coap_message.cpp",
|
||||
|
||||
@@ -106,6 +106,7 @@ set(COMMON_SOURCES
|
||||
backbone_router/bbr_local.cpp
|
||||
backbone_router/bbr_manager.cpp
|
||||
backbone_router/multicast_listeners_table.cpp
|
||||
backbone_router/ndproxy_table.cpp
|
||||
coap/coap.cpp
|
||||
coap/coap_message.cpp
|
||||
coap/coap_secure.cpp
|
||||
|
||||
@@ -148,6 +148,7 @@ SOURCES_COMMON = \
|
||||
backbone_router/bbr_local.cpp \
|
||||
backbone_router/bbr_manager.cpp \
|
||||
backbone_router/multicast_listeners_table.cpp \
|
||||
backbone_router/ndproxy_table.cpp \
|
||||
coap/coap.cpp \
|
||||
coap/coap_message.cpp \
|
||||
coap/coap_secure.cpp \
|
||||
@@ -328,6 +329,7 @@ HEADERS_COMMON = \
|
||||
backbone_router/bbr_local.hpp \
|
||||
backbone_router/bbr_manager.hpp \
|
||||
backbone_router/multicast_listeners_table.hpp \
|
||||
backbone_router/ndproxy_table.hpp \
|
||||
coap/coap.hpp \
|
||||
coap/coap_message.hpp \
|
||||
coap/coap_secure.hpp \
|
||||
|
||||
@@ -302,6 +302,7 @@ void Leader::UpdateDomainPrefixConfig(void)
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
Get<Local>().UpdateAllDomainBackboneRouters(state);
|
||||
Get<NdProxyTable>().HandleDomainPrefixUpdate(state);
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_DUA_ENABLE || OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE
|
||||
|
||||
@@ -53,6 +53,7 @@ Manager::Manager(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
, mMulticastListenerRegistration(UriPath::kMlr, Manager::HandleMulticastListenerRegistration, this)
|
||||
, mDuaRegistration(UriPath::kDuaRegistrationRequest, Manager::HandleDuaRegistration, this)
|
||||
, mNdProxyTable(aInstance)
|
||||
, mMulticastListenersTable(aInstance)
|
||||
, mTimer(aInstance, Manager::HandleTimer, this)
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
@@ -267,13 +268,15 @@ exit:
|
||||
|
||||
void Manager::HandleDuaRegistration(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
ThreadStatusTlv::DuaStatus status = ThreadStatusTlv::kDuaSuccess;
|
||||
bool isPrimary = Get<BackboneRouter::Local>().IsPrimary();
|
||||
uint32_t lastTransactionTime = 0;
|
||||
otError error = OT_ERROR_NONE;
|
||||
ThreadStatusTlv::DuaStatus status = ThreadStatusTlv::kDuaSuccess;
|
||||
bool isPrimary = Get<BackboneRouter::Local>().IsPrimary();
|
||||
uint32_t lastTransactionTime;
|
||||
bool hasLastTransactionTime;
|
||||
Ip6::Address target;
|
||||
Ip6::InterfaceIdentifier meshLocalIid;
|
||||
|
||||
VerifyOrExit(aMessageInfo.GetPeerAddr().GetIid().IsRoutingLocator(), error = OT_ERROR_DROP);
|
||||
VerifyOrExit(aMessage.IsConfirmablePostRequest(), error = OT_ERROR_PARSE);
|
||||
|
||||
SuccessOrExit(error = Tlv::FindTlv(aMessage, ThreadTlv::kTarget, &target, sizeof(target)));
|
||||
@@ -290,17 +293,31 @@ void Manager::HandleDuaRegistration(const Coap::Message &aMessage, const Ip6::Me
|
||||
VerifyOrExit(isPrimary, status = ThreadStatusTlv::kDuaNotPrimary);
|
||||
VerifyOrExit(Get<BackboneRouter::Leader>().IsDomainUnicast(target), status = ThreadStatusTlv::kDuaInvalid);
|
||||
|
||||
if (Tlv::FindUint32Tlv(aMessage, ThreadTlv::kLastTransactionTime, lastTransactionTime) == OT_ERROR_NONE)
|
||||
hasLastTransactionTime =
|
||||
(Tlv::FindUint32Tlv(aMessage, ThreadTlv::kLastTransactionTime, lastTransactionTime) == OT_ERROR_NONE);
|
||||
|
||||
switch (mNdProxyTable.Register(target.GetIid(), meshLocalIid, aMessageInfo.GetPeerAddr().GetIid().GetLocator(),
|
||||
hasLastTransactionTime ? &lastTransactionTime : nullptr))
|
||||
{
|
||||
// TODO: (DUA) hasLastTransactionTime = true;
|
||||
case OT_ERROR_NONE:
|
||||
// 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 OT_ERROR_DUPLICATED:
|
||||
status = ThreadStatusTlv::kDuaDuplicate;
|
||||
break;
|
||||
case OT_ERROR_NO_BUFS:
|
||||
status = ThreadStatusTlv::kDuaNoResources;
|
||||
break;
|
||||
default:
|
||||
status = ThreadStatusTlv::kDuaGeneralFailure;
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: (DUA) Add ND-PROXY table management
|
||||
// TODO: (DUA) Add DAD process
|
||||
// TODO: (DUA) Extended Address Query
|
||||
|
||||
exit:
|
||||
|
||||
otLogInfoBbr("Received DUA.req on %s: %s", (isPrimary ? "PBBR" : "SBBR"), otThreadErrorToString(error));
|
||||
|
||||
if (error == OT_ERROR_NONE)
|
||||
@@ -361,6 +378,32 @@ void Manager::ConfigNextMulticastListenerRegistrationResponse(ThreadStatusTlv::M
|
||||
}
|
||||
#endif
|
||||
|
||||
NdProxyTable &Manager::GetNdProxyTable(void)
|
||||
{
|
||||
return mNdProxyTable;
|
||||
}
|
||||
|
||||
bool Manager::ShouldForwardDuaToBackbone(const Ip6::Address &aAddress)
|
||||
{
|
||||
bool forwardToBackbone = false;
|
||||
Mac::ShortAddress rloc16;
|
||||
otError error;
|
||||
|
||||
VerifyOrExit(Get<Local>().IsPrimary(), OT_NOOP);
|
||||
VerifyOrExit(Get<Leader>().IsDomainUnicast(aAddress), OT_NOOP);
|
||||
|
||||
VerifyOrExit(!mNdProxyTable.IsRegistered(aAddress.GetIid()), OT_NOOP);
|
||||
|
||||
error = Get<AddressResolver>().Resolve(aAddress, rloc16, /* aAllowAddressQuery */ false);
|
||||
VerifyOrExit(error != OT_ERROR_NONE || rloc16 == Get<Mle::MleRouter>().GetRloc16(), OT_NOOP);
|
||||
|
||||
// TODO: check if the DUA is an address of any Child?
|
||||
forwardToBackbone = true;
|
||||
|
||||
exit:
|
||||
return forwardToBackbone;
|
||||
}
|
||||
|
||||
} // namespace BackboneRouter
|
||||
|
||||
} // namespace ot
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
#include "backbone_router/bbr_leader.hpp"
|
||||
#include "backbone_router/multicast_listeners_table.hpp"
|
||||
#include "backbone_router/ndproxy_table.hpp"
|
||||
#include "common/locator.hpp"
|
||||
#include "net/netif.hpp"
|
||||
#include "thread/network_data.hpp"
|
||||
@@ -67,6 +68,14 @@ public:
|
||||
*/
|
||||
explicit Manager(Instance &aInstance);
|
||||
|
||||
/**
|
||||
* This method returns the NdProxy Table.
|
||||
*
|
||||
* @returns The NdProxy Table.
|
||||
*
|
||||
*/
|
||||
NdProxyTable &GetNdProxyTable(void);
|
||||
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
/**
|
||||
* This method configures response status for next DUA registration.
|
||||
@@ -102,6 +111,18 @@ public:
|
||||
*/
|
||||
MulticastListenersTable &GetMulticastListenersTable(void) { return mMulticastListenersTable; }
|
||||
|
||||
/**
|
||||
* This method 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);
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
@@ -140,6 +161,7 @@ private:
|
||||
|
||||
Coap::Resource mMulticastListenerRegistration;
|
||||
Coap::Resource mDuaRegistration;
|
||||
NdProxyTable mNdProxyTable;
|
||||
|
||||
MulticastListenersTable mMulticastListenersTable;
|
||||
TimerMilli mTimer;
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* 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_ENABLE
|
||||
|
||||
#include "common/locator-getters.hpp"
|
||||
#include "common/logging.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
||||
namespace BackboneRouter {
|
||||
|
||||
void NdProxyTable::NdProxy::Init(const Ip6::InterfaceIdentifier &aAddressIid,
|
||||
const Ip6::InterfaceIdentifier &aMeshLocalIid,
|
||||
uint16_t aRloc16,
|
||||
uint32_t aTimeSinceLastTransaction)
|
||||
{
|
||||
OT_ASSERT(!mValid);
|
||||
|
||||
mValid = true;
|
||||
mAddressIid = aAddressIid;
|
||||
mMeshLocalIid = aMeshLocalIid;
|
||||
Update(aRloc16, aTimeSinceLastTransaction);
|
||||
}
|
||||
|
||||
void NdProxyTable::NdProxy::Update(uint16_t aRloc16, uint32_t aTimeSinceLastTransaction)
|
||||
{
|
||||
OT_ASSERT(mValid);
|
||||
|
||||
mRloc16 = aRloc16;
|
||||
aTimeSinceLastTransaction =
|
||||
OT_MIN(aTimeSinceLastTransaction, static_cast<uint32_t>(Mle::kTimeSinceLastTransactionMax));
|
||||
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;
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
NdProxyTable::Iterator::Iterator(Instance &aInstance, Filter aFilter)
|
||||
: InstanceLocator(aInstance)
|
||||
, mFilter(aFilter)
|
||||
{
|
||||
NdProxyTable &table = GetInstance().Get<BackboneRouter::NdProxyTable>();
|
||||
|
||||
mCurrent = &table.mProxies[0];
|
||||
|
||||
if (!MatchesFilter(*mCurrent, mFilter))
|
||||
{
|
||||
Advance();
|
||||
}
|
||||
}
|
||||
|
||||
NdProxyTable::Iterator::Iterator(Instance &aInstance, NdProxyTable::Iterator::IteratorType)
|
||||
: InstanceLocator(aInstance)
|
||||
{
|
||||
NdProxyTable &table = GetInstance().Get<BackboneRouter::NdProxyTable>();
|
||||
mCurrent = OT_ARRAY_END(table.mProxies);
|
||||
}
|
||||
|
||||
void NdProxyTable::Iterator::Advance(void)
|
||||
{
|
||||
NdProxyTable &table = GetInstance().Get<BackboneRouter::NdProxyTable>();
|
||||
|
||||
do
|
||||
{
|
||||
mCurrent++;
|
||||
} while (mCurrent < OT_ARRAY_END(table.mProxies) && !MatchesFilter(*mCurrent, mFilter));
|
||||
}
|
||||
|
||||
void NdProxyTable::Erase(NdProxy &aProxy)
|
||||
{
|
||||
aProxy.Clear();
|
||||
}
|
||||
|
||||
void NdProxyTable::HandleDomainPrefixUpdate(Leader::DomainPrefixState aState)
|
||||
{
|
||||
if (aState == Leader::kDomainPrefixAdded || aState == Leader::kDomainPrefixRemoved ||
|
||||
aState == Leader::kDomainPrefixRefreshed)
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void NdProxyTable::Clear(void)
|
||||
{
|
||||
for (NdProxy &proxy : mProxies)
|
||||
{
|
||||
proxy.Clear();
|
||||
}
|
||||
|
||||
otLogNoteBbr("NdProxyTable::Clear!");
|
||||
}
|
||||
|
||||
otError NdProxyTable::Register(const Ip6::InterfaceIdentifier &aAddressIid,
|
||||
const Ip6::InterfaceIdentifier &aMeshLocalIid,
|
||||
uint16_t aRloc16,
|
||||
const uint32_t * aTimeSinceLastTransaction)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
NdProxy *proxy = FindByAddressIid(aAddressIid);
|
||||
uint32_t timeSinceLastTransaction = aTimeSinceLastTransaction == nullptr ? 0 : *aTimeSinceLastTransaction;
|
||||
|
||||
if (proxy != nullptr)
|
||||
{
|
||||
VerifyOrExit(proxy->mMeshLocalIid == aMeshLocalIid, error = OT_ERROR_DUPLICATED);
|
||||
|
||||
proxy->Update(aRloc16, timeSinceLastTransaction);
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
proxy = FindByMeshLocalIid(aMeshLocalIid);
|
||||
if (proxy != nullptr)
|
||||
{
|
||||
Erase(*proxy);
|
||||
}
|
||||
else
|
||||
{
|
||||
proxy = FindInvalid();
|
||||
|
||||
// TODO: evict stale DUA entries to have room for this new DUA.
|
||||
VerifyOrExit(proxy != nullptr, error = OT_ERROR_NO_BUFS);
|
||||
}
|
||||
|
||||
proxy->Init(aAddressIid, aMeshLocalIid, aRloc16, timeSinceLastTransaction);
|
||||
|
||||
exit:
|
||||
otLogInfoBbr("NdProxyTable::Register %s MLIID %s RLOC16 %04x LTT %u => %s", aAddressIid.ToString().AsCString(),
|
||||
aMeshLocalIid.ToString().AsCString(), aRloc16, timeSinceLastTransaction, otThreadErrorToString(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:
|
||||
otLogDebgBbr("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:
|
||||
otLogDebgBbr("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:
|
||||
otLogDebgBbr("NdProxyTable::FindInvalid() => %s", found ? "OK" : "NOT_FOUND");
|
||||
return found;
|
||||
}
|
||||
|
||||
} // namespace BackboneRouter
|
||||
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* 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 NDPROXY_TABLE_HPP_
|
||||
#define NDPROXY_TABLE_HPP_
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
|
||||
#include <openthread/backbone_router_ftd.h>
|
||||
|
||||
#include "backbone_router/bbr_leader.hpp"
|
||||
#include "common/locator.hpp"
|
||||
#include "common/non_copyable.hpp"
|
||||
#include "common/time.hpp"
|
||||
#include "net/ip6_address.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
||||
namespace BackboneRouter {
|
||||
|
||||
/**
|
||||
* This class implements NdProxy Table maintenance on Primary Backbone Router.
|
||||
*
|
||||
*/
|
||||
class NdProxyTable : public InstanceLocator, private NonCopyable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes the `NdProxyTable` object.
|
||||
*
|
||||
* @param[in] aInstance A reference to the OpenThread instance.
|
||||
*
|
||||
*/
|
||||
explicit NdProxyTable(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method registers a given Ip6 address IID with related information to the NdProxy table.
|
||||
*
|
||||
* @param[in] aAddressIid The Ip6 address IID.
|
||||
* @param[in] aMeshLocalIid The Mesh-Local IID.
|
||||
* @param[in] aRloc16 The RLOC16.
|
||||
* @param[in] aTimeSinceLastTransaction Time since last transaction (in seconds).
|
||||
*
|
||||
* @retval OT_ERROR_NONE If registered successfully.
|
||||
* @retval OT_ERROR_DUPLICATED If the Ip6 address IID is a duplicate.
|
||||
* @retval OT_ERROR_NO_BUFS Insufficient buffer space available to register.
|
||||
*
|
||||
*/
|
||||
otError Register(const Ip6::InterfaceIdentifier &aAddressIid,
|
||||
const Ip6::InterfaceIdentifier &aMeshLocalIid,
|
||||
uint16_t aRloc16,
|
||||
const uint32_t * aTimeSinceLastTransaction);
|
||||
|
||||
/**
|
||||
* This method checks if a given Ip6 address IID was registered.
|
||||
*
|
||||
* @param[in] aAddressIid The Ip6 address IID.
|
||||
*
|
||||
* @retval TRUE If the Ip6 address IID was registered.
|
||||
* @retval FALSE If the Ip6 address IID was not registered.
|
||||
*
|
||||
*/
|
||||
bool IsRegistered(const Ip6::InterfaceIdentifier &aAddressIid) { return FindByAddressIid(aAddressIid) != nullptr; }
|
||||
|
||||
/**
|
||||
* This method notifies Domain Prefix status.
|
||||
*
|
||||
* @param[in] aState The Domain Prefix state or state change.
|
||||
*
|
||||
*/
|
||||
void HandleDomainPrefixUpdate(Leader::DomainPrefixState aState);
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kMaxNdProxyNum = OPENTHREAD_CONFIG_NDPROXY_TABLE_ENTRY_NUM,
|
||||
};
|
||||
|
||||
enum Filter : uint8_t
|
||||
{
|
||||
kFilterInvalid,
|
||||
kFilterValid,
|
||||
};
|
||||
|
||||
class NdProxy : private Clearable<NdProxy>
|
||||
{
|
||||
friend class NdProxyTable;
|
||||
|
||||
private:
|
||||
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);
|
||||
|
||||
Ip6::InterfaceIdentifier mAddressIid;
|
||||
Ip6::InterfaceIdentifier mMeshLocalIid;
|
||||
TimeMilli mLastRegistrationTime; ///< in milliseconds
|
||||
uint16_t mRloc16;
|
||||
bool mValid : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class represents an iterator for iterating through the NdProxy Table.
|
||||
*
|
||||
*/
|
||||
class Iterator : public InstanceLocator
|
||||
{
|
||||
friend class NdProxyTable;
|
||||
friend class IteratorBuilder;
|
||||
|
||||
private:
|
||||
enum IteratorType
|
||||
{
|
||||
kEndIterator,
|
||||
};
|
||||
|
||||
Iterator(Instance &aInstance, Filter aFilter);
|
||||
Iterator(Instance &aInstance, IteratorType);
|
||||
|
||||
bool IsDone(void) const { return (mCurrent == nullptr); }
|
||||
void Advance(void);
|
||||
void operator++(void) { Advance(); }
|
||||
void operator++(int) { Advance(); }
|
||||
const NdProxy &operator*(void)const { return *mCurrent; }
|
||||
bool operator==(const Iterator &aOther) const { return mCurrent == aOther.mCurrent; }
|
||||
bool operator!=(const Iterator &aOther) const { return !(*this == aOther); }
|
||||
NdProxy * operator->(void) { return mCurrent; }
|
||||
NdProxy & operator*(void) { return *mCurrent; }
|
||||
|
||||
NdProxy *mCurrent;
|
||||
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);
|
||||
static void Erase(NdProxy &aProxy);
|
||||
|
||||
NdProxy mProxies[kMaxNdProxyNum];
|
||||
};
|
||||
|
||||
} // namespace BackboneRouter
|
||||
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
|
||||
#endif // NDPROXY_TABLE_HPP_
|
||||
@@ -763,6 +763,10 @@ template <> inline BackboneRouter::MulticastListenersTable &Instance::Get(void)
|
||||
{
|
||||
return mThreadNetif.mBackboneRouterManager.GetMulticastListenersTable();
|
||||
}
|
||||
template <> inline BackboneRouter::NdProxyTable &Instance::Get(void)
|
||||
{
|
||||
return mThreadNetif.mBackboneRouterManager.GetNdProxyTable();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLR_ENABLE || OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
|
||||
|
||||
@@ -60,4 +60,17 @@
|
||||
#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
|
||||
|
||||
#endif // CONFIG_BACKBONE_ROUTER_H_
|
||||
|
||||
+12
-2
@@ -33,6 +33,9 @@
|
||||
|
||||
#include "ip6.hpp"
|
||||
|
||||
#include "backbone_router/bbr_leader.hpp"
|
||||
#include "backbone_router/bbr_local.hpp"
|
||||
#include "backbone_router/ndproxy_table.hpp"
|
||||
#include "common/code_utils.hpp"
|
||||
#include "common/debug.hpp"
|
||||
#include "common/instance.hpp"
|
||||
@@ -1217,7 +1220,7 @@ start:
|
||||
{
|
||||
uint8_t hopLimit;
|
||||
|
||||
if (!ShouldForwardToThread(messageInfo))
|
||||
if (!ShouldForwardToThread(messageInfo, aFromNcpHost))
|
||||
{
|
||||
// try passing to host
|
||||
error = ProcessReceiveCallback(aMessage, messageInfo, nextHeader, aFromNcpHost, Message::kTakeCustody);
|
||||
@@ -1267,8 +1270,10 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
bool Ip6::ShouldForwardToThread(const MessageInfo &aMessageInfo) const
|
||||
bool Ip6::ShouldForwardToThread(const MessageInfo &aMessageInfo, bool aFromNcpHost) const
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aFromNcpHost);
|
||||
|
||||
bool rval = false;
|
||||
|
||||
if (aMessageInfo.GetSockAddr().IsMulticast())
|
||||
@@ -1284,7 +1289,12 @@ bool Ip6::ShouldForwardToThread(const MessageInfo &aMessageInfo) const
|
||||
else if (IsOnLink(aMessageInfo.GetSockAddr()))
|
||||
{
|
||||
// on-link global address
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
ExitNow(rval = (aFromNcpHost ||
|
||||
!Get<BackboneRouter::Manager>().ShouldForwardDuaToBackbone(aMessageInfo.GetSockAddr())));
|
||||
#else
|
||||
ExitNow(rval = true);
|
||||
#endif
|
||||
}
|
||||
else if (Get<ThreadNetif>().RouteLookup(aMessageInfo.GetPeerAddr(), aMessageInfo.GetSockAddr(), nullptr) ==
|
||||
OT_ERROR_NONE)
|
||||
|
||||
@@ -358,7 +358,7 @@ private:
|
||||
otError RemoveMplOption(Message &aMessage);
|
||||
otError HandleOptions(Message &aMessage, Header &aHeader, bool &aForward);
|
||||
otError HandlePayload(Message &aMessage, MessageInfo &aMessageInfo, uint8_t aIpProto);
|
||||
bool ShouldForwardToThread(const MessageInfo &aMessageInfo) const;
|
||||
bool ShouldForwardToThread(const MessageInfo &aMessageInfo, bool aFromNcpHost) const;
|
||||
bool IsOnLink(const Address &aAddress) const;
|
||||
|
||||
bool mForwardingEnabled;
|
||||
|
||||
@@ -442,7 +442,7 @@ void AddressResolver::RestartAddressQueries(void)
|
||||
}
|
||||
}
|
||||
|
||||
otError AddressResolver::Resolve(const Ip6::Address &aEid, uint16_t &aRloc16)
|
||||
otError AddressResolver::Resolve(const Ip6::Address &aEid, Mac::ShortAddress &aRloc16, bool aAllowAddressQuery)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
CacheEntry * entry;
|
||||
@@ -457,6 +457,7 @@ otError AddressResolver::Resolve(const Ip6::Address &aEid, uint16_t &aRloc16)
|
||||
// allocate a new entry and perform address query. We do not
|
||||
// allow first-time address query entries to be evicted till
|
||||
// timeout.
|
||||
VerifyOrExit(aAllowAddressQuery, error = OT_ERROR_NOT_FOUND);
|
||||
|
||||
entry = NewCacheEntry(/* aSnoopedEntry */ false);
|
||||
VerifyOrExit(entry != nullptr, error = OT_ERROR_NO_BUFS);
|
||||
@@ -485,6 +486,11 @@ otError AddressResolver::Resolve(const Ip6::Address &aEid, uint16_t &aRloc16)
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
// Note that if `aAllowAddressQuery` is `false` then the `entry` is definitely already in a list, i.e., we cannot
|
||||
// not get here with `aAllowAddressQuery` being `false` and `entry` being a newly allocated one, due to the
|
||||
// `VerifyOrExit` check that `aAllowAddressQuery` is `true` before allocating a new cache entry.
|
||||
VerifyOrExit(aAllowAddressQuery, error = OT_ERROR_NOT_FOUND);
|
||||
|
||||
if (list == &mQueryList)
|
||||
{
|
||||
ExitNow(error = OT_ERROR_ADDRESS_QUERY);
|
||||
|
||||
@@ -153,18 +153,21 @@ public:
|
||||
void AddSnoopedCacheEntry(const Ip6::Address &aEid, Mac::ShortAddress aRloc16);
|
||||
|
||||
/**
|
||||
* This method returns the RLOC16 for a given EID, or initiates an Address Query if the mapping is not known.
|
||||
* This method returns the RLOC16 for a given EID, initiates an Address Query if allowed and the mapping is not
|
||||
* known.
|
||||
*
|
||||
* @param[in] aEid A reference to the EID.
|
||||
* @param[out] aRloc16 The RLOC16 corresponding to @p aEid.
|
||||
* @param[in] aEid A reference to the EID.
|
||||
* @param[out] aRloc16 The RLOC16 corresponding to @p aEid.
|
||||
* @param[in] aAllowAddressQuery Allow to initiate Address Query if the mapping is not known.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully provided the RLOC16.
|
||||
* @retval OT_ERROR_ADDRESS_QUERY Initiated an Address Query.
|
||||
* @retval OT_ERROR_ADDRESS_QUERY Initiated an Address Query if allowed.
|
||||
* @retval OT_ERROR_DROP Earlier Address Query for the EID timed out. In retry timeout interval.
|
||||
* @retval OT_ERROR_NO_BUFS Insufficient buffer space available to send Address Query.
|
||||
* @retval OT_ERROR_NOT_FOUND The mapping was not found and Address Query was not allowed.
|
||||
*
|
||||
*/
|
||||
otError Resolve(const Ip6::Address &aEid, Mac::ShortAddress &aRloc16);
|
||||
otError Resolve(const Ip6::Address &aEid, Mac::ShortAddress &aRloc16, bool aAllowAddressQuery = true);
|
||||
|
||||
/**
|
||||
* This method restarts any ongoing address queries.
|
||||
|
||||
@@ -268,6 +268,7 @@ enum
|
||||
KResponseTimeoutDelay = 30, ///< In seconds.
|
||||
kDuaDadPeriod = 100, ///< In seconds. Time period after which the address
|
||||
///< becomes "Preferred" if no duplicate address error.
|
||||
kTimeSinceLastTransactionMax = 10 * 86400, ///< In seconds (10 days).
|
||||
};
|
||||
|
||||
static_assert(kMlrTimeoutDefault >= kMlrTimeoutMin && kMlrTimeoutDefault <= kMlrTimeoutMax,
|
||||
@@ -276,6 +277,9 @@ static_assert(kMlrTimeoutDefault >= kMlrTimeoutMin && kMlrTimeoutDefault <= kMlr
|
||||
static_assert(Mle::kParentAggregateDelay > 1, "kParentAggregateDelay should be larger than 1 second");
|
||||
static_assert(kMlrTimeoutMax * 1000 > kMlrTimeoutMax, "SecToMsec(kMlrTimeoutMax) will overflow");
|
||||
|
||||
static_assert(kTimeSinceLastTransactionMax * 1000 > kTimeSinceLastTransactionMax,
|
||||
"SecToMsec(kTimeSinceLastTransactionMax) will overflow");
|
||||
|
||||
/**
|
||||
* State change of Child's DUA
|
||||
*
|
||||
|
||||
@@ -360,27 +360,50 @@ target_link_libraries(test-message-queue
|
||||
add_test(NAME test-message-queue COMMAND test-message-queue)
|
||||
|
||||
add_executable(test-multicast-listeners-table
|
||||
${COMMON_SOURCES}
|
||||
test_multicast_listeners_table.cpp
|
||||
)
|
||||
${COMMON_SOURCES}
|
||||
test_multicast_listeners_table.cpp
|
||||
)
|
||||
|
||||
target_include_directories(test-multicast-listeners-table
|
||||
PRIVATE
|
||||
PRIVATE
|
||||
${COMMON_INCLUDES}
|
||||
)
|
||||
)
|
||||
|
||||
target_compile_options(test-multicast-listeners-table
|
||||
PRIVATE
|
||||
PRIVATE
|
||||
${COMMON_COMPILE_OPTIONS}
|
||||
)
|
||||
)
|
||||
|
||||
target_link_libraries(test-multicast-listeners-table
|
||||
PRIVATE
|
||||
${COMMON_LIBS}
|
||||
)
|
||||
)
|
||||
|
||||
add_test(NAME test-multicast-listeners-table COMMAND test-multicast-listeners-table)
|
||||
|
||||
add_executable(test-ndproxy-table
|
||||
${COMMON_SOURCES}
|
||||
test_ndproxy_table.cpp
|
||||
)
|
||||
|
||||
target_include_directories(test-ndproxy-table
|
||||
PRIVATE
|
||||
${COMMON_INCLUDES}
|
||||
)
|
||||
|
||||
target_compile_options(test-ndproxy-table
|
||||
PRIVATE
|
||||
${COMMON_COMPILE_OPTIONS}
|
||||
)
|
||||
|
||||
|
||||
target_link_libraries(test-ndproxy-table
|
||||
PRIVATE
|
||||
${COMMON_LIBS}
|
||||
)
|
||||
|
||||
add_test(NAME test-ndproxy-table COMMAND test-ndproxy-table)
|
||||
|
||||
|
||||
add_executable(test-netif
|
||||
${COMMON_SOURCES}
|
||||
@@ -559,7 +582,7 @@ target_link_libraries(test-timer
|
||||
add_test(NAME test-timer COMMAND test-timer)
|
||||
|
||||
set_target_properties(
|
||||
test-aes test-checksum test-child test-child-table test-flash test-heap test-hmac-sha256 test-ip6-address test-link-quality test-linked-list test-lowpan test-mac-frame test-message test-message-queue test-multicast-listeners-table test-netif test-network-data test-pool test-priority-queue test-pskc test-steering-data test-string test-timer
|
||||
test-aes test-checksum test-child test-child-table test-flash test-heap test-hmac-sha256 test-ip6-address test-link-quality test-linked-list test-lowpan test-mac-frame test-message test-message-queue test-multicast-listeners-table test-ndproxy-table test-netif test-network-data test-pool test-priority-queue test-pskc test-steering-data test-string test-timer
|
||||
PROPERTIES
|
||||
C_STANDARD 99
|
||||
CXX_STANDARD 11
|
||||
|
||||
@@ -121,6 +121,7 @@ check_PROGRAMS += \
|
||||
test-message \
|
||||
test-message-queue \
|
||||
test-multicast-listeners-table \
|
||||
test-ndproxy-table \
|
||||
test-netif \
|
||||
test-network-data \
|
||||
test-pool \
|
||||
@@ -220,6 +221,9 @@ test_multicast_listeners_table_SOURCES = $(COMMON_SOURCES) test_multicast_listen
|
||||
test_spinel_buffer_LDADD = $(COMMON_LDADD)
|
||||
test_spinel_buffer_SOURCES = $(COMMON_SOURCES) test_spinel_buffer.cpp
|
||||
|
||||
test_ndproxy_table_LDADD = $(COMMON_LDADD)
|
||||
test_ndproxy_table_SOURCES = $(COMMON_SOURCES) test_ndproxy_table.cpp
|
||||
|
||||
test_netif_LDADD = $(COMMON_LDADD)
|
||||
test_netif_SOURCES = $(COMMON_SOURCES) test_netif.cpp
|
||||
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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_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 "common/instance.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
||||
static ot::Instance *sInstance;
|
||||
|
||||
using namespace ot::BackboneRouter;
|
||||
|
||||
Ip6::InterfaceIdentifier generateRandomIid(uint16_t aIndex)
|
||||
{
|
||||
Ip6::InterfaceIdentifier iid;
|
||||
|
||||
Random::NonCrypto::FillBuffer(iid.mFields.m8, sizeof(iid));
|
||||
iid.mFields.m16[3] = aIndex;
|
||||
|
||||
return iid;
|
||||
}
|
||||
|
||||
void TestNdProxyTable(void)
|
||||
{
|
||||
otError error;
|
||||
|
||||
sInstance = testInitInstance();
|
||||
VerifyOrQuit(sInstance != nullptr, "Null OpenThread instance");
|
||||
|
||||
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.
|
||||
error = table.Register(existedAddressIid, existedMeshLocalIid, 0, nullptr);
|
||||
VerifyOrQuit(error == OT_ERROR_NONE, "Register failed");
|
||||
VerifyOrQuit(table.IsRegistered(existedAddressIid), "should be registered");
|
||||
VerifyOrQuit(!table.IsRegistered(notExistAddressIid), "should not be registered");
|
||||
|
||||
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.
|
||||
error = table.Register(addressIid, meshLocalIid, i, nullptr);
|
||||
VerifyOrQuit(error == OT_ERROR_NONE, "Register failed");
|
||||
|
||||
VerifyOrQuit(table.IsRegistered(addressIid), "should be registered");
|
||||
|
||||
// Reregister the same address IID should always succeed.
|
||||
error = table.Register(addressIid, meshLocalIid, i, nullptr);
|
||||
VerifyOrQuit(error == OT_ERROR_NONE, "Register again failed");
|
||||
|
||||
// Register the same address IID with a different ML-IID should fail.
|
||||
error = table.Register(addressIid, notExistMeshLocalIid, i, nullptr);
|
||||
VerifyOrQuit(error == OT_ERROR_DUPLICATED, "Register duplicate should fail");
|
||||
|
||||
VerifyOrQuit(table.IsRegistered(addressIid), "should be registered");
|
||||
}
|
||||
|
||||
// Now the table is full, registering another IID should fail.
|
||||
error =
|
||||
table.Register(notExistAddressIid, notExistMeshLocalIid, OPENTHREAD_CONFIG_NDPROXY_TABLE_ENTRY_NUM, nullptr);
|
||||
VerifyOrQuit(error == OT_ERROR_NO_BUFS, "should fail with no bufs");
|
||||
VerifyOrQuit(!table.IsRegistered(notExistAddressIid), "should not be registered");
|
||||
}
|
||||
|
||||
} // namespace ot
|
||||
|
||||
int main(void)
|
||||
{
|
||||
ot::TestNdProxyTable();
|
||||
|
||||
printf("\nAll tests passed.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user