From 999b29dcc2a06ec9f932c0317e7aa48cb1007ec9 Mon Sep 17 00:00:00 2001 From: Rongli Sun Date: Tue, 31 Mar 2020 23:01:17 +0800 Subject: [PATCH] [ip6-address] add `SetMulticastNetworkPrefix()` for Prefix-Based Multicast Address (#4757) This commit also replaces the relevant magic numbers with the constants `MeshLocalPrefix::kLength` and `MeshLocalPrefix::kSize` --- src/core/net/ip6_address.cpp | 20 ++++++++++++++++---- src/core/net/ip6_address.hpp | 28 ++++++++++++++++++++++++++-- src/core/thread/mle.cpp | 20 ++++++++------------ 3 files changed, 50 insertions(+), 18 deletions(-) diff --git a/src/core/net/ip6_address.cpp b/src/core/net/ip6_address.cpp index c1a6b5d7b..1e683c700 100644 --- a/src/core/net/ip6_address.cpp +++ b/src/core/net/ip6_address.cpp @@ -145,15 +145,21 @@ bool Address::IsIidReserved(void) const void Address::SetPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) { - uint8_t extraBits = (aPrefixLength % CHAR_BIT); + SetPrefix(0, aPrefix, aPrefixLength); +} - OT_ASSERT(aPrefixLength <= sizeof(Address) * CHAR_BIT); +void Address::SetPrefix(uint8_t aOffset, const uint8_t *aPrefix, uint8_t aPrefixLength) +{ + uint8_t bytes = aPrefixLength / CHAR_BIT; + uint8_t extraBits = aPrefixLength % CHAR_BIT; - memcpy(mFields.m8, aPrefix, (aPrefixLength - extraBits) / CHAR_BIT); + OT_ASSERT(aPrefixLength <= (sizeof(Address) - aOffset) * CHAR_BIT); + + memcpy(mFields.m8 + aOffset, aPrefix, bytes); if (extraBits > 0) { - uint8_t index = aPrefixLength / CHAR_BIT; + uint8_t index = aOffset + bytes; uint8_t mask = ((0x80 >> (extraBits - 1)) - 1); // `mask` has its higher (msb) `extraBits` bits as `0` and the reminaing as `1`. @@ -165,6 +171,12 @@ void Address::SetPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) } } +void Address::SetMulticastNetworkPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) +{ + SetPrefix(kMulticastNetworkPrefixOffset, aPrefix, aPrefixLength); + mFields.m8[kMulticastNetworkPrefixLengthOffset] = aPrefixLength; +} + void Address::SetIid(const uint8_t *aIid) { memcpy(mFields.m8 + kInterfaceIdentifierOffset, aIid, kInterfaceIdentifierSize); diff --git a/src/core/net/ip6_address.hpp b/src/core/net/ip6_address.hpp index 4b20475de..af4197c30 100644 --- a/src/core/net/ip6_address.hpp +++ b/src/core/net/ip6_address.hpp @@ -313,6 +313,26 @@ public: SetPrefix(aMeshLocalPrefix.m8, Mle::MeshLocalPrefix::kLength); } + /** + * This method sets the prefix content of the Prefix-Based Multicast Address. + * + * @param[in] aPrefix A buffer containing the prefix. + * @param[in] aPrefixLength The prefix length (in bits). + * + */ + void SetMulticastNetworkPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength); + + /** + * This method sets the prefix content of Mesh Local Prefix-Based Multicast Address. + * + * @param[in] aMeshLocalPrefix A reference to the Mesh Local Prefix. + * + */ + void SetMulticastNetworkPrefix(const Mle::MeshLocalPrefix &aMeshLocalPrefix) + { + SetMulticastNetworkPrefix(aMeshLocalPrefix.m8, Mle::MeshLocalPrefix::kLength); + } + /** * This method returns a pointer to the Interface Identifier. * @@ -433,10 +453,14 @@ public: static uint8_t PrefixMatch(const uint8_t *aPrefixA, const uint8_t *aPrefixB, uint8_t aMaxLength); private: + void SetPrefix(uint8_t aOffset, const uint8_t *aPrefix, uint8_t aPrefixLength); + enum { - kInterfaceIdentifierOffset = 8, ///< Interface Identifier offset in bytes. - kIp4AddressSize = 4 ///< Size of the IPv4 address. + kInterfaceIdentifierOffset = 8, ///< Interface Identifier offset in bytes. + kIp4AddressSize = 4, ///< Size of the IPv4 address. + kMulticastNetworkPrefixLengthOffset = 3, ///< Prefix-Based Multicast Address (RFC3306). + kMulticastNetworkPrefixOffset = 4, ///< Prefix-Based Multicast Address (RFC3306). }; } OT_TOOL_PACKED_END; diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 9b325c4e7..86f5c6a06 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -139,7 +139,7 @@ Mle::Mle(Instance &aInstance) // Leader Aloc mLeaderAloc.Clear(); - mLeaderAloc.mPrefixLength = 64; + mLeaderAloc.mPrefixLength = MeshLocalPrefix::kLength; mLeaderAloc.mPreferred = true; mLeaderAloc.mValid = true; mLeaderAloc.mScopeOverride = Ip6::Address::kRealmLocalScope; @@ -151,7 +151,7 @@ Mle::Mle(Instance &aInstance) for (size_t i = 0; i < OT_ARRAY_LENGTH(mServiceAlocs); i++) { mServiceAlocs[i].Clear(); - mServiceAlocs[i].mPrefixLength = 64; + mServiceAlocs[i].mPrefixLength = MeshLocalPrefix::kLength; mServiceAlocs[i].mPreferred = true; mServiceAlocs[i].mValid = true; mServiceAlocs[i].mScopeOverride = Ip6::Address::kRealmLocalScope; @@ -166,7 +166,7 @@ Mle::Mle(Instance &aInstance) // Primary Backbone Router Aloc mBackboneRouterPrimaryAloc.Clear(); - mBackboneRouterPrimaryAloc.mPrefixLength = 64; + mBackboneRouterPrimaryAloc.mPrefixLength = MeshLocalPrefix::kLength; mBackboneRouterPrimaryAloc.mPreferred = true; mBackboneRouterPrimaryAloc.mValid = true; mBackboneRouterPrimaryAloc.mScopeOverride = Ip6::Address::kRealmLocalScope; @@ -179,7 +179,6 @@ Mle::Mle(Instance &aInstance) mAllNetworkBackboneRouters.GetAddress().mFields.m8[0] = 0xff; // Multicast mAllNetworkBackboneRouters.GetAddress().mFields.m8[1] = 0x32; // Flags = 3, Scope = 2 mAllNetworkBackboneRouters.GetAddress().mFields.m8[2] = 0; // Reserved - mAllNetworkBackboneRouters.GetAddress().mFields.m8[3] = 64; // Prefix Length = 64 mAllNetworkBackboneRouters.GetAddress().mFields.m8[15] = 3; // Group ID = 3 #endif @@ -192,7 +191,7 @@ Mle::Mle(Instance &aInstance) Random::NonCrypto::FillBuffer(mMeshLocal64.GetAddress().mFields.m8 + OT_IP6_PREFIX_SIZE, OT_IP6_ADDRESS_SIZE - OT_IP6_PREFIX_SIZE); - mMeshLocal64.mPrefixLength = 64; + mMeshLocal64.mPrefixLength = MeshLocalPrefix::kLength; mMeshLocal64.mPreferred = true; mMeshLocal64.mValid = true; mMeshLocal64.mScopeOverride = Ip6::Address::kRealmLocalScope; @@ -203,7 +202,7 @@ Mle::Mle(Instance &aInstance) mMeshLocal16.GetAddress().mFields.m16[4] = HostSwap16(0x0000); mMeshLocal16.GetAddress().mFields.m16[5] = HostSwap16(0x00ff); mMeshLocal16.GetAddress().mFields.m16[6] = HostSwap16(0xfe00); - mMeshLocal16.mPrefixLength = 64; + mMeshLocal16.mPrefixLength = MeshLocalPrefix::kLength; mMeshLocal16.mPreferred = true; mMeshLocal16.mValid = true; mMeshLocal16.mScopeOverride = Ip6::Address::kRealmLocalScope; @@ -990,11 +989,8 @@ exit: void Mle::ApplyMeshLocalPrefix(void) { - mLinkLocalAllThreadNodes.GetAddress().mFields.m8[3] = 64; - memcpy(mLinkLocalAllThreadNodes.GetAddress().mFields.m8 + 4, mMeshLocal64.GetAddress().mFields.m8, 8); - - mRealmLocalAllThreadNodes.GetAddress().mFields.m8[3] = 64; - memcpy(mRealmLocalAllThreadNodes.GetAddress().mFields.m8 + 4, mMeshLocal64.GetAddress().mFields.m8, 8); + mLinkLocalAllThreadNodes.GetAddress().SetMulticastNetworkPrefix(GetMeshLocalPrefix()); + mRealmLocalAllThreadNodes.GetAddress().SetMulticastNetworkPrefix(GetMeshLocalPrefix()); VerifyOrExit(mRole != OT_DEVICE_ROLE_DISABLED); @@ -1035,7 +1031,7 @@ void Mle::ApplyMeshLocalPrefix(void) Get().AddUnicastAddress(mBackboneRouterPrimaryAloc); } - memcpy(mAllNetworkBackboneRouters.GetAddress().mFields.m8 + 4, mMeshLocal64.GetAddress().mFields.m8, 8); + mAllNetworkBackboneRouters.GetAddress().SetMulticastNetworkPrefix(GetMeshLocalPrefix()); if (Get().IsEnabled()) {