From cc70a88642dd8a79678239a895881a17ea32763a Mon Sep 17 00:00:00 2001 From: Buke Po Date: Thu, 4 May 2017 00:11:38 +0800 Subject: [PATCH] Disallow adding mesh local prefix as on-mesh prefix (#1699) * disallow adding mesh local prefix * update prefix match --- src/core/net/ip6_address.cpp | 16 +++++++++++++--- src/core/net/ip6_address.hpp | 13 +++++++++++++ src/core/thread/network_data_local.cpp | 9 ++++++++- src/core/thread/network_data_local_ftd.hpp | 5 +++-- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/core/net/ip6_address.cpp b/src/core/net/ip6_address.cpp index 8c0455401..b0062bf0d 100644 --- a/src/core/net/ip6_address.cpp +++ b/src/core/net/ip6_address.cpp @@ -180,14 +180,19 @@ uint8_t Address::GetScope(void) const return kGlobalScope; } -uint8_t Address::PrefixMatch(const Address &aOther) const +uint8_t Address::PrefixMatch(const uint8_t *aPrefixA, const uint8_t *aPrefixB, uint8_t aMaxLength) { uint8_t rval = 0; uint8_t diff; - for (uint8_t i = 0; i < sizeof(Address); i++) + if (aMaxLength > sizeof(Address)) { - diff = mFields.m8[i] ^ aOther.mFields.m8[i]; + aMaxLength = sizeof(Address); + } + + for (uint8_t i = 0; i < aMaxLength; i++) + { + diff = aPrefixA[i] ^ aPrefixB[i]; if (diff == 0) { @@ -208,6 +213,11 @@ uint8_t Address::PrefixMatch(const Address &aOther) const return rval; } +uint8_t Address::PrefixMatch(const Address &aOther) const +{ + return PrefixMatch(mFields.m8, aOther.mFields.m8, sizeof(Address)); +} + bool Address::operator==(const Address &aOther) const { return memcmp(mFields.m8, aOther.mFields.m8, sizeof(mFields.m8)) == 0; diff --git a/src/core/net/ip6_address.hpp b/src/core/net/ip6_address.hpp index 9da4693aa..cc94e221d 100644 --- a/src/core/net/ip6_address.hpp +++ b/src/core/net/ip6_address.hpp @@ -74,6 +74,7 @@ public: { kInterfaceIdentifierSize = 8, ///< Interface Identifier size in bytes. kIp6AddressStringSize = 40, ///< Max buffer size in bytes to store an IPv6 address in string format. + kMeshLocalPrefixLength = 64, ///< Length of Thread mesh local prefix. }; /** @@ -338,6 +339,18 @@ public: */ const char *ToString(char *aBuf, uint16_t aSize) const; + /** + * This method returns the number of IPv6 prefix bits that match. + * + * @param[in] aPrefixA A pointer to the prefix to match. + * @param[in] aPrefixB A pointer to the prefix to match against. + * @param[in] aMaxLength Number of bytes of the two prefixes. + * + * @returns The number of prefix bits that match. + * + */ + static uint8_t PrefixMatch(const uint8_t *aPrefixA, const uint8_t *aPrefixB, uint8_t aMaxLength); + private: enum { diff --git a/src/core/thread/network_data_local.cpp b/src/core/thread/network_data_local.cpp index fdcdbc791..c1c1eda5a 100644 --- a/src/core/thread/network_data_local.cpp +++ b/src/core/thread/network_data_local.cpp @@ -58,9 +58,14 @@ Local::Local(ThreadNetif &aThreadNetif): ThreadError Local::AddOnMeshPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, int8_t aPrf, uint8_t aFlags, bool aStable) { + ThreadError error = kThreadError_None; PrefixTlv *prefixTlv; BorderRouterTlv *brTlv; + VerifyOrExit(Ip6::Address::PrefixMatch(aPrefix, mNetif.GetMle().GetMeshLocalPrefix(), + (aPrefixLength + 7) / 8) < Ip6::Address::kMeshLocalPrefixLength, + error = kThreadError_InvalidArgs); + RemoveOnMeshPrefix(aPrefix, aPrefixLength); prefixTlv = reinterpret_cast(mTlvs + mLength); @@ -85,7 +90,9 @@ ThreadError Local::AddOnMeshPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength ClearResubmitDelayTimer(); otDumpDebgNetData(GetInstance(), "add prefix done", mTlvs, mLength); - return kThreadError_None; + +exit: + return error; } ThreadError Local::RemoveOnMeshPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) diff --git a/src/core/thread/network_data_local_ftd.hpp b/src/core/thread/network_data_local_ftd.hpp index 85d0b397c..2be23413c 100644 --- a/src/core/thread/network_data_local_ftd.hpp +++ b/src/core/thread/network_data_local_ftd.hpp @@ -75,8 +75,9 @@ public: * @param[in] aFlags The Border Router Flags value. * @param[in] aStable The Stable value. * - * @retval kThreadError_None Successfully added the Border Router entry. - * @retval kThreadError_NoBufs Insufficient space to add the Border Router entry. + * @retval kThreadError_None Successfully added the Border Router entry. + * @retval kThreadError_NoBufs Insufficient space to add the Border Router entry. + * @retval kThreadError_InvalidArgs The prefix is mesh local prefix. * */ ThreadError AddOnMeshPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, int8_t aPrf, uint8_t aFlags,