From 9abd81b11bdaa02c5997698a7cda96b3b67b014e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Wa=C5=84czyk?= Date: Fri, 9 Apr 2021 22:35:54 +0200 Subject: [PATCH] [border-router] add validation of updated on mesh prefixes (#6313) This commit adds validation of the on mesh prefixes. With this change, the domain on mesh prefix can be directly configured after successful verification. --- src/core/api/border_router_api.cpp | 11 +++--- src/core/thread/network_data_local.cpp | 54 ++++++++++++++++++-------- src/core/thread/network_data_local.hpp | 12 ++++++ 3 files changed, 55 insertions(+), 22 deletions(-) diff --git a/src/core/api/border_router_api.cpp b/src/core/api/border_router_api.cpp index 10f9d5e4a..a72530967 100644 --- a/src/core/api/border_router_api.cpp +++ b/src/core/api/border_router_api.cpp @@ -80,18 +80,17 @@ otError otBorderRouterAddOnMeshPrefix(otInstance *aInstance, const otBorderRoute OT_ASSERT(aConfig != nullptr); - SuccessOrExit(error = instance.Get().AddOnMeshPrefix(*config)); - #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE - // Only try to configure Domain Prefix after the parameter is validated via above `AddOnMeshPrefix()`. if (aConfig->mDp) { - // Restore local server data - IgnoreError(instance.Get().RemoveOnMeshPrefix(config->GetPrefix())); - + SuccessOrExit(error = instance.Get().ValidateOnMeshPrefix(*config)); instance.Get().SetDomainPrefix(*config); } + else #endif + { + SuccessOrExit(error = instance.Get().AddOnMeshPrefix(*config)); + } exit: return error; diff --git a/src/core/thread/network_data_local.cpp b/src/core/thread/network_data_local.cpp index 65076c6ab..241d29ae7 100644 --- a/src/core/thread/network_data_local.cpp +++ b/src/core/thread/network_data_local.cpp @@ -54,10 +54,9 @@ Local::Local(Instance &aInstance) } #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE -Error Local::AddOnMeshPrefix(const OnMeshPrefixConfig &aConfig) +Error Local::ValidateOnMeshPrefix(const OnMeshPrefixConfig &aConfig) { - Error error; - uint16_t flags = 0; + Error error = kErrorNone; // Add Prefix validation check: // Thread 1.1 Specification 5.13.2 says @@ -69,6 +68,19 @@ Error Local::AddOnMeshPrefix(const OnMeshPrefixConfig &aConfig) // 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; + + SuccessOrExit(error = ValidateOnMeshPrefix(aConfig)); + if (aConfig.mPreferred) { flags |= BorderRouterEntry::kPreferredFlag; @@ -123,6 +135,28 @@ 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) { return AddPrefix(aConfig.GetPrefix(), NetworkDataTlv::kTypeHasRoute, aConfig.mPreference, /* aFlags */ 0, @@ -144,19 +178,7 @@ Error Local::AddPrefix(const Ip6::Prefix & aPrefix, uint8_t subTlvLength; PrefixTlv *prefixTlv; - 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); - } - - VerifyOrExit(!aPrefix.ContainsPrefix(Get().GetMeshLocalPrefix()), error = kErrorInvalidArgs); + SuccessOrExit(error = ValidatePrefixAndPreference(aPrefix, aPrf)); IgnoreError(RemovePrefix(aPrefix, aSubTlvType)); diff --git a/src/core/thread/network_data_local.hpp b/src/core/thread/network_data_local.hpp index fa1dbd5cf..70f49e2a5 100644 --- a/src/core/thread/network_data_local.hpp +++ b/src/core/thread/network_data_local.hpp @@ -83,6 +83,17 @@ 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. * @@ -170,6 +181,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,