diff --git a/Android.mk b/Android.mk index c9594d4d5..113884274 100644 --- a/Android.mk +++ b/Android.mk @@ -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 \ diff --git a/src/core/BUILD.gn b/src/core/BUILD.gn index c82c247e5..0ce713bb5 100644 --- a/src/core/BUILD.gn +++ b/src/core/BUILD.gn @@ -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", diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 61e166df0..20ad44041 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -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 diff --git a/src/core/Makefile.am b/src/core/Makefile.am index b229619f0..08c05b583 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -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 \ diff --git a/src/core/api/border_router_api.cpp b/src/core/api/border_router_api.cpp index 3135fc116..21e083b1f 100644 --- a/src/core/api/border_router_api.cpp +++ b/src/core/api/border_router_api.cpp @@ -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(aInstance); const NetworkData::OnMeshPrefixConfig *config = static_cast(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().ValidateOnMeshPrefix(*config)); - instance.Get().SetDomainPrefix(*config); + error = instance.Get().SetDomainPrefix(*config); } else #endif { - SuccessOrExit(error = instance.Get().AddOnMeshPrefix(*config)); + error = instance.Get().AddOnMeshPrefix(*config); } -exit: return error; } diff --git a/src/core/backbone_router/bbr_local.cpp b/src/core/backbone_router/bbr_local.cpp index dc48eafe1..9d5a0e90b 100644 --- a/src/core/backbone_router/bbr_local.cpp +++ b/src/core/backbone_router/bbr_local.cpp @@ -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) diff --git a/src/core/backbone_router/bbr_local.hpp b/src/core/backbone_router/bbr_local.hpp index 4e8b47f95..62bf11e18 100644 --- a/src/core/backbone_router/bbr_local.hpp +++ b/src/core/backbone_router/bbr_local.hpp @@ -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. diff --git a/src/core/thread/network_data.cpp b/src/core/thread/network_data.cpp index 6fcca99dd..1d5b355a4 100644 --- a/src/core/thread/network_data.cpp +++ b/src/core/thread/network_data.cpp @@ -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().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) diff --git a/src/core/thread/network_data.hpp b/src/core/thread/network_data.hpp index add1561c6..eef3b04a4 100644 --- a/src/core/thread/network_data.hpp +++ b/src/core/thread/network_data.hpp @@ -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, - public Equatable -{ - friend class NetworkData; - -public: - /** - * This method gets the prefix. - * - * @return The prefix. - * - */ - const Ip6::Prefix &GetPrefix(void) const { return static_cast(mPrefix); } - - /** - * This method gets the prefix. - * - * @return The prefix. - * - */ - Ip6::Prefix &GetPrefix(void) { return static_cast(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, - public Equatable -{ - friend class NetworkData; - -public: - /** - * This method gets the prefix. - * - * @return The prefix. - * - */ - const Ip6::Prefix &GetPrefix(void) const { return static_cast(mPrefix); } - - /** - * This method gets the prefix. - * - * @return The prefix. - * - */ - Ip6::Prefix &GetPrefix(void) { return static_cast(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, public Unequatable -{ - friend class NetworkData; - -public: - /** - * This class represents a Server configuration. - * - */ - class ServerConfig : public otServerConfig, public Unequatable - { - 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(mServerConfig); } - - /** - * This method gets the Server configuration. - * - * @returns The Server configuration. - * - */ - ServerConfig &GetServerConfig(void) { return static_cast(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. * diff --git a/src/core/thread/network_data_local.cpp b/src/core/thread/network_data_local.cpp index 78a8918da..d6bda8b43 100644 --- a/src/core/thread/network_data_local.cpp +++ b/src/core/thread/network_data_local.cpp @@ -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().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(aFlags)); } diff --git a/src/core/thread/network_data_local.hpp b/src/core/thread/network_data_local.hpp index 00f717ba5..e3e80b135 100644 --- a/src/core/thread/network_data_local.hpp +++ b/src/core/thread/network_data_local.hpp @@ -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; diff --git a/src/core/thread/network_data_tlvs.hpp b/src/core/thread/network_data_tlvs.hpp index 4f66298df..a10cb583a 100644 --- a/src/core/thread/network_data_tlvs.hpp +++ b/src/core/thread/network_data_tlvs.hpp @@ -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 { -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(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(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 { -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(static_cast(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(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; diff --git a/src/core/thread/network_data_types.cpp b/src/core/thread/network_data_types.cpp new file mode 100644 index 000000000..9b0e4781a --- /dev/null +++ b/src/core/thread/network_data_types.cpp @@ -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().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(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(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(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().GetRloc16()); +} + +void ExternalRouteConfig::SetFromTlvFlags(uint8_t aFlags) +{ + mNat64 = ((aFlags & HasRouteEntry::kNat64Flag) != 0); + mPreference = static_cast(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 diff --git a/src/core/thread/network_data_types.hpp b/src/core/thread/network_data_types.hpp new file mode 100644 index 000000000..df2c52060 --- /dev/null +++ b/src/core/thread/network_data_types.hpp @@ -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 + +#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, + public Equatable +{ + friend class NetworkData; + friend class Local; + +public: + /** + * This method gets the prefix. + * + * @return The prefix. + * + */ + const Ip6::Prefix &GetPrefix(void) const { return static_cast(mPrefix); } + + /** + * This method gets the prefix. + * + * @return The prefix. + * + */ + Ip6::Prefix &GetPrefix(void) { return static_cast(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, + public Equatable +{ + friend class NetworkData; + friend class Local; + +public: + /** + * This method gets the prefix. + * + * @return The prefix. + * + */ + const Ip6::Prefix &GetPrefix(void) const { return static_cast(mPrefix); } + + /** + * This method gets the prefix. + * + * @return The prefix. + * + */ + Ip6::Prefix &GetPrefix(void) { return static_cast(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, public Unequatable +{ + friend class NetworkData; + +public: + /** + * This class represents a Server configuration. + * + */ + class ServerConfig : public otServerConfig, public Unequatable + { + 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(mServerConfig); } + + /** + * This method gets the Server configuration. + * + * @returns The Server configuration. + * + */ + ServerConfig &GetServerConfig(void) { return static_cast(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_