[network-data] simplify config definitions and implementations (#6596)

This commit adds a new header file `networks_data_type.hpp` and its
related `cpp` file which now contain all the Network Data related
types and config definitions (for on-mesh prefix, external route,
service, and server entries) and their implementation (moved from
`network_data.hpp`).

It adds `IsValid()`, `ConvertToTlvFlags()`, and `SetFromTlvFlags()` in
`OnMeshPrefixConfig` and `ExternalRouteConfig` to validate the config
and convert it to/from the corresponding TLV bitmask flags. These
changes help simplify the use of the configs by other classes.
This commit is contained in:
Abtin Keshavarzian 2021-05-12 15:07:08 -07:00 committed by GitHub
parent 6d48af2e59
commit daa10ed2d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 565 additions and 386 deletions

View File

@ -319,6 +319,7 @@ LOCAL_SRC_FILES := \
src/core/thread/network_data_local.cpp \
src/core/thread/network_data_notifier.cpp \
src/core/thread/network_data_service.cpp \
src/core/thread/network_data_types.cpp \
src/core/thread/network_diagnostic.cpp \
src/core/thread/panid_query_server.cpp \
src/core/thread/radio_selector.cpp \

View File

@ -590,6 +590,8 @@ openthread_core_files = [
"thread/network_data_service.cpp",
"thread/network_data_service.hpp",
"thread/network_data_tlvs.hpp",
"thread/network_data_types.cpp",
"thread/network_data_types.hpp",
"thread/network_diagnostic.cpp",
"thread/network_diagnostic.hpp",
"thread/network_diagnostic_tlvs.hpp",

View File

@ -193,6 +193,7 @@ set(COMMON_SOURCES
thread/network_data_local.cpp
thread/network_data_notifier.cpp
thread/network_data_service.cpp
thread/network_data_types.cpp
thread/network_diagnostic.cpp
thread/panid_query_server.cpp
thread/radio_selector.cpp

View File

@ -270,6 +270,7 @@ SOURCES_COMMON = \
thread/network_data_local.cpp \
thread/network_data_notifier.cpp \
thread/network_data_service.cpp \
thread/network_data_types.cpp \
thread/network_diagnostic.cpp \
thread/panid_query_server.cpp \
thread/radio_selector.cpp \
@ -532,6 +533,7 @@ HEADERS_COMMON = \
thread/network_data_notifier.hpp \
thread/network_data_service.hpp \
thread/network_data_tlvs.hpp \
thread/network_data_types.hpp \
thread/network_diagnostic.hpp \
thread/network_diagnostic_tlvs.hpp \
thread/panid_query_server.hpp \

View File

@ -70,7 +70,7 @@ otError otBorderRouterGetNetData(otInstance *aInstance, bool aStable, uint8_t *a
otError otBorderRouterAddOnMeshPrefix(otInstance *aInstance, const otBorderRouterConfig *aConfig)
{
Error error;
Error error = kErrorNone;
Instance & instance = *static_cast<Instance *>(aInstance);
const NetworkData::OnMeshPrefixConfig *config = static_cast<const NetworkData::OnMeshPrefixConfig *>(aConfig);
@ -79,16 +79,14 @@ otError otBorderRouterAddOnMeshPrefix(otInstance *aInstance, const otBorderRoute
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
if (aConfig->mDp)
{
SuccessOrExit(error = instance.Get<NetworkData::Local>().ValidateOnMeshPrefix(*config));
instance.Get<BackboneRouter::Local>().SetDomainPrefix(*config);
error = instance.Get<BackboneRouter::Local>().SetDomainPrefix(*config);
}
else
#endif
{
SuccessOrExit(error = instance.Get<NetworkData::Local>().AddOnMeshPrefix(*config));
error = instance.Get<NetworkData::Local>().AddOnMeshPrefix(*config);
}
exit:
return error;
}

View File

@ -310,8 +310,12 @@ exit:
return error;
}
void Local::SetDomainPrefix(const NetworkData::OnMeshPrefixConfig &aConfig)
Error Local::SetDomainPrefix(const NetworkData::OnMeshPrefixConfig &aConfig)
{
Error error = kErrorNone;
VerifyOrExit(aConfig.IsValid(GetInstance()), error = kErrorInvalidArgs);
if (IsEnabled())
{
RemoveDomainPrefixFromNetworkData();
@ -324,6 +328,9 @@ void Local::SetDomainPrefix(const NetworkData::OnMeshPrefixConfig &aConfig)
{
AddDomainPrefixToNetworkData();
}
exit:
return error;
}
void Local::ApplyMeshLocalPrefix(void)

View File

@ -42,6 +42,10 @@
#error "Thread 1.2 or higher version is required for OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE."
#endif
#if !OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
#error "OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE is required for OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE."
#endif
#if !OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
#error "OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE is required for OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE."
#endif
@ -205,8 +209,11 @@ public:
*
* @param[in] aConfig A reference to the Domain Prefix configuration.
*
* @returns kErrorNone Successfully set the local Domain Prefix.
* @returns kErrorInvalidArgs @p aConfig is invalid.
*
*/
void SetDomainPrefix(const NetworkData::OnMeshPrefixConfig &aConfig);
Error SetDomainPrefix(const NetworkData::OnMeshPrefixConfig &aConfig);
/**
* This method returns a reference to the All Network Backbone Routers Multicast Address.

View File

@ -47,73 +47,6 @@
namespace ot {
namespace NetworkData {
void OnMeshPrefixConfig::SetFrom(const PrefixTlv & aPrefixTlv,
const BorderRouterTlv & aBorderRouterTlv,
const BorderRouterEntry &aBorderRouterEntry)
{
Clear();
aPrefixTlv.CopyPrefixTo(GetPrefix());
mPreference = aBorderRouterEntry.GetPreference();
mPreferred = aBorderRouterEntry.IsPreferred();
mSlaac = aBorderRouterEntry.IsSlaac();
mDhcp = aBorderRouterEntry.IsDhcp();
mConfigure = aBorderRouterEntry.IsConfigure();
mDefaultRoute = aBorderRouterEntry.IsDefaultRoute();
mOnMesh = aBorderRouterEntry.IsOnMesh();
mStable = aBorderRouterTlv.IsStable();
mRloc16 = aBorderRouterEntry.GetRloc();
mNdDns = aBorderRouterEntry.IsNdDns();
mDp = aBorderRouterEntry.IsDp();
}
void ExternalRouteConfig::SetFrom(Instance & aInstance,
const PrefixTlv & aPrefixTlv,
const HasRouteTlv & aHasRouteTlv,
const HasRouteEntry &aHasRouteEntry)
{
Clear();
aPrefixTlv.CopyPrefixTo(GetPrefix());
mPreference = aHasRouteEntry.GetPreference();
mNat64 = aHasRouteEntry.IsNat64();
mStable = aHasRouteTlv.IsStable();
mRloc16 = aHasRouteEntry.GetRloc();
mNextHopIsThisDevice = (aHasRouteEntry.GetRloc() == aInstance.Get<Mle::MleRouter>().GetRloc16());
}
bool ServiceConfig::ServerConfig::operator==(const ServerConfig &aOther) const
{
return (mStable == aOther.mStable) && (mServerDataLength == aOther.mServerDataLength) &&
(memcmp(mServerData, aOther.mServerData, mServerDataLength) == 0);
}
void ServiceConfig::ServerConfig::SetFrom(const ServerTlv &aServerTlv)
{
mStable = aServerTlv.IsStable();
mRloc16 = aServerTlv.GetServer16();
mServerDataLength = aServerTlv.GetServerDataLength();
memcpy(&mServerData, aServerTlv.GetServerData(), mServerDataLength);
}
bool ServiceConfig::operator==(const ServiceConfig &aOther) const
{
return (mEnterpriseNumber == aOther.mEnterpriseNumber) && (mServiceDataLength == aOther.mServiceDataLength) &&
(memcmp(mServiceData, aOther.mServiceData, mServiceDataLength) == 0) &&
(GetServerConfig() == aOther.GetServerConfig());
}
void ServiceConfig::SetFrom(const ServiceTlv &aServiceTlv, const ServerTlv &aServerTlv)
{
Clear();
mServiceId = aServiceTlv.GetServiceId();
mEnterpriseNumber = aServiceTlv.GetEnterpriseNumber();
mServiceDataLength = aServiceTlv.GetServiceDataLength();
memcpy(&mServiceData, aServiceTlv.GetServiceData(), mServiceDataLength);
GetServerConfig().SetFrom(aServerTlv);
}
NetworkData::NetworkData(Instance &aInstance, Type aType)
: InstanceLocator(aInstance)
, mType(aType)

View File

@ -48,6 +48,7 @@
#include "thread/lowpan.hpp"
#include "thread/mle_router.hpp"
#include "thread/network_data_tlvs.hpp"
#include "thread/network_data_types.hpp"
namespace ot {
@ -101,145 +102,6 @@ enum
*/
typedef otNetworkDataIterator Iterator;
/**
* This class represents an On Mesh Prefix (Border Router) configuration.
*
*/
class OnMeshPrefixConfig : public otBorderRouterConfig,
public Clearable<OnMeshPrefixConfig>,
public Equatable<OnMeshPrefixConfig>
{
friend class NetworkData;
public:
/**
* This method gets the prefix.
*
* @return The prefix.
*
*/
const Ip6::Prefix &GetPrefix(void) const { return static_cast<const Ip6::Prefix &>(mPrefix); }
/**
* This method gets the prefix.
*
* @return The prefix.
*
*/
Ip6::Prefix &GetPrefix(void) { return static_cast<Ip6::Prefix &>(mPrefix); }
private:
void SetFrom(const PrefixTlv & aPrefixTlv,
const BorderRouterTlv & aBorderRouterTlv,
const BorderRouterEntry &aBorderRouterEntry);
};
/**
* This class represents an External Route configuration.
*
*/
class ExternalRouteConfig : public otExternalRouteConfig,
public Clearable<ExternalRouteConfig>,
public Equatable<ExternalRouteConfig>
{
friend class NetworkData;
public:
/**
* This method gets the prefix.
*
* @return The prefix.
*
*/
const Ip6::Prefix &GetPrefix(void) const { return static_cast<const Ip6::Prefix &>(mPrefix); }
/**
* This method gets the prefix.
*
* @return The prefix.
*
*/
Ip6::Prefix &GetPrefix(void) { return static_cast<Ip6::Prefix &>(mPrefix); }
/**
* This method sets the prefix.
*
* @param[in] aPrefix The prefix to set to.
*
*/
void SetPrefix(const Ip6::Prefix &aPrefix) { mPrefix = aPrefix; }
private:
void SetFrom(Instance & aInstance,
const PrefixTlv & aPrefixTlv,
const HasRouteTlv & aHasRouteTlv,
const HasRouteEntry &aHasRouteEntry);
};
/**
* This type represents a Service configuration.
*
*/
class ServiceConfig : public otServiceConfig, public Clearable<ServiceConfig>, public Unequatable<ServiceConfig>
{
friend class NetworkData;
public:
/**
* This class represents a Server configuration.
*
*/
class ServerConfig : public otServerConfig, public Unequatable<ServerConfig>
{
friend class ServiceConfig;
public:
/**
* This method overloads operator `==` to evaluate whether or not two `ServerConfig` instances are equal.
*
* @param[in] aOther The other `ServerConfig` instance to compare with.
*
* @retval TRUE If the two `ServerConfig` instances are equal.
* @retval FALSE If the two `ServerConfig` instances are not equal.
*
*/
bool operator==(const ServerConfig &aOther) const;
private:
void SetFrom(const ServerTlv &aServerTlv);
};
/**
* This method gets the Server configuration.
*
* @returns The Server configuration.
*
*/
const ServerConfig &GetServerConfig(void) const { return static_cast<const ServerConfig &>(mServerConfig); }
/**
* This method gets the Server configuration.
*
* @returns The Server configuration.
*
*/
ServerConfig &GetServerConfig(void) { return static_cast<ServerConfig &>(mServerConfig); }
/**
* This method overloads operator `==` to evaluate whether or not two `ServiceConfig` instances are equal.
*
* @param[in] aOther The other `ServiceConfig` instance to compare with.
*
* @retval TRUE If the two `ServiceConfig` instances are equal.
* @retval FALSE If the two `ServiceConfig` instances are not equal.
*
*/
bool operator==(const ServiceConfig &aOther) const;
private:
void SetFrom(const ServiceTlv &aServiceTlv, const ServerTlv &aServerTlv);
};
/**
* This class implements Network Data processing.
*

View File

@ -54,77 +54,15 @@ Local::Local(Instance &aInstance)
}
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
Error Local::ValidateOnMeshPrefix(const OnMeshPrefixConfig &aConfig)
{
Error error = kErrorNone;
// Add Prefix validation check:
// Thread 1.1 Specification 5.13.2 says
// "A valid prefix MUST NOT allow both DHCPv6 and SLAAC for address configuration"
VerifyOrExit(!aConfig.mDhcp || !aConfig.mSlaac, error = kErrorInvalidArgs);
// RFC 4944 Section 6 says:
// An IPv6 address prefix used for stateless autoconfiguration [RFC4862]
// of an IEEE 802.15.4 interface MUST have a length of 64 bits.
VerifyOrExit(!aConfig.mSlaac || aConfig.mPrefix.mLength == OT_IP6_PREFIX_BITSIZE, error = kErrorInvalidArgs);
SuccessOrExit(error = ValidatePrefixAndPreference(aConfig.GetPrefix(), aConfig.mPreference));
exit:
return error;
}
Error Local::AddOnMeshPrefix(const OnMeshPrefixConfig &aConfig)
{
uint16_t flags = 0;
Error error = kErrorNone;
Error error = kErrorInvalidArgs;
SuccessOrExit(error = ValidateOnMeshPrefix(aConfig));
if (aConfig.mPreferred)
{
flags |= BorderRouterEntry::kPreferredFlag;
}
if (aConfig.mSlaac)
{
flags |= BorderRouterEntry::kSlaacFlag;
}
if (aConfig.mDhcp)
{
flags |= BorderRouterEntry::kDhcpFlag;
}
if (aConfig.mConfigure)
{
flags |= BorderRouterEntry::kConfigureFlag;
}
if (aConfig.mDefaultRoute)
{
flags |= BorderRouterEntry::kDefaultRouteFlag;
}
if (aConfig.mOnMesh)
{
flags |= BorderRouterEntry::kOnMeshFlag;
}
if (aConfig.mNdDns)
{
flags |= BorderRouterEntry::kNdDnsFlag;
}
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
if (aConfig.mDp)
{
flags |= BorderRouterEntry::kDpFlag;
}
#endif
VerifyOrExit(aConfig.IsValid(GetInstance()));
error =
AddPrefix(aConfig.GetPrefix(), NetworkDataTlv::kTypeBorderRouter, aConfig.mPreference, flags, aConfig.mStable);
AddPrefix(aConfig.GetPrefix(), NetworkDataTlv::kTypeBorderRouter, aConfig.ConvertToTlvFlags(), aConfig.mStable);
exit:
return error;
@ -135,40 +73,13 @@ Error Local::RemoveOnMeshPrefix(const Ip6::Prefix &aPrefix)
return RemovePrefix(aPrefix, NetworkDataTlv::kTypeBorderRouter);
}
Error Local::ValidatePrefixAndPreference(const Ip6::Prefix &aPrefix, int8_t aPrf)
{
Error error = kErrorNone;
VerifyOrExit((aPrefix.GetLength() > 0) && aPrefix.IsValid(), error = kErrorInvalidArgs);
switch (aPrf)
{
case OT_ROUTE_PREFERENCE_LOW:
case OT_ROUTE_PREFERENCE_MED:
case OT_ROUTE_PREFERENCE_HIGH:
break;
default:
ExitNow(error = kErrorInvalidArgs);
}
// Check if the prefix overlaps mesh-local prefix.
VerifyOrExit(!aPrefix.ContainsPrefix(Get<Mle::MleRouter>().GetMeshLocalPrefix()), error = kErrorInvalidArgs);
exit:
return error;
}
Error Local::AddHasRoutePrefix(const ExternalRouteConfig &aConfig)
{
Error error;
uint8_t flags = 0;
Error error = kErrorInvalidArgs;
if (aConfig.mNat64)
{
VerifyOrExit(aConfig.GetPrefix().IsValidNat64(), error = kErrorInvalidArgs);
flags |= HasRouteEntry::kNat64Flag;
}
VerifyOrExit(aConfig.IsValid(GetInstance()));
error = AddPrefix(aConfig.GetPrefix(), NetworkDataTlv::kTypeHasRoute, aConfig.mPreference, flags, aConfig.mStable);
error = AddPrefix(aConfig.GetPrefix(), NetworkDataTlv::kTypeHasRoute, aConfig.ConvertToTlvFlags(), aConfig.mStable);
exit:
return error;
@ -179,18 +90,12 @@ Error Local::RemoveHasRoutePrefix(const Ip6::Prefix &aPrefix)
return RemovePrefix(aPrefix, NetworkDataTlv::kTypeHasRoute);
}
Error Local::AddPrefix(const Ip6::Prefix & aPrefix,
NetworkDataTlv::Type aSubTlvType,
int8_t aPrf,
uint16_t aFlags,
bool aStable)
Error Local::AddPrefix(const Ip6::Prefix &aPrefix, NetworkDataTlv::Type aSubTlvType, uint16_t aFlags, bool aStable)
{
Error error = kErrorNone;
uint8_t subTlvLength;
PrefixTlv *prefixTlv;
SuccessOrExit(error = ValidatePrefixAndPreference(aPrefix, aPrf));
IgnoreError(RemovePrefix(aPrefix, aSubTlvType));
subTlvLength = (aSubTlvType == NetworkDataTlv::kTypeBorderRouter)
@ -209,7 +114,6 @@ Error Local::AddPrefix(const Ip6::Prefix & aPrefix,
brTlv->Init();
brTlv->SetLength(brTlv->GetLength() + sizeof(BorderRouterEntry));
brTlv->GetEntry(0)->Init();
brTlv->GetEntry(0)->SetPreference(aPrf);
brTlv->GetEntry(0)->SetFlags(aFlags);
}
else // aSubTlvType is NetworkDataTlv::kTypeHasRoute
@ -218,7 +122,6 @@ Error Local::AddPrefix(const Ip6::Prefix & aPrefix,
hasRouteTlv->Init();
hasRouteTlv->SetLength(hasRouteTlv->GetLength() + sizeof(HasRouteEntry));
hasRouteTlv->GetEntry(0)->Init();
hasRouteTlv->GetEntry(0)->SetPreference(aPrf);
hasRouteTlv->GetEntry(0)->SetFlags(static_cast<uint8_t>(aFlags));
}

View File

@ -1,4 +1,3 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
@ -83,17 +82,6 @@ public:
*/
Error AddOnMeshPrefix(const OnMeshPrefixConfig &aConfig);
/**
* This method validates an on-mesh prefix.
*
* @param[in] aConfig A reference to the on-mesh perfix configuration.
*
* @retval kErrorNone Successfully verified the on-mesh prefix.
* @retval kErrorInvalidArgs The prefix is not a valid on-mesh prefix.
*
*/
Error ValidateOnMeshPrefix(const OnMeshPrefixConfig &aConfig);
/**
* This method removes a Border Router entry from the Thread Network Data.
*
@ -182,12 +170,7 @@ public:
private:
void UpdateRloc(void);
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
Error ValidatePrefixAndPreference(const Ip6::Prefix &aPrefix, int8_t aPrf);
Error AddPrefix(const Ip6::Prefix & aPrefix,
NetworkDataTlv::Type aSubTlvType,
int8_t aPrf,
uint16_t aFlags,
bool aStable);
Error AddPrefix(const Ip6::Prefix &aPrefix, NetworkDataTlv::Type aSubTlvType, uint16_t aFlags, bool aStable);
Error RemovePrefix(const Ip6::Prefix &aPrefix, NetworkDataTlv::Type aSubTlvType);
void UpdateRloc(PrefixTlv &aPrefixTlv);
bool IsOnMeshPrefixConsistent(void) const;

View File

@ -42,6 +42,7 @@
#include "common/encoding.hpp"
#include "common/equatable.hpp"
#include "net/ip6_address.hpp"
#include "thread/network_data_types.hpp"
namespace ot {
namespace NetworkData {
@ -226,12 +227,9 @@ private:
OT_TOOL_PACKED_BEGIN
class HasRouteEntry : public Equatable<HasRouteEntry>
{
public:
enum : uint8_t
{
kNat64Flag = 1 << 5, // NAT64 flag.
};
friend class ExternalRouteConfig;
public:
/**
* This method initializes the header.
*
@ -265,26 +263,13 @@ public:
*/
int8_t GetPreference(void) const { return static_cast<int8_t>(mFlags) >> kPreferenceOffset; }
/**
* This method sets the Preference value.
*
* @param[in] aPrf The Preference value.
*
*/
void SetPreference(int8_t aPrf)
{
OT_ASSERT((aPrf == OT_ROUTE_PREFERENCE_LOW) || (aPrf == OT_ROUTE_PREFERENCE_MED) ||
(aPrf == OT_ROUTE_PREFERENCE_HIGH));
mFlags = (mFlags & ~kPreferenceMask) | ((static_cast<uint8_t>(aPrf) << kPreferenceOffset) & kPreferenceMask);
}
/**
* This method gets the Flags value.
*
* @returns The Flags value.
*
*/
uint16_t GetFlags(void) const { return (mFlags & ~kPreferenceMask); }
uint8_t GetFlags(void) const { return mFlags; }
/**
* This method sets the Flags value.
@ -292,7 +277,7 @@ public:
* @param[in] aFlags The Flags value.
*
*/
void SetFlags(uint8_t aFlags) { mFlags = (mFlags & kPreferenceMask) | (aFlags & ~kPreferenceMask); }
void SetFlags(uint8_t aFlags) { mFlags = aFlags; }
/**
* This method indicates whether or not the NAT64 flag is set.
@ -320,10 +305,11 @@ public:
const HasRouteEntry *GetNext(void) const { return (this + 1); }
private:
enum
enum : uint8_t
{
kPreferenceOffset = 6,
kPreferenceMask = 3 << kPreferenceOffset,
kNat64Flag = 1 << 5,
};
uint16_t mRloc;
@ -629,21 +615,9 @@ private:
OT_TOOL_PACKED_BEGIN
class BorderRouterEntry : public Equatable<BorderRouterEntry>
{
public:
enum
{
kPreferenceOffset = 14,
kPreferenceMask = 3 << kPreferenceOffset,
kPreferredFlag = 1 << 13,
kSlaacFlag = 1 << 12,
kDhcpFlag = 1 << 11,
kConfigureFlag = 1 << 10,
kDefaultRouteFlag = 1 << 9,
kOnMeshFlag = 1 << 8,
kNdDnsFlag = 1 << 7,
kDpFlag = 1 << 6,
};
friend class OnMeshPrefixConfig;
public:
/**
* This method initializes the TLV.
*
@ -675,7 +649,7 @@ public:
* @returns The Flags value.
*
*/
uint16_t GetFlags(void) const { return HostSwap16(mFlags) & ~kPreferenceMask; }
uint16_t GetFlags(void) const { return HostSwap16(mFlags); }
/**
* This method sets the Flags value.
@ -683,10 +657,7 @@ public:
* @param[in] aFlags The Flags value.
*
*/
void SetFlags(uint16_t aFlags)
{
mFlags = HostSwap16((HostSwap16(mFlags) & kPreferenceMask) | (aFlags & ~kPreferenceMask));
}
void SetFlags(uint16_t aFlags) { mFlags = HostSwap16(aFlags); }
/**
* This method returns the Preference value.
@ -699,17 +670,6 @@ public:
return static_cast<int8_t>(static_cast<int16_t>(HostSwap16(mFlags)) >> kPreferenceOffset);
}
/**
* This method sets the Preference value.
*
* @param[in] aPrf The Preference value.
*
*/
void SetPreference(int8_t aPrf)
{
mFlags = HostSwap16(GetFlags() | ((static_cast<uint16_t>(aPrf) << kPreferenceOffset) & kPreferenceMask));
}
/**
* This method indicates whether or not the Preferred flag is set.
*
@ -799,6 +759,24 @@ public:
const BorderRouterEntry *GetNext(void) const { return (this + 1); }
private:
enum : uint8_t
{
kPreferenceOffset = 14,
};
enum : uint16_t
{
kPreferenceMask = 3 << kPreferenceOffset,
kPreferredFlag = 1 << 13,
kSlaacFlag = 1 << 12,
kDhcpFlag = 1 << 11,
kConfigureFlag = 1 << 10,
kDefaultRouteFlag = 1 << 9,
kOnMeshFlag = 1 << 8,
kNdDnsFlag = 1 << 7,
kDpFlag = 1 << 6,
};
uint16_t mRloc;
uint16_t mFlags;
} OT_TOOL_PACKED_END;

View File

@ -0,0 +1,252 @@
/*
* Copyright (c) 2016-21, 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 Network Data related types and constants.
*/
#include "network_data_types.hpp"
#include "common/instance.hpp"
#include "thread/network_data_tlvs.hpp"
namespace ot {
namespace NetworkData {
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
static bool IsPreferenceValid(int8_t aPrf)
{
return (aPrf == OT_ROUTE_PREFERENCE_LOW) || (aPrf == OT_ROUTE_PREFERENCE_MED) || (aPrf == OT_ROUTE_PREFERENCE_HIGH);
}
static bool IsPrefixValid(Instance &aInstance, const Ip6::Prefix &aPrefix)
{
// Check that prefix length is within the valid range and the prefix
// does not overlap with the mesh-local prefix.
return (aPrefix.GetLength() > 0) && aPrefix.IsValid() &&
!aPrefix.ContainsPrefix(aInstance.Get<Mle::Mle>().GetMeshLocalPrefix());
}
bool OnMeshPrefixConfig::IsValid(Instance &aInstance) const
{
bool isValid = false;
if (mDhcp && mSlaac)
{
// A valid prefix MUST NOT allow both DHCPv6 and SLAAC for
// address configuration.
ExitNow();
}
if (mSlaac)
{
// An IPv6 address prefix used for stateless auto-configuration
// [RFC4862] of an IEEE 802.15.4 interface MUST have a length of
// 64 bits.
VerifyOrExit(GetPrefix().GetLength() == Ip6::NetworkPrefix::kLength);
}
VerifyOrExit(IsPreferenceValid(mPreference));
VerifyOrExit(IsPrefixValid(aInstance, GetPrefix()));
isValid = true;
exit:
return isValid;
}
uint16_t OnMeshPrefixConfig::ConvertToTlvFlags(void) const
{
uint16_t flags = 0;
if (mPreferred)
{
flags |= BorderRouterEntry::kPreferredFlag;
}
if (mSlaac)
{
flags |= BorderRouterEntry::kSlaacFlag;
}
if (mDhcp)
{
flags |= BorderRouterEntry::kDhcpFlag;
}
if (mConfigure)
{
flags |= BorderRouterEntry::kConfigureFlag;
}
if (mDefaultRoute)
{
flags |= BorderRouterEntry::kDefaultRouteFlag;
}
if (mOnMesh)
{
flags |= BorderRouterEntry::kOnMeshFlag;
}
if (mNdDns)
{
flags |= BorderRouterEntry::kNdDnsFlag;
}
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
if (mDp)
{
flags |= BorderRouterEntry::kDpFlag;
}
#endif
flags |= (static_cast<uint16_t>(mPreference) << BorderRouterEntry::kPreferenceOffset);
return flags;
}
#endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
void OnMeshPrefixConfig::SetFrom(const PrefixTlv & aPrefixTlv,
const BorderRouterTlv & aBorderRouterTlv,
const BorderRouterEntry &aBorderRouterEntry)
{
Clear();
aPrefixTlv.CopyPrefixTo(GetPrefix());
SetFromTlvFlags(aBorderRouterEntry.GetFlags());
mRloc16 = aBorderRouterEntry.GetRloc();
mStable = aBorderRouterTlv.IsStable();
}
void OnMeshPrefixConfig::SetFromTlvFlags(uint16_t aFlags)
{
mPreferred = ((aFlags & BorderRouterEntry::kPreferredFlag) != 0);
mSlaac = ((aFlags & BorderRouterEntry::kSlaacFlag) != 0);
mDhcp = ((aFlags & BorderRouterEntry::kDhcpFlag) != 0);
mConfigure = ((aFlags & BorderRouterEntry::kConfigureFlag) != 0);
mDefaultRoute = ((aFlags & BorderRouterEntry::kDefaultRouteFlag) != 0);
mOnMesh = ((aFlags & BorderRouterEntry::kOnMeshFlag) != 0);
mNdDns = ((aFlags & BorderRouterEntry::kNdDnsFlag) != 0);
mDp = ((aFlags & BorderRouterEntry::kDpFlag) != 0);
mPreference = static_cast<int8_t>(aFlags >> BorderRouterEntry::kPreferenceOffset);
}
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
bool ExternalRouteConfig::IsValid(Instance &aInstance) const
{
bool isValid = false;
if (mNat64)
{
VerifyOrExit(GetPrefix().IsValidNat64());
}
VerifyOrExit(IsPreferenceValid(mPreference));
VerifyOrExit(IsPrefixValid(aInstance, GetPrefix()));
isValid = true;
exit:
return isValid;
}
uint8_t ExternalRouteConfig::ConvertToTlvFlags(void) const
{
uint8_t flags = 0;
if (mNat64)
{
flags |= HasRouteEntry::kNat64Flag;
}
flags |= (static_cast<uint8_t>(mPreference) << HasRouteEntry::kPreferenceOffset);
return flags;
}
#endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
void ExternalRouteConfig::SetFrom(Instance & aInstance,
const PrefixTlv & aPrefixTlv,
const HasRouteTlv & aHasRouteTlv,
const HasRouteEntry &aHasRouteEntry)
{
Clear();
aPrefixTlv.CopyPrefixTo(GetPrefix());
SetFromTlvFlags(aHasRouteEntry.GetFlags());
mStable = aHasRouteTlv.IsStable();
mRloc16 = aHasRouteEntry.GetRloc();
mNextHopIsThisDevice = (aHasRouteEntry.GetRloc() == aInstance.Get<Mle::MleRouter>().GetRloc16());
}
void ExternalRouteConfig::SetFromTlvFlags(uint8_t aFlags)
{
mNat64 = ((aFlags & HasRouteEntry::kNat64Flag) != 0);
mPreference = static_cast<int8_t>(aFlags >> HasRouteEntry::kPreferenceOffset);
}
bool ServiceConfig::ServerConfig::operator==(const ServerConfig &aOther) const
{
return (mStable == aOther.mStable) && (mServerDataLength == aOther.mServerDataLength) &&
(memcmp(mServerData, aOther.mServerData, mServerDataLength) == 0);
}
void ServiceConfig::ServerConfig::SetFrom(const ServerTlv &aServerTlv)
{
mStable = aServerTlv.IsStable();
mRloc16 = aServerTlv.GetServer16();
mServerDataLength = aServerTlv.GetServerDataLength();
memcpy(&mServerData, aServerTlv.GetServerData(), mServerDataLength);
}
bool ServiceConfig::operator==(const ServiceConfig &aOther) const
{
return (mEnterpriseNumber == aOther.mEnterpriseNumber) && (mServiceDataLength == aOther.mServiceDataLength) &&
(memcmp(mServiceData, aOther.mServiceData, mServiceDataLength) == 0) &&
(GetServerConfig() == aOther.GetServerConfig());
}
void ServiceConfig::SetFrom(const ServiceTlv &aServiceTlv, const ServerTlv &aServerTlv)
{
Clear();
mServiceId = aServiceTlv.GetServiceId();
mEnterpriseNumber = aServiceTlv.GetEnterpriseNumber();
mServiceDataLength = aServiceTlv.GetServiceDataLength();
memcpy(&mServiceData, aServiceTlv.GetServiceData(), mServiceDataLength);
GetServerConfig().SetFrom(aServerTlv);
}
} // namespace NetworkData
} // namespace ot

View File

@ -0,0 +1,250 @@
/*
* Copyright (c) 2016-21, 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 Network Data types and constants.
*/
#ifndef NETWORK_DATA_TYPES_HPP_
#define NETWORK_DATA_TYPES_HPP_
#include "openthread-core-config.h"
#include <openthread/netdata.h>
#include "common/clearable.hpp"
#include "common/equatable.hpp"
#include "net/ip6_address.hpp"
namespace ot {
class Instance;
namespace NetworkData {
/**
* @addtogroup core-netdata-core
*
*/
// Forward declarations
class NetworkData;
class Local;
class PrefixTlv;
class BorderRouterTlv;
class BorderRouterEntry;
class HasRouteTlv;
class HasRouteEntry;
class ServiceTlv;
class ServerTlv;
/**
* This class represents an On-mesh Prefix (Border Router) configuration.
*
*/
class OnMeshPrefixConfig : public otBorderRouterConfig,
public Clearable<OnMeshPrefixConfig>,
public Equatable<OnMeshPrefixConfig>
{
friend class NetworkData;
friend class Local;
public:
/**
* This method gets the prefix.
*
* @return The prefix.
*
*/
const Ip6::Prefix &GetPrefix(void) const { return static_cast<const Ip6::Prefix &>(mPrefix); }
/**
* This method gets the prefix.
*
* @return The prefix.
*
*/
Ip6::Prefix &GetPrefix(void) { return static_cast<Ip6::Prefix &>(mPrefix); }
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
/**
* This method indicates whether or not the prefix configuration is valid.
*
* @param[in] aInstance A reference to the OpenThread instance.
*
* @retval TRUE The config is a valid on-mesh prefix.
* @retval FALSE The config is not a valid on-mesh prefix.
*
*/
bool IsValid(Instance &aInstance) const;
#endif
private:
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
uint16_t ConvertToTlvFlags(void) const;
#endif
void SetFrom(const PrefixTlv & aPrefixTlv,
const BorderRouterTlv & aBorderRouterTlv,
const BorderRouterEntry &aBorderRouterEntry);
void SetFromTlvFlags(uint16_t aFlags);
};
/**
* This class represents an External Route configuration.
*
*/
class ExternalRouteConfig : public otExternalRouteConfig,
public Clearable<ExternalRouteConfig>,
public Equatable<ExternalRouteConfig>
{
friend class NetworkData;
friend class Local;
public:
/**
* This method gets the prefix.
*
* @return The prefix.
*
*/
const Ip6::Prefix &GetPrefix(void) const { return static_cast<const Ip6::Prefix &>(mPrefix); }
/**
* This method gets the prefix.
*
* @return The prefix.
*
*/
Ip6::Prefix &GetPrefix(void) { return static_cast<Ip6::Prefix &>(mPrefix); }
/**
* This method sets the prefix.
*
* @param[in] aPrefix The prefix to set to.
*
*/
void SetPrefix(const Ip6::Prefix &aPrefix) { mPrefix = aPrefix; }
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
/**
* This method indicates whether or not the external route configuration is valid.
*
* @param[in] aInstance A reference to the OpenThread instance.
*
* @retval TRUE The config is a valid external route.
* @retval FALSE The config is not a valid extern route.
*
*/
bool IsValid(Instance &aInstance) const;
#endif
private:
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
uint8_t ConvertToTlvFlags(void) const;
#endif
void SetFrom(Instance & aInstance,
const PrefixTlv & aPrefixTlv,
const HasRouteTlv & aHasRouteTlv,
const HasRouteEntry &aHasRouteEntry);
void SetFromTlvFlags(uint8_t aFlags);
};
/**
* This type represents a Service configuration.
*
*/
class ServiceConfig : public otServiceConfig, public Clearable<ServiceConfig>, public Unequatable<ServiceConfig>
{
friend class NetworkData;
public:
/**
* This class represents a Server configuration.
*
*/
class ServerConfig : public otServerConfig, public Unequatable<ServerConfig>
{
friend class ServiceConfig;
public:
/**
* This method overloads operator `==` to evaluate whether or not two `ServerConfig` instances are equal.
*
* @param[in] aOther The other `ServerConfig` instance to compare with.
*
* @retval TRUE If the two `ServerConfig` instances are equal.
* @retval FALSE If the two `ServerConfig` instances are not equal.
*
*/
bool operator==(const ServerConfig &aOther) const;
private:
void SetFrom(const ServerTlv &aServerTlv);
};
/**
* This method gets the Server configuration.
*
* @returns The Server configuration.
*
*/
const ServerConfig &GetServerConfig(void) const { return static_cast<const ServerConfig &>(mServerConfig); }
/**
* This method gets the Server configuration.
*
* @returns The Server configuration.
*
*/
ServerConfig &GetServerConfig(void) { return static_cast<ServerConfig &>(mServerConfig); }
/**
* This method overloads operator `==` to evaluate whether or not two `ServiceConfig` instances are equal.
*
* @param[in] aOther The other `ServiceConfig` instance to compare with.
*
* @retval TRUE If the two `ServiceConfig` instances are equal.
* @retval FALSE If the two `ServiceConfig` instances are not equal.
*
*/
bool operator==(const ServiceConfig &aOther) const;
private:
void SetFrom(const ServiceTlv &aServiceTlv, const ServerTlv &aServerTlv);
};
} // namespace NetworkData
/**
* @}
*/
} // namespace ot
#endif // NETWORK_DATA_TYPES_HPP_