mirror of
https://github.com/espressif/openthread.git
synced 2026-08-09 04:07:47 +00:00
[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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -96,6 +96,8 @@ MleRouter::MleRouter(Instance &aInstance)
|
||||
mLeaderWeight = kDefaultLeaderWeight;
|
||||
#endif
|
||||
|
||||
mLeaderAloc.InitAsThreadOriginMeshLocal();
|
||||
|
||||
SetRouterId(kInvalidRouterId);
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
|
||||
|
||||
@@ -769,6 +769,8 @@ private:
|
||||
MeshCoP::SteeringData mSteeringData;
|
||||
#endif
|
||||
|
||||
Ip6::Netif::UnicastAddress mLeaderAloc;
|
||||
|
||||
Callback<otThreadDiscoveryRequestCallback> mDiscoveryRequestCallback;
|
||||
};
|
||||
|
||||
|
||||
+125
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user