[netif] simplify applying mesh-local prefix change to addresses (#9527)

This commit simplifies how the `Netif` unicast and multicast addresses
that use the mesh-local prefix are updated when the mesh-local prefix
is changed.

The `Netif::UnicastAddress` class now includes a `mMeshLocal` flag,
which is set for all mesh-local addresses (RLOCs, ALOCs, and ML-EID).
When the mesh-local prefix is changed, `Mle` will inform `ThreadNetif`
to apply the new prefix. `ThreadNetif` will then update all of the
assigned unicast addresses that are marked as mesh-local, as well as
all of the subscribed mesh-local prefix-based multicast addresses
(such as link-local or realm-local All Thread Nodes addresses). The
`Netif` class first signals the removal of the previous address based
on the old prefix, and then the addition of the new address with the
new mesh-local prefix.

This change simplifies the code, in particular the modules such as
`Commissioner`, `BorderAgent` and `BackboneRouter::Local`, which need
to manage specific ALOC addresses. These modules no longer need to be
informed when the mesh-local prefix is changed to update their
address, as it will be done by the `Netif` class directly.
This commit is contained in:
Abtin Keshavarzian
2023-10-13 17:15:58 -07:00
committed by GitHub
parent 9876468006
commit 3e18032d2f
21 changed files with 250 additions and 209 deletions
+1 -1
View File
@@ -53,7 +53,7 @@ extern "C" {
* @note This number versions both OpenThread platform and user APIs.
*
*/
#define OPENTHREAD_API_VERSION (365)
#define OPENTHREAD_API_VERSION (366)
/**
* @addtogroup api-instance
+1
View File
@@ -188,6 +188,7 @@ typedef struct otNetifAddress
bool mScopeOverrideValid : 1; ///< TRUE if the mScopeOverride value is valid, FALSE otherwise.
unsigned int mScopeOverride : 4; ///< The IPv6 scope of this address.
bool mRloc : 1; ///< TRUE if the address is an RLOC, FALSE otherwise.
bool mMeshLocal : 1; ///< TRUE if the address is mesh-local, FALSE otherwise.
const struct otNetifAddress *mNext; ///< A pointer to the next network interface address.
} otNetifAddress;
+2 -9
View File
@@ -62,7 +62,7 @@ Local::Local(Instance &aInstance)
mDomainPrefixConfig.GetPrefix().SetLength(0);
// Primary Backbone Router Aloc
mBackboneRouterPrimaryAloc.InitAsThreadOriginRealmLocalScope();
mBackboneRouterPrimaryAloc.InitAsThreadOriginMeshLocal();
mBackboneRouterPrimaryAloc.GetAddress().GetIid().SetToLocator(Mle::kAloc16BackboneRouterPrimary);
// All Network Backbone Routers Multicast Address.
@@ -364,7 +364,7 @@ exit:
return error;
}
void Local::ApplyMeshLocalPrefix(void)
void Local::ApplyNewMeshLocalPrefix(void)
{
VerifyOrExit(IsEnabled());
@@ -372,13 +372,6 @@ void Local::ApplyMeshLocalPrefix(void)
mAllNetworkBackboneRouters.SetMulticastNetworkPrefix(Get<Mle::MleRouter>().GetMeshLocalPrefix());
Get<BackboneTmfAgent>().SubscribeMulticast(mAllNetworkBackboneRouters);
if (IsPrimary())
{
Get<ThreadNetif>().RemoveUnicastAddress(mBackboneRouterPrimaryAloc);
mBackboneRouterPrimaryAloc.GetAddress().SetPrefix(Get<Mle::MleRouter>().GetMeshLocalPrefix());
Get<ThreadNetif>().AddUnicastAddress(mBackboneRouterPrimaryAloc);
}
exit:
return;
}
+1 -1
View File
@@ -256,7 +256,7 @@ public:
* Applies the Mesh Local Prefix.
*
*/
void ApplyMeshLocalPrefix(void);
void ApplyNewMeshLocalPrefix(void);
/**
* Updates the subscription of All Domain Backbone Routers Multicast Address.
+1 -16
View File
@@ -240,7 +240,7 @@ BorderAgent::BorderAgent(Instance &aInstance)
, mIdInitialized(false)
#endif
{
mCommissionerAloc.InitAsThreadOriginRealmLocalScope();
mCommissionerAloc.InitAsThreadOriginMeshLocal();
}
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
@@ -654,21 +654,6 @@ exit:
return;
}
void BorderAgent::ApplyMeshLocalPrefix(void)
{
VerifyOrExit(mState == kStateActive);
if (Get<ThreadNetif>().HasUnicastAddress(mCommissionerAloc))
{
Get<ThreadNetif>().RemoveUnicastAddress(mCommissionerAloc);
mCommissionerAloc.GetAddress().SetPrefix(Get<Mle::MleRouter>().GetMeshLocalPrefix());
Get<ThreadNetif>().AddUnicastAddress(mCommissionerAloc);
}
exit:
return;
}
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN)
void BorderAgent::LogError(const char *aActionText, Error aError)
{
-6
View File
@@ -141,12 +141,6 @@ public:
*/
State GetState(void) const { return mState; }
/**
* Applies the Mesh Local Prefix.
*
*/
void ApplyMeshLocalPrefix(void);
/**
* Returns the UDP Proxy port to which the commissioner is currently
* bound.
+2 -18
View File
@@ -74,12 +74,8 @@ Commissioner::Commissioner(Instance &aInstance)
{
memset(reinterpret_cast<void *>(mJoiners), 0, sizeof(mJoiners));
mCommissionerAloc.Clear();
mCommissionerAloc.mPrefixLength = 64;
mCommissionerAloc.mPreferred = true;
mCommissionerAloc.mValid = true;
mCommissionerAloc.mScopeOverride = Ip6::Address::kRealmLocalScope;
mCommissionerAloc.mScopeOverrideValid = true;
mCommissionerAloc.InitAsThreadOriginMeshLocal();
mCommissionerAloc.mPreferred = true;
IgnoreError(SetId("OpenThread Commissioner"));
@@ -1155,18 +1151,6 @@ exit:
return error;
}
void Commissioner::ApplyMeshLocalPrefix(void)
{
VerifyOrExit(mState == kStateActive);
Get<ThreadNetif>().RemoveUnicastAddress(mCommissionerAloc);
mCommissionerAloc.GetAddress().SetPrefix(Get<Mle::MleRouter>().GetMeshLocalPrefix());
Get<ThreadNetif>().AddUnicastAddress(mCommissionerAloc);
exit:
return;
}
// LCOV_EXCL_START
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
-6
View File
@@ -486,12 +486,6 @@ public:
*/
PanIdQueryClient &GetPanIdQueryClient(void) { return mPanIdQuery; }
/**
* Applies the Mesh Local Prefix.
*
*/
void ApplyMeshLocalPrefix(void);
private:
static constexpr uint32_t kPetitionAttemptDelay = 5; // COMM_PET_ATTEMPT_DELAY (seconds)
static constexpr uint8_t kPetitionRetryCount = 2; // COMM_PET_RETRY_COUNT
-15
View File
@@ -485,21 +485,6 @@ Error Server::AppendRapidCommit(Message &aMessage)
return aMessage.Append(option);
}
void Server::ApplyMeshLocalPrefix(void)
{
for (PrefixAgent &prefixAgent : mPrefixAgents)
{
if (prefixAgent.IsValid())
{
PrefixAgent *entry = &prefixAgent;
Get<ThreadNetif>().RemoveUnicastAddress(entry->GetAloc());
entry->GetAloc().GetAddress().SetPrefix(Get<Mle::MleRouter>().GetMeshLocalPrefix());
Get<ThreadNetif>().AddUnicastAddress(entry->GetAloc());
}
}
}
} // namespace Dhcp6
} // namespace ot
+1 -6
View File
@@ -80,12 +80,6 @@ public:
*/
Error UpdateService(void);
/**
* Applies the Mesh Local Prefix.
*
*/
void ApplyMeshLocalPrefix(void);
private:
class PrefixAgent
{
@@ -173,6 +167,7 @@ private:
mAloc.InitAsThreadOrigin();
mAloc.GetAddress().SetToAnycastLocator(aMeshLocalPrefix, (Ip6::Address::kAloc16Mask << 8) + aContextId);
mAloc.mMeshLocal = true;
}
private:
+1 -12
View File
@@ -105,6 +105,7 @@ void Agent::UpdateService(void)
mAloc.InitAsThreadOrigin();
mAloc.GetAddress().SetToAnycastLocator(Get<Mle::MleRouter>().GetMeshLocalPrefix(), rloc);
mAloc.mMeshLocal = true;
Get<ThreadNetif>().AddUnicastAddress(mAloc);
ExitNow();
}
@@ -114,18 +115,6 @@ exit:
return;
}
void Agent::ApplyMeshLocalPrefix(void)
{
VerifyOrExit(IsAlocInUse());
Get<ThreadNetif>().RemoveUnicastAddress(mAloc);
mAloc.GetAddress().SetPrefix(Get<Mle::MleRouter>().GetMeshLocalPrefix());
Get<ThreadNetif>().AddUnicastAddress(mAloc);
exit:
return;
}
} // namespace NeighborDiscovery
} // namespace ot
-6
View File
@@ -66,12 +66,6 @@ public:
*/
void UpdateService(void);
/**
* Updates the prefix of the Neighbor Discovery Agent Anycast Locator.
*
*/
void ApplyMeshLocalPrefix(void);
private:
void FreeAloc(void) { mAloc.mNext = &mAloc; }
bool IsAlocInUse(void) const { return mAloc.mNext != &mAloc; }
+34 -3
View File
@@ -365,6 +365,11 @@ void Netif::UnsubscribeAllExternalMulticastAddresses(void)
void Netif::AddUnicastAddress(UnicastAddress &aAddress)
{
if (aAddress.mMeshLocal)
{
aAddress.GetAddress().SetPrefix(Get<Mle::Mle>().GetMeshLocalPrefix());
}
SuccessOrExit(mUnicastAddresses.Add(aAddress));
SignalUnicastAddressChange(kAddressAdded, aAddress);
@@ -438,8 +443,10 @@ Error Netif::AddExternalUnicastAddress(const UnicastAddress &aAddress)
entry = mExtUnicastAddressPool.Allocate();
VerifyOrExit(entry != nullptr, error = kErrorNoBufs);
*entry = aAddress;
entry->mRloc = false;
*entry = aAddress;
entry->mRloc = false;
entry->mMeshLocal = false;
mUnicastAddresses.Push(*entry);
SignalUnicastAddressChange(kAddressAdded, *entry);
@@ -490,6 +497,29 @@ bool Netif::IsUnicastAddressExternal(const UnicastAddress &aAddress) const
return mExtUnicastAddressPool.IsPoolEntry(aAddress);
}
void Netif::ApplyNewMeshLocalPrefix(void)
{
for (UnicastAddress &address : mUnicastAddresses)
{
if (address.mMeshLocal)
{
SignalUnicastAddressChange(kAddressRemoved, address);
address.GetAddress().SetPrefix(Get<Mle::Mle>().GetMeshLocalPrefix());
SignalUnicastAddressChange(kAddressAdded, address);
}
}
for (MulticastAddress &address : mMulticastAddresses)
{
if (Get<Mle::Mle>().IsMulticastAddressMeshLocalPrefixBased(address))
{
SignalMulticastAddressChange(kAddressRemoved, address, kOriginThread);
address.GetAddress().SetMulticastNetworkPrefix(Get<Mle::Mle>().GetMeshLocalPrefix());
SignalMulticastAddressChange(kAddressAdded, address, kOriginThread);
}
}
}
//---------------------------------------------------------------------------------------------------------------------
// Netif::UnicastAddress
@@ -502,10 +532,11 @@ void Netif::UnicastAddress::InitAsThreadOrigin(bool aPreferred)
mValid = true;
}
void Netif::UnicastAddress::InitAsThreadOriginRealmLocalScope(void)
void Netif::UnicastAddress::InitAsThreadOriginMeshLocal(void)
{
InitAsThreadOrigin();
SetScopeOverride(Address::kRealmLocalScope);
mMeshLocal = true;
}
void Netif::UnicastAddress::InitAsThreadOriginGlobalScope(void)
+10 -2
View File
@@ -123,10 +123,10 @@ public:
/**
* Clears and initializes the unicast address as a valid (but not preferred), thread-origin,
* realm-local scope (overridden) address with 64-bit prefix length.
* mesh-local address using the realm-local scope (overridden) address with 64-bit prefix length.
*
*/
void InitAsThreadOriginRealmLocalScope(void);
void InitAsThreadOriginMeshLocal(void);
/**
* Clears and initializes the unicast address as a valid (but not preferred), thread-origin, global
@@ -646,6 +646,14 @@ public:
*/
bool HasAnyExternalMulticastAddress(void) const { return !ExternalMulticastAddress::Iterator(*this).IsDone(); }
/**
* Applies the new mesh local prefix.
*
* Updates all mesh-local unicast addresses and prefix-based multicast addresses of the network interface.
*
*/
void ApplyNewMeshLocalPrefix(void);
protected:
/**
* Subscribes the network interface to the realm-local all MPL forwarders, link-local, and realm-local
+47 -99
View File
@@ -124,12 +124,10 @@ Mle::Mle(Instance &aInstance)
mLinkLocal64.InitAsThreadOrigin(/* aPreferred */ true);
mLinkLocal64.GetAddress().SetToLinkLocalAddress(Get<Mac::Mac>().GetExtAddress());
mLeaderAloc.InitAsThreadOriginRealmLocalScope();
mMeshLocal64.InitAsThreadOriginRealmLocalScope();
mMeshLocal64.InitAsThreadOriginMeshLocal();
mMeshLocal64.GetAddress().GetIid().GenerateRandom();
mMeshLocal16.InitAsThreadOriginRealmLocalScope();
mMeshLocal16.InitAsThreadOriginMeshLocal();
mMeshLocal16.GetAddress().GetIid().SetToLocator(0);
mMeshLocal16.mRloc = true;
@@ -141,10 +139,8 @@ Mle::Mle(Instance &aInstance)
mRealmLocalAllThreadNodes.GetAddress().mFields.m16[0] = HostSwap16(0xff33);
mRealmLocalAllThreadNodes.GetAddress().mFields.m16[7] = HostSwap16(0x0001);
mMeshLocalPrefix.Clear();
SetMeshLocalPrefix(AsCoreType(&kMeshLocalPrefixInit));
// `SetMeshLocalPrefix()` also adds the Mesh-Local EID and subscribes
// to the Link- and Realm-Local All Thread Nodes multicast addresses.
}
Error Mle::Enable(void)
@@ -195,7 +191,11 @@ Error Mle::Start(StartMode aMode)
SetStateDetached();
ApplyMeshLocalPrefix();
Get<ThreadNetif>().AddUnicastAddress(mMeshLocal64);
Get<ThreadNetif>().SubscribeMulticast(mLinkLocalAllThreadNodes);
Get<ThreadNetif>().SubscribeMulticast(mRealmLocalAllThreadNodes);
SetRloc16(GetRloc16());
mAttachCounter = 0;
@@ -693,10 +693,12 @@ void Mle::SetStateDetached(void)
Get<BackboneRouter::Leader>().Reset();
#endif
#if OPENTHREAD_FTD
if (IsLeader())
{
Get<ThreadNetif>().RemoveUnicastAddress(mLeaderAloc);
Get<ThreadNetif>().RemoveUnicastAddress(Get<MleRouter>().mLeaderAloc);
}
#endif
SetRole(kRoleDetached);
SetAttachState(kAttachStateIdle);
@@ -719,10 +721,12 @@ void Mle::SetStateDetached(void)
void Mle::SetStateChild(uint16_t aRloc16)
{
#if OPENTHREAD_FTD
if (IsLeader())
{
Get<ThreadNetif>().RemoveUnicastAddress(mLeaderAloc);
Get<ThreadNetif>().RemoveUnicastAddress(Get<MleRouter>().mLeaderAloc);
}
#endif
SetRloc16(aRloc16);
SetRole(kRoleChild);
@@ -888,28 +892,40 @@ void Mle::UpdateLinkLocalAddress(void)
void Mle::SetMeshLocalPrefix(const Ip6::NetworkPrefix &aMeshLocalPrefix)
{
VerifyOrExit(GetMeshLocalPrefix() != aMeshLocalPrefix,
Get<Notifier>().SignalIfFirst(kEventThreadMeshLocalAddrChanged));
VerifyOrExit(mMeshLocalPrefix != aMeshLocalPrefix);
if (Get<ThreadNetif>().IsUp())
{
Get<ThreadNetif>().RemoveUnicastAddress(mLeaderAloc);
mMeshLocalPrefix = aMeshLocalPrefix;
// We must remove the old addresses before adding the new ones.
Get<ThreadNetif>().RemoveUnicastAddress(mMeshLocal64);
Get<ThreadNetif>().RemoveUnicastAddress(mMeshLocal16);
Get<ThreadNetif>().UnsubscribeMulticast(mLinkLocalAllThreadNodes);
Get<ThreadNetif>().UnsubscribeMulticast(mRealmLocalAllThreadNodes);
}
// We ask `ThreadNetif` to apply the new mesh-local prefix which
// will then update all of its assigned unicast addresses that are
// marked as mesh-local, as well as all of the subscribed mesh-local
// prefix-based multicast addresses (such as link-local or
// realm-local All Thread Nodes addresses). It is important to call
// `ApplyNewMeshLocalPrefix()` first so that `ThreadNetif` can
// correctly signal the updates. It will first signal the removal
// of the previous address based on the old prefix, and then the
// addition of the new address with the new mesh-local prefix.
mMeshLocal64.GetAddress().SetPrefix(aMeshLocalPrefix);
mMeshLocal16.GetAddress().SetPrefix(aMeshLocalPrefix);
mLeaderAloc.GetAddress().SetPrefix(aMeshLocalPrefix);
Get<ThreadNetif>().ApplyNewMeshLocalPrefix();
// Just keep mesh local prefix if network interface is down
VerifyOrExit(Get<ThreadNetif>().IsUp());
// Some of the addresses may already be updated from the
// `ApplyNewMeshLocalPrefix()` call, but we apply the new prefix to
// them in case they are not yet added to the `Netif`. This ensures
// that addresses are always updated and other modules can retrieve
// them using methods such as `GetMeshLocal16()`, `GetMeshLocal64()`
// or `GetLinkLocalAllThreadNodesAddress()`, even if they have not
// yet been added to the `Netif`.
ApplyMeshLocalPrefix();
mMeshLocal64.GetAddress().SetPrefix(mMeshLocalPrefix);
mMeshLocal16.GetAddress().SetPrefix(mMeshLocalPrefix);
mLinkLocalAllThreadNodes.GetAddress().SetMulticastNetworkPrefix(mMeshLocalPrefix);
mRealmLocalAllThreadNodes.GetAddress().SetMulticastNetworkPrefix(mMeshLocalPrefix);
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
Get<BackboneRouter::Local>().ApplyNewMeshLocalPrefix();
#endif
Get<Notifier>().Signal(kEventThreadMeshLocalAddrChanged);
exit:
return;
@@ -928,71 +944,6 @@ exit:
}
#endif
void Mle::ApplyMeshLocalPrefix(void)
{
mLinkLocalAllThreadNodes.GetAddress().SetMulticastNetworkPrefix(GetMeshLocalPrefix());
mRealmLocalAllThreadNodes.GetAddress().SetMulticastNetworkPrefix(GetMeshLocalPrefix());
VerifyOrExit(!IsDisabled());
// Add the addresses back into the table.
Get<ThreadNetif>().AddUnicastAddress(mMeshLocal64);
Get<ThreadNetif>().SubscribeMulticast(mLinkLocalAllThreadNodes);
Get<ThreadNetif>().SubscribeMulticast(mRealmLocalAllThreadNodes);
if (IsAttached())
{
Get<ThreadNetif>().AddUnicastAddress(mMeshLocal16);
}
// update Leader ALOC
if (IsLeader())
{
Get<ThreadNetif>().AddUnicastAddress(mLeaderAloc);
}
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
Get<MeshCoP::Commissioner>().ApplyMeshLocalPrefix();
#endif
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
Get<MeshCoP::BorderAgent>().ApplyMeshLocalPrefix();
#endif
#if OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE
Get<Dhcp6::Server>().ApplyMeshLocalPrefix();
#endif
#if OPENTHREAD_CONFIG_NEIGHBOR_DISCOVERY_AGENT_ENABLE
Get<NeighborDiscovery::Agent>().ApplyMeshLocalPrefix();
#endif
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
for (ServiceAloc &serviceAloc : mServiceAlocs)
{
if (serviceAloc.IsInUse())
{
Get<ThreadNetif>().RemoveUnicastAddress(serviceAloc);
}
serviceAloc.ApplyMeshLocalPrefix(GetMeshLocalPrefix());
if (serviceAloc.IsInUse())
{
Get<ThreadNetif>().AddUnicastAddress(serviceAloc);
}
}
#endif
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
Get<BackboneRouter::Local>().ApplyMeshLocalPrefix();
#endif
exit:
// Changing the prefix also causes the mesh local address to be different.
Get<Notifier>().Signal(kEventThreadMeshLocalAddrChanged);
}
void Mle::SetRloc16(uint16_t aRloc16)
{
uint16_t oldRloc16 = GetRloc16();
@@ -1051,7 +1002,7 @@ Error Mle::GetLeaderAddress(Ip6::Address &aAddress) const
VerifyOrExit(GetRloc16() != Mac::kShortAddrInvalid, error = kErrorDetached);
aAddress.SetToRoutingLocator(GetMeshLocalPrefix(), Rloc16FromRouterId(mLeaderData.GetLeaderRouterId()));
aAddress.SetToRoutingLocator(mMeshLocalPrefix, Rloc16FromRouterId(mLeaderData.GetLeaderRouterId()));
exit:
return error;
@@ -1075,7 +1026,7 @@ Error Mle::GetServiceAloc(uint8_t aServiceId, Ip6::Address &aAddress) const
Error error = kErrorNone;
VerifyOrExit(GetRloc16() != Mac::kShortAddrInvalid, error = kErrorDetached);
aAddress.SetToAnycastLocator(GetMeshLocalPrefix(), ServiceAlocFromId(aServiceId));
aAddress.SetToAnycastLocator(mMeshLocalPrefix, ServiceAlocFromId(aServiceId));
exit:
return error;
@@ -1259,7 +1210,7 @@ exit:
Mle::ServiceAloc::ServiceAloc(void)
{
InitAsThreadOriginRealmLocalScope();
InitAsThreadOriginMeshLocal();
GetAddress().GetIid().SetToLocator(kNotInUse);
}
@@ -3954,10 +3905,7 @@ bool Mle::IsAnycastLocator(const Ip6::Address &aAddress) const
return IsMeshLocalAddress(aAddress) && aAddress.GetIid().IsAnycastLocator();
}
bool Mle::IsMeshLocalAddress(const Ip6::Address &aAddress) const
{
return (aAddress.GetPrefix() == GetMeshLocalPrefix());
}
bool Mle::IsMeshLocalAddress(const Ip6::Address &aAddress) const { return (aAddress.GetPrefix() == mMeshLocalPrefix); }
Error Mle::CheckReachability(uint16_t aMeshDest, const Ip6::Header &aIp6Header)
{
+17 -9
View File
@@ -352,7 +352,7 @@ public:
* @returns A reference to the Mesh Local Prefix.
*
*/
const Ip6::NetworkPrefix &GetMeshLocalPrefix(void) const { return mMeshLocal16.GetAddress().GetPrefix(); }
const Ip6::NetworkPrefix &GetMeshLocalPrefix(void) const { return mMeshLocalPrefix; }
/**
* Sets the Mesh Local Prefix.
@@ -377,12 +377,6 @@ public:
Error SetMeshLocalIid(const Ip6::InterfaceIdentifier &aMlIid);
#endif
/**
* Applies the Mesh Local Prefix.
*
*/
void ApplyMeshLocalPrefix(void);
/**
* Returns a reference to the Thread link-local address.
*
@@ -690,6 +684,21 @@ public:
*/
bool HasRestored(void) const { return mHasRestored; }
/**
* Indicates whether or not a given netif multicast address instance is a prefix-based address added by MLE and
* uses the mesh local prefix.
*
* @param[in] aAddress A `Netif::MulticastAddress` address instance.
*
* @retval TRUE If @p aAddress is a prefix-based address which uses the mesh local prefix.
* @retval FALSE If @p aAddress is not a prefix-based address which uses the mesh local prefix.
*
*/
bool IsMulticastAddressMeshLocalPrefixBased(const Ip6::Netif::MulticastAddress &aAddress) const
{
return (&aAddress == &mLinkLocalAllThreadNodes) || (&aAddress == &mRealmLocalAllThreadNodes);
}
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
/**
* Gets the CSL timeout.
@@ -1151,7 +1160,6 @@ private:
void MarkAsNotInUse(void) { SetAloc16(kNotInUse); }
uint16_t GetAloc16(void) const { return GetAddress().GetIid().GetLocator(); }
void SetAloc16(uint16_t aAloc16) { GetAddress().GetIid().SetLocator(aAloc16); }
void ApplyMeshLocalPrefix(const Ip6::NetworkPrefix &aPrefix) { GetAddress().SetPrefix(aPrefix); }
};
#endif
@@ -1401,12 +1409,12 @@ private:
DelayTimer mDelayedResponseTimer;
MsgTxTimer mMessageTransmissionTimer;
DetachGracefullyTimer mDetachGracefullyTimer;
Ip6::NetworkPrefix mMeshLocalPrefix;
Ip6::Netif::UnicastAddress mLinkLocal64;
Ip6::Netif::UnicastAddress mMeshLocal64;
Ip6::Netif::UnicastAddress mMeshLocal16;
Ip6::Netif::MulticastAddress mLinkLocalAllThreadNodes;
Ip6::Netif::MulticastAddress mRealmLocalAllThreadNodes;
Ip6::Netif::UnicastAddress mLeaderAloc;
};
} // namespace Mle
+2
View File
@@ -96,6 +96,8 @@ MleRouter::MleRouter(Instance &aInstance)
mLeaderWeight = kDefaultLeaderWeight;
#endif
mLeaderAloc.InitAsThreadOriginMeshLocal();
SetRouterId(kInvalidRouterId);
#if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
+2
View File
@@ -769,6 +769,8 @@ private:
MeshCoP::SteeringData mSteeringData;
#endif
Ip6::Netif::UnicastAddress mLeaderAloc;
Callback<otThreadDiscoveryRequestCallback> mDiscoveryRequestCallback;
};
+125
View File
@@ -0,0 +1,125 @@
#!/usr/bin/env python3
#
# Copyright (c) 2023, The OpenThread Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of the copyright holder nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
from cli import verify
from cli import verify_within
import cli
import time
# -----------------------------------------------------------------------------------------------------------------------
# Test description: Validate update of unicast/multicast mesh-local addresses on prefix change
#
# Network topology
#
# r1 ---- r2
#
test_name = __file__[:-3] if __file__.endswith('.py') else __file__
print('-' * 120)
print('Starting \'{}\''.format(test_name))
# -----------------------------------------------------------------------------------------------------------------------
# Creating `cli.Node` instances
speedup = 40
cli.Node.set_time_speedup_factor(speedup)
r1 = cli.Node()
r2 = cli.Node()
# -----------------------------------------------------------------------------------------------------------------------
# Form topology
r1.form('ml-change')
r2.join(r1)
verify(r1.get_state() == 'leader')
verify(r2.get_state() == 'router')
# -----------------------------------------------------------------------------------------------------------------------
# Test Implementation
r1.srp_server_enable()
r1.srp_client_enable_auto_start_mode()
r2.srp_client_enable_auto_start_mode()
time.sleep(0.5)
ml_prefix = r1.get_mesh_local_prefix()
ml_prefix = ml_prefix[:ml_prefix.index("/64") - 1]
# Validate that r1 has 4 mesh-local address: ML-EID, RLOC, leader ALOC
# and since it is acting as SRP server the service ALOC.
r1_addrs = r1.get_ip_addrs()
verify(sum([addr.startswith(ml_prefix) for addr in r1_addrs]) == 4)
# Validate that r1 has link-local and realm-local All Thread Nodes
# multicast addresses which are prefix-based and use mesh-local
# prefix.
r1_maddrs = r1.get_ip_maddrs()
verify(sum([ml_prefix in maddr for maddr in r1_maddrs]) == 2)
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Change the mesh-local prefix on all devices.
r2.cli('dataset clear')
r2.cli('dataset meshlocalprefix fd00:1122:3344:5566::')
r2.cli('dataset delaytimer 1100') # `toranj` allows 1000 msec as minimum in its config
r2.cli('dataset updater start')
time.sleep(0.5)
ml_prefix = r1.get_mesh_local_prefix()
ml_prefix = ml_prefix[:ml_prefix.index("/64") - 1]
verify(ml_prefix == 'fd00:1122:3344:5566:')
# Validate that all 4 mesh-local address on r1 are updated to use the
# new mesh-local prefix.
r1_addrs = r1.get_ip_addrs()
verify(sum([addr.startswith(ml_prefix) for addr in r1_addrs]) == 4)
# Validate the network data entry for SRP server is also updated to
# used the new address.
verify(r1.srp_client_get_server_address().startswith(ml_prefix))
# Validate the r1 multicast addresses are also updated
r1_maddrs = r1.get_ip_maddrs()
verify(sum([ml_prefix in maddr for maddr in r1_maddrs]) == 2)
# -----------------------------------------------------------------------------------------------------------------------
# Test finished
cli.Node.finalize_all_nodes()
print('\'{}\' passed.'.format(test_name))
@@ -131,6 +131,8 @@
#define OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH 1
#define OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE 1
#define OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE 1
#define OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE 1
+1
View File
@@ -189,6 +189,7 @@ if [ "$TORANJ_CLI" = 1 ]; then
run cli/test-022-netdata-full.py
run cli/test-023-mesh-diag.py
run cli/test-024-mle-adv-imax-change.py
run cli/test-025-mesh-local-prefix-change.py
run cli/test-400-srp-client-server.py
run cli/test-601-channel-manager-channel-change.py
# Skip the "channel-select" test on a TREL only radio link, since it