From 8533ee39365af101ef39596f422f1b214e4e7eb1 Mon Sep 17 00:00:00 2001 From: Yakun Xu Date: Tue, 6 Nov 2018 12:46:08 +0800 Subject: [PATCH] [mle] add address outside of constructor (#3251) This commit adds link local address when MLE is enabled. Adding address in constructor gives no chance to notify address change with address callback. --- src/core/api/thread_api.cpp | 2 +- src/core/net/netif.cpp | 22 ++++++++++++-- src/core/net/netif.hpp | 15 ++++++++++ src/core/thread/mle.cpp | 50 ++++++++++++++++++++++---------- src/core/thread/mle.hpp | 10 +++++-- src/core/thread/thread_netif.cpp | 35 ++++++++++++---------- 6 files changed, 97 insertions(+), 37 deletions(-) diff --git a/src/core/api/thread_api.cpp b/src/core/api/thread_api.cpp index 770823c47..d2be27e20 100644 --- a/src/core/api/thread_api.cpp +++ b/src/core/api/thread_api.cpp @@ -206,7 +206,7 @@ otError otThreadSetMeshLocalPrefix(otInstance *aInstance, const otMeshLocalPrefi VerifyOrExit(instance.GetThreadNetif().GetMle().GetRole() == OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE); - error = instance.GetThreadNetif().GetMle().SetMeshLocalPrefix(*aMeshLocalPrefix); + instance.GetThreadNetif().GetMle().SetMeshLocalPrefix(*aMeshLocalPrefix); instance.GetThreadNetif().GetActiveDataset().Clear(); instance.GetThreadNetif().GetPendingDataset().Clear(); diff --git a/src/core/net/netif.cpp b/src/core/net/netif.cpp index 322a6b724..7805ba373 100644 --- a/src/core/net/netif.cpp +++ b/src/core/net/netif.cpp @@ -99,9 +99,6 @@ Netif::Netif(Instance &aInstance, int8_t aInterfaceId) // To mark the address as unused/available, set the `mNext` to point back to itself. mExtMulticastAddresses[i].mNext = &mExtMulticastAddresses[i]; } - - mMulticastAddresses = static_cast( - const_cast(&kLinkLocalAllNodesMulticastAddress)); } bool Netif::IsMulticastSubscribed(const Address &aAddress) const @@ -120,6 +117,25 @@ exit: return rval; } +void Netif::SubscribeAllNodesMulticast(void) +{ + assert(mMulticastAddresses == NULL); + + mMulticastAddresses = static_cast( + const_cast(&kLinkLocalAllNodesMulticastAddress)); + + GetNotifier().Signal(OT_CHANGED_IP6_MULTICAST_SUBSRCRIBED); +} + +void Netif::UnsubscribeAllNodesMulticast(void) +{ + assert(mMulticastAddresses == NULL || mMulticastAddresses == &kLinkLocalAllNodesMulticastAddress); + + mMulticastAddresses = NULL; + + GetNotifier().Signal(OT_CHANGED_IP6_MULTICAST_UNSUBSRCRIBED); +} + otError Netif::SubscribeAllRoutersMulticast(void) { otError error = OT_ERROR_NONE; diff --git a/src/core/net/netif.hpp b/src/core/net/netif.hpp index a4e647479..6f3222986 100644 --- a/src/core/net/netif.hpp +++ b/src/core/net/netif.hpp @@ -447,6 +447,21 @@ public: return OT_ERROR_NOT_IMPLEMENTED; } +protected: + /** + * This method subscribes the network interface to the realm-local all MPL forwarders, link-local and + * realm-local all nodes address. + * + */ + void SubscribeAllNodesMulticast(void); + + /** + * This method unsubscribes the network interface from the realm-local all MPL forwarders, link-local and + * realm-local all nodes address. + * + */ + void UnsubscribeAllNodesMulticast(void); + private: NetifUnicastAddress * mUnicastAddresses; NetifMulticastAddress *mMulticastAddresses; diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index daff00574..9805efc92 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -133,7 +133,6 @@ Mle::Mle(Instance &aInstance) mLinkLocal64.mPrefixLength = 64; mLinkLocal64.mPreferred = true; mLinkLocal64.mValid = true; - GetNetif().AddUnicastAddress(mLinkLocal64); // Leader Aloc mLeaderAloc.mPrefixLength = 128; @@ -216,7 +215,7 @@ otError Mle::Enable(void) otError error = OT_ERROR_NONE; Ip6::SockAddr sockaddr; - // memcpy(&sockaddr.mAddr, &mLinkLocal64.GetAddress(), sizeof(sockaddr.mAddr)); + UpdateLinkLocalAddress(); sockaddr.mPort = kUdpPort; SuccessOrExit(error = mSocket.Open(&Mle::HandleUdpReceive, this)); SuccessOrExit(error = mSocket.Bind(sockaddr)); @@ -231,6 +230,7 @@ otError Mle::Disable(void) SuccessOrExit(error = Stop(false)); SuccessOrExit(error = mSocket.Close()); + SuccessOrExit(error = GetNetif().RemoveUnicastAddress(mLinkLocal64)); exit: return error; @@ -245,6 +245,9 @@ otError Mle::Start(bool aEnableReattach, bool aAnnounceAttach) VerifyOrExit(otPlatRadioGetPromiscuous(&netif.GetInstance()) == false, error = OT_ERROR_INVALID_STATE); VerifyOrExit(netif.IsUp(), error = OT_ERROR_INVALID_STATE); + ApplyMeshLocalPrefix(); + SetRloc16(GetRloc16()); + SetStateDetached(); mAttachCounter = 0; @@ -291,7 +294,10 @@ otError Mle::Stop(bool aClearNetworkDatasets) netif.GetKeyManager().Stop(); SetStateDetached(); + GetNetif().UnsubscribeMulticast(mRealmLocalAllThreadNodes); + GetNetif().UnsubscribeMulticast(mLinkLocalAllThreadNodes); netif.RemoveUnicastAddress(mMeshLocal16); + netif.RemoveUnicastAddress(mMeshLocal64); SetRole(OT_DEVICE_ROLE_DISABLED); @@ -382,9 +388,8 @@ otError Mle::Restore(void) } mDeviceMode = networkInfo.mDeviceMode; - SetRloc16(networkInfo.mRloc16); + netif.GetMac().SetShortAddress(networkInfo.mRloc16); netif.GetMac().SetExtAddress(networkInfo.mExtAddress); - UpdateLinkLocalAddress(); memcpy(&mMeshLocal64.GetAddress().mFields.m8[OT_IP6_PREFIX_SIZE], networkInfo.mMlIid, OT_IP6_ADDRESS_SIZE - OT_IP6_PREFIX_SIZE); @@ -864,7 +869,7 @@ otError Mle::UpdateLinkLocalAddress(void) return OT_ERROR_NONE; } -otError Mle::SetMeshLocalPrefix(const otMeshLocalPrefix &aMeshLocalPrefix) +void Mle::SetMeshLocalPrefix(const otMeshLocalPrefix &aMeshLocalPrefix) { ThreadNetif &netif = GetNetif(); @@ -874,14 +879,32 @@ otError Mle::SetMeshLocalPrefix(const otMeshLocalPrefix &aMeshLocalPrefix) ExitNow(); } - // We must remove the old addresses before adding the new ones. - netif.RemoveUnicastAddress(mMeshLocal64); - netif.RemoveUnicastAddress(mMeshLocal16); - netif.UnsubscribeMulticast(mLinkLocalAllThreadNodes); - netif.UnsubscribeMulticast(mRealmLocalAllThreadNodes); + if (netif.IsUp()) + { + netif.RemoveUnicastAddress(mLeaderAloc); + // We must remove the old addresses before adding the new ones. + netif.RemoveUnicastAddress(mMeshLocal64); + netif.RemoveUnicastAddress(mMeshLocal16); + netif.UnsubscribeMulticast(mLinkLocalAllThreadNodes); + netif.UnsubscribeMulticast(mRealmLocalAllThreadNodes); + } memcpy(mMeshLocal64.GetAddress().mFields.m8, aMeshLocalPrefix.m8, sizeof(aMeshLocalPrefix)); - memcpy(mMeshLocal16.GetAddress().mFields.m8, mMeshLocal64.GetAddress().mFields.m8, 8); + memcpy(mMeshLocal16.GetAddress().mFields.m8, aMeshLocalPrefix.m8, sizeof(aMeshLocalPrefix)); + memcpy(mLeaderAloc.GetAddress().mFields.m8, aMeshLocalPrefix.m8, sizeof(aMeshLocalPrefix)); + + // Just keep mesh local prefix if network interface is down + VerifyOrExit(netif.IsUp()); + + ApplyMeshLocalPrefix(); + +exit: + return; +} + +void Mle::ApplyMeshLocalPrefix(void) +{ + ThreadNetif &netif = GetNetif(); #if OPENTHREAD_ENABLE_SERVICE @@ -916,16 +939,11 @@ otError Mle::SetMeshLocalPrefix(const otMeshLocalPrefix &aMeshLocalPrefix) // update Leader ALOC if (mRole == OT_DEVICE_ROLE_LEADER) { - netif.RemoveUnicastAddress(mLeaderAloc); - memcpy(mLeaderAloc.GetAddress().mFields.m8, mMeshLocal64.GetAddress().mFields.m8, 8); netif.AddUnicastAddress(mLeaderAloc); } // Changing the prefix also causes the mesh local address to be different. GetNotifier().Signal(OT_CHANGED_THREAD_ML_ADDR); - -exit: - return OT_ERROR_NONE; } uint16_t Mle::GetRloc16(void) const diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index ae4bd963e..1d6eb0930 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -705,10 +705,16 @@ public: * * @param[in] aPrefix A reference to the Mesh Local Prefix. * - * @retval OT_ERROR_NONE Successfully set the Mesh Local Prefix. + */ + void SetMeshLocalPrefix(const otMeshLocalPrefix &aPrefix); + + /** + * This method applies the Mesh Local Prefix. + * + * @param[in] aPrefix A reference to the Mesh Local Prefix. * */ - otError SetMeshLocalPrefix(const otMeshLocalPrefix &aPrefix); + void ApplyMeshLocalPrefix(void); /** * This method returns a reference to the Thread link-local address. diff --git a/src/core/thread/thread_netif.cpp b/src/core/thread/thread_netif.cpp index ac07fed25..0d5cbe35c 100644 --- a/src/core/thread/thread_netif.cpp +++ b/src/core/thread/thread_netif.cpp @@ -117,8 +117,16 @@ otError ThreadNetif::Up(void) // Enable the MAC just in case it was disabled while the Interface was down. mMac.SetEnabled(true); - GetIp6().AddNetif(*this); +#if OPENTHREAD_ENABLE_CHANNEL_MONITOR + GetInstance().GetChannelMonitor().Start(); +#endif mMeshForwarder.Start(); + GetIp6().AddNetif(*this); + + mIsUp = true; + + SubscribeAllNodesMulticast(); + mMleRouter.Enable(); mCoap.Start(kCoapUdpPort); #if OPENTHREAD_ENABLE_DNS_CLIENT mDnsClient.Start(); @@ -126,11 +134,6 @@ otError ThreadNetif::Up(void) #if OPENTHREAD_ENABLE_SNTP_CLIENT mSntpClient.Start(); #endif -#if OPENTHREAD_ENABLE_CHANNEL_MONITOR - GetInstance().GetChannelMonitor().Start(); -#endif - mMleRouter.Enable(); - mIsUp = true; GetNotifier().Signal(OT_CHANGED_THREAD_NETIF_STATE); exit: @@ -141,25 +144,27 @@ otError ThreadNetif::Down(void) { VerifyOrExit(mIsUp); - mCoap.Stop(); +#if OPENTHREAD_ENABLE_DTLS + mDtls.Stop(); +#endif #if OPENTHREAD_ENABLE_DNS_CLIENT mDnsClient.Stop(); #endif #if OPENTHREAD_ENABLE_SNTP_CLIENT mSntpClient.Stop(); #endif -#if OPENTHREAD_ENABLE_CHANNEL_MONITOR - GetInstance().GetChannelMonitor().Stop(); -#endif + mCoap.Stop(); mMleRouter.Disable(); - mMeshForwarder.Stop(); - GetIp6().RemoveNetif(*this); RemoveAllExternalUnicastAddresses(); UnsubscribeAllExternalMulticastAddresses(); - mIsUp = false; + UnsubscribeAllRoutersMulticast(); + UnsubscribeAllNodesMulticast(); -#if OPENTHREAD_ENABLE_DTLS - mDtls.Stop(); + mIsUp = false; + GetIp6().RemoveNetif(*this); + mMeshForwarder.Stop(); +#if OPENTHREAD_ENABLE_CHANNEL_MONITOR + GetInstance().GetChannelMonitor().Stop(); #endif GetNotifier().Signal(OT_CHANGED_THREAD_NETIF_STATE);