diff --git a/src/core/net/dhcp6_server.cpp b/src/core/net/dhcp6_server.cpp index 02aadf2be..6f388d740 100644 --- a/src/core/net/dhcp6_server.cpp +++ b/src/core/net/dhcp6_server.cpp @@ -53,40 +53,31 @@ namespace Dhcp6 { Dhcp6Server::Dhcp6Server(Instance &aInstance) : InstanceLocator(aInstance) , mSocket(GetNetif().GetIp6().GetUdp()) + , mPrefixAgentsCount(0) + , mPrefixAgentsMask(0) { - for (uint8_t i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++) - { - memset(&(mPrefixAgents[i]), 0, sizeof(PrefixAgent)); - memset(&mAgentsAloc[i], 0, sizeof(mAgentsAloc[i])); - } - - mPrefixAgentsCount = 0; - mPrefixAgentsMask = 0; + memset(mPrefixAgents, 0, sizeof(mPrefixAgents)); } otError Dhcp6Server::UpdateService(void) { - ThreadNetif & netif = GetNetif(); - otError error = OT_ERROR_NONE; - bool found; - uint8_t i; - uint16_t rloc16 = netif.GetMle().GetRloc16(); - Ip6::Address * address = NULL; + otError error = OT_ERROR_NONE; + ThreadNetif & netif = GetNetif(); + uint16_t rloc16 = netif.GetMle().GetRloc16(); otNetworkDataIterator iterator; otBorderRouterConfig config; Lowpan::Context lowpanContext; // remove dhcp agent aloc and prefix delegation - for (i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++) + for (int i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++) { - found = false; + bool found = false; - if (!mAgentsAloc[i].mValid) + if (!mPrefixAgents[i].IsValid()) { continue; } - address = &(mAgentsAloc[i].GetAddress()); iterator = OT_NETWORK_DATA_ITERATOR_INIT; while (netif.GetNetworkDataLeader().GetNextOnMeshPrefix(&iterator, rloc16, &config) == OT_ERROR_NONE) @@ -96,10 +87,9 @@ otError Dhcp6Server::UpdateService(void) continue; } - netif.GetNetworkDataLeader().GetContext(*static_cast(&(config.mPrefix.mPrefix)), - lowpanContext); + error = netif.GetNetworkDataLeader().GetContext(mPrefixAgents[i].GetPrefix(), lowpanContext); - if (address->mFields.m8[15] == lowpanContext.mContextId) + if ((error == OT_ERROR_NONE) && (mPrefixAgents[i].GetContextId() == lowpanContext.mContextId)) { // still in network data found = true; @@ -109,10 +99,8 @@ otError Dhcp6Server::UpdateService(void) if (!found) { - netif.GetNetworkDataLeader().GetContext(address->mFields.m8[15], lowpanContext); - netif.RemoveUnicastAddress(mAgentsAloc[i]); - mAgentsAloc[i].mValid = false; - RemovePrefixAgent(lowpanContext.mPrefix); + mPrefixAgents[i].Clear(); + mPrefixAgentsCount--; } } @@ -121,57 +109,17 @@ otError Dhcp6Server::UpdateService(void) while (netif.GetNetworkDataLeader().GetNextOnMeshPrefix(&iterator, rloc16, &config) == OT_ERROR_NONE) { - found = false; - if (!config.mDhcp) { continue; } - netif.GetNetworkDataLeader().GetContext(*static_cast(&config.mPrefix.mPrefix), - lowpanContext); + error = netif.GetNetworkDataLeader().GetContext(static_cast(config.mPrefix.mPrefix), + lowpanContext); - for (i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++) + if (error == OT_ERROR_NONE) { - address = &(mAgentsAloc[i].GetAddress()); - - if ((mAgentsAloc[i].mValid) && (address->mFields.m8[15] == lowpanContext.mContextId)) - { - found = true; - break; - } - } - - // already added - if (found) - { - continue; - } - - for (i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++) - { - if (!mAgentsAloc[i].mValid) - { - address = &(mAgentsAloc[i].GetAddress()); - memcpy(address, netif.GetMle().GetMeshLocalPrefix().m8, sizeof(otMeshLocalPrefix)); - address->mFields.m16[4] = HostSwap16(0x0000); - address->mFields.m16[5] = HostSwap16(0x00ff); - address->mFields.m16[6] = HostSwap16(0xfe00); - address->mFields.m8[14] = Ip6::Address::kAloc16Mask; - address->mFields.m8[15] = lowpanContext.mContextId; - mAgentsAloc[i].mPrefixLength = 64; - mAgentsAloc[i].mPreferred = true; - mAgentsAloc[i].mValid = true; - netif.AddUnicastAddress(mAgentsAloc[i]); - AddPrefixAgent(config.mPrefix); - break; - } - } - - // if no available Dhcp Agent Aloc resources - if (i == OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES) - { - ExitNow(error = OT_ERROR_NO_BUFS); + AddPrefixAgent(config.mPrefix, lowpanContext); } } @@ -184,7 +132,6 @@ otError Dhcp6Server::UpdateService(void) Stop(); } -exit: return error; } @@ -202,48 +149,29 @@ void Dhcp6Server::Stop(void) mSocket.Close(); } -otError Dhcp6Server::AddPrefixAgent(otIp6Prefix &aIp6Prefix) +otError Dhcp6Server::AddPrefixAgent(const otIp6Prefix &aIp6Prefix, const Lowpan::Context &aContext) { - otError error = OT_ERROR_NO_BUFS; + otError error = OT_ERROR_NONE; + PrefixAgent *newEntry = NULL; - for (uint8_t i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++) + for (int i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++) { - if (mPrefixAgents[i].GetPrefix()->mLength != 0) + if (!mPrefixAgents[i].IsValid()) { - continue; + newEntry = &mPrefixAgents[i]; + } + else if (mPrefixAgents[i].IsPrefixMatch(aIp6Prefix)) + { + // already added + ExitNow(); } - - mPrefixAgents[i].SetPrefix(aIp6Prefix); - mPrefixAgentsCount++; - ExitNow(error = OT_ERROR_NONE); } -exit: - return error; -} + VerifyOrExit(newEntry != NULL, error = OT_ERROR_NO_BUFS); -otError Dhcp6Server::RemovePrefixAgent(const uint8_t *aIp6Address) -{ - otError error = OT_ERROR_NOT_FOUND; - otIp6Prefix *prefix = NULL; - - for (uint8_t i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++) - { - prefix = mPrefixAgents[i].GetPrefix(); - - if (prefix->mLength == 0) - { - continue; - } - - if (otIp6PrefixMatch(&(prefix->mPrefix), reinterpret_cast(aIp6Address)) >= - prefix->mLength) - { - memset(&(mPrefixAgents[i]), 0, sizeof(PrefixAgent)); - mPrefixAgentsCount--; - ExitNow(error = OT_ERROR_NONE); - } - } + newEntry->Set(aIp6Prefix, GetNetif().GetMle().GetMeshLocalPrefix(), aContext.mContextId); + GetNetif().AddUnicastAddress(newEntry->GetAloc()); + mPrefixAgentsCount++; exit: return error; @@ -381,9 +309,8 @@ exit: otError Dhcp6Server::ProcessIaAddress(Message &aMessage, uint16_t aOffset) { - otError error = OT_ERROR_NONE; - otIp6Prefix *prefix = NULL; - IaAddress option; + otError error = OT_ERROR_NONE; + IaAddress option; VerifyOrExit(((aMessage.Read(aOffset, sizeof(option), &option) == sizeof(option)) && option.GetLength() == (sizeof(option) - sizeof(Dhcp6Option))), @@ -392,14 +319,7 @@ otError Dhcp6Server::ProcessIaAddress(Message &aMessage, uint16_t aOffset) // mask matching prefix for (uint8_t i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++) { - prefix = mPrefixAgents[i].GetPrefix(); - - if (prefix->mLength == 0) - { - continue; - } - - if (otIp6PrefixMatch(&option.GetAddress(), &prefix->mPrefix) >= prefix->mLength) + if (mPrefixAgents[i].IsValid() && mPrefixAgents[i].IsPrefixMatch(option.GetAddress())) { mPrefixAgentsMask |= (1 << i); break; @@ -514,33 +434,28 @@ otError Dhcp6Server::AppendStatusCode(Message &aMessage, Status aStatus) otError Dhcp6Server::AppendIaAddress(Message &aMessage, ClientIdentifier &aClient) { - otError error = OT_ERROR_NONE; - otIp6Prefix *prefix = NULL; + otError error = OT_ERROR_NONE; - // if specified, only apply specified prefixes if (mPrefixAgentsMask) { + // if specified, only apply specified prefixes for (uint8_t i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++) { if (mPrefixAgentsMask & (1 << i)) { - prefix = mPrefixAgents[i].GetPrefix(); - SuccessOrExit(error = AddIaAddress(aMessage, *prefix, aClient)); + SuccessOrExit(error = AddIaAddress(aMessage, mPrefixAgents[i].GetPrefix(), aClient)); } } } - else // if not specified, apply all configured prefixes + else { + // if not specified, apply all configured prefixes for (uint8_t i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++) { - prefix = mPrefixAgents[i].GetPrefix(); - - if (prefix->mLength == 0) + if (mPrefixAgents[i].IsValid()) { - continue; + SuccessOrExit(error = AddIaAddress(aMessage, mPrefixAgents[i].GetPrefix(), aClient)); } - - SuccessOrExit(error = AddIaAddress(aMessage, *prefix, aClient)); } } @@ -548,17 +463,18 @@ exit: return error; } -otError Dhcp6Server::AddIaAddress(Message &aMessage, otIp6Prefix &aIp6Prefix, ClientIdentifier &aClient) +otError Dhcp6Server::AddIaAddress(Message &aMessage, const Ip6::Address &aPrefix, ClientIdentifier &aClient) { otError error = OT_ERROR_NONE; IaAddress option; option.Init(); - memcpy(option.GetAddress().mFields.m8, &aIp6Prefix.mPrefix, 8); + memcpy(option.GetAddress().mFields.m8, &aPrefix, OT_IP6_PREFIX_SIZE); option.GetAddress().SetIid(*reinterpret_cast(aClient.GetDuidLinkLayerAddress())); option.SetPreferredLifetime(OT_DHCP6_DEFAULT_PREFERRED_LIFETIME); option.SetValidLifetime(OT_DHCP6_DEFAULT_VALID_LIFETIME); SuccessOrExit(error = aMessage.Append(&option, sizeof(option))); + exit: return error; } diff --git a/src/core/net/dhcp6_server.hpp b/src/core/net/dhcp6_server.hpp index 29d7cb55e..427ee6935 100644 --- a/src/core/net/dhcp6_server.hpp +++ b/src/core/net/dhcp6_server.hpp @@ -66,35 +66,6 @@ namespace Dhcp6 { #define OT_DHCP6_DEFAULT_PREFERRED_LIFETIME 0xffffffffU #define OT_DHCP6_DEFAULT_VALID_LIFETIME 0xffffffffU -/** - * This class implements prefix agent. - * - */ - -OT_TOOL_PACKED_BEGIN -class PrefixAgent -{ -public: - /** - * This method returns the reference to the IPv6 prefix. - * - * @returns A reference to the IPv6 prefix. - * - */ - otIp6Prefix *GetPrefix(void) { return &mIp6Prefix; } - - /** - * This method sets the IPv6 prefix. - * - * @param[in] aIp6Prefix The reference to the IPv6 prefix to set. - * - */ - void SetPrefix(otIp6Prefix &aIp6Prefix) { memcpy(&mIp6Prefix, &aIp6Prefix, sizeof(otIp6Prefix)); } - -private: - otIp6Prefix mIp6Prefix; ///< prefix -} OT_TOOL_PACKED_END; - class Dhcp6Server : public InstanceLocator { public: @@ -113,11 +84,109 @@ public: otError UpdateService(); private: + class PrefixAgent + { + public: + /** + * This method indicates whether or not @p aPrefix matches this entry. + * + * @param[in] aPrefix The prefix to compare. + * + * @retval TRUE if the prefix matches. + * @retval FALSE if the prefix does not match. + * + */ + bool IsPrefixMatch(const otIp6Prefix &aPrefix) const + { + return (mPrefix.mLength == aPrefix.mLength) && + (otIp6PrefixMatch(&mPrefix.mPrefix, &aPrefix.mPrefix) >= mPrefix.mLength); + } + + /** + * This method indicates whether or not @p aAddress has a matching prefix. + * + * @param[in] aAddress The IPv6 address to compare. + * + * @retval TRUE if the address has a matching prefix. + * @retval FALSE if the address does not have a matching prefix. + * + */ + bool IsPrefixMatch(const otIp6Address &aAddress) const + { + return (otIp6PrefixMatch(&mPrefix.mPrefix, &aAddress) >= mPrefix.mLength); + } + + /** + * This method indicates whether or not this entry is valid. + * + * @retval TRUE if this entry is valid. + * @retval FALSE if this entry is not valid. + * + */ + bool IsValid(void) const { return mAloc.mValid; } + + /** + * This method sets the entry to invalid. + * + */ + void Clear(void) { mAloc.mValid = false; } + + /** + * This method returns the 6LoWPAN context ID. + * + * @returns The 6LoWPAN context ID. + * + */ + uint8_t GetContextId(void) const { return mAloc.mAddress.mFields.m8[15]; } + + /** + * This method returns the ALOC. + * + * @returns the ALOC. + * + */ + Ip6::NetifUnicastAddress &GetAloc(void) { return mAloc; } + + /** + * This method returns the IPv6 prefix. + * + * @returns The IPv6 prefix. + * + */ + const Ip6::Address &GetPrefix(void) const { return static_cast(mPrefix.mPrefix); } + + /** + * This method sets the ALOC. + * + * @param[in] aPrefix The IPv6 prefix. + * @param[in] aMeshLocalPrefix The Mesh Local Prefix. + * @param[in] aContextId The 6LoWPAN Context ID. + * + */ + void Set(const otIp6Prefix &aPrefix, const otMeshLocalPrefix &aMeshLocalPrefix, uint8_t aContextId) + { + mPrefix = aPrefix; + + memcpy(&mAloc.mAddress, &aMeshLocalPrefix, OT_IP6_PREFIX_SIZE); + mAloc.mAddress.mFields.m16[4] = HostSwap16(0x0000); + mAloc.mAddress.mFields.m16[5] = HostSwap16(0x00ff); + mAloc.mAddress.mFields.m16[6] = HostSwap16(0xfe00); + mAloc.mAddress.mFields.m8[14] = Ip6::Address::kAloc16Mask; + mAloc.mAddress.mFields.m8[15] = aContextId; + mAloc.mPrefixLength = 64; + mAloc.mPreferred = true; + mAloc.mValid = true; + } + + private: + Ip6::NetifUnicastAddress mAloc; + otIp6Prefix mPrefix; + }; + void Start(void); void Stop(void); - otError AddPrefixAgent(otIp6Prefix &aIp6Prefix); - otError RemovePrefixAgent(const uint8_t *aIp6Address); + otError AddPrefixAgent(const otIp6Prefix &aIp6Prefix, const Lowpan::Context &aContext); otError AppendHeader(Message &aMessage, uint8_t *aTransactionId); otError AppendClientIdentifier(Message &aMessage, ClientIdentifier &aClient); @@ -128,7 +197,7 @@ private: otError AppendRapidCommit(Message &aMessage); otError AppendVendorSpecificInformation(Message &aMessage); - otError AddIaAddress(Message &aMessage, otIp6Prefix &aIp6Prefix, ClientIdentifier &aClient); + otError AddIaAddress(Message &aMessage, const Ip6::Address &aPrefix, ClientIdentifier &aClient); static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo); void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo); @@ -145,10 +214,9 @@ private: Ip6::UdpSocket mSocket; - Ip6::NetifUnicastAddress mAgentsAloc[OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES]; - PrefixAgent mPrefixAgents[OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES]; - uint8_t mPrefixAgentsMask; - uint8_t mPrefixAgentsCount; + PrefixAgent mPrefixAgents[OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES]; + uint8_t mPrefixAgentsCount; + uint8_t mPrefixAgentsMask; }; } // namespace Dhcp6