[mle] update DetachGracefully() to stop BR routing manager (#8105)

This commit updates `Mle::DetachGracefully()` to stop Border Router
`RoutingManager`. This ensures that BR will have the chance to send
a final Router Advertisement message desecrating/removing its
previously advertised on-link or route prefixes.
This commit is contained in:
Abtin Keshavarzian
2022-09-01 08:19:57 -07:00
committed by GitHub
parent 30d65bca48
commit c3dd3ba8fb
4 changed files with 47 additions and 53 deletions
@@ -119,6 +119,21 @@ public:
*/
Error SetEnabled(bool aEnabled);
/**
* This method requests the Border Routing Manager to stop.
*
* If Border Routing Manager is running, calling this method immediately stops it and triggers the preparation
* and sending of a final Router Advertisement (RA) message on infrastructure interface which deprecates and/or
* removes any previously advertised PIO/RIO prefixes. If Routing Manager is not running (or not enabled), no
* action is taken.
*
* Note that this method does not change whether the Routing Manager is enabled or disabled (see `SetEnabled()`).
* It stops the Routing Manager temporarily. After calling this method if the device role gets changes (device
* gets attached) and/or the infra interface state gets changed, the Routing Manager may be started again.
*
*/
void RequestStop(void) { Stop(); }
/**
* This method gets the preference used when advertising Route Info Options (e.g., for discovered OMR prefixes) in
* Router Advertisement messages sent over the infrastructure link.
+29 -41
View File
@@ -4295,7 +4295,8 @@ uint64_t Mle::CalcParentCslMetric(const Mac::CslAccuracy &aCslAccuracy)
Error Mle::DetachGracefully(otDetachGracefullyCallback aCallback, void *aContext)
{
Error error = kErrorNone;
Error error = kErrorNone;
uint32_t timeout = kDetachGracefullyTimeout;
VerifyOrExit(!IsDetachingGracefully(), error = kErrorBusy);
@@ -4304,27 +4305,36 @@ Error Mle::DetachGracefully(otDetachGracefullyCallback aCallback, void *aContext
mDetachGracefullyCallback = aCallback;
mDetachGracefullyContext = aContext;
if (IsChild() || IsRouter())
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
Get<BorderRouter::RoutingManager>().RequestStop();
#endif
switch (mRole)
{
mDetachGracefullyTimer.Start(kDetachGracefullyTimeout);
}
else
{
// If the device is a leader, or it's already detached or disabled, we start the timer with zero duration to
// stop and invoke the callback when the timer fires, so the operation finishes immediately and asynchronously.
mDetachGracefullyTimer.Start(0);
case kRoleLeader:
break;
case kRoleRouter:
#if OPENTHREAD_FTD
Get<MleRouter>().SendAddressRelease();
#endif
break;
case kRoleChild:
IgnoreError(SendChildUpdateRequest(/* aAppendChallenge */ false, /* aTimeout */ 0));
break;
case kRoleDisabled:
case kRoleDetached:
// If device is already detached or disabled, we start the timer
// with zero duration to stop and invoke the callback when the
// timer fires, so the operation finishes immediately and
// asynchronously.
timeout = 0;
break;
}
if (IsChild())
{
IgnoreError(SendChildUpdateRequest(/* aAppendChallenge */ false, /* aTimeout */ 0));
}
#if OPENTHREAD_FTD
else if (IsRouter())
{
Get<MleRouter>().SendAddressRelease(&Mle::HandleDetachGracefullyAddressReleaseResponse, this);
}
#endif
mDetachGracefullyTimer.Start(timeout);
exit:
return error;
@@ -4340,28 +4350,6 @@ void Mle::HandleDetachGracefullyTimer(void)
Stop();
}
#if OPENTHREAD_FTD
void Mle::HandleDetachGracefullyAddressReleaseResponse(void * aContext,
otMessage * aMessage,
const otMessageInfo *aMessageInfo,
Error aResult)
{
OT_UNUSED_VARIABLE(aMessage);
OT_UNUSED_VARIABLE(aMessageInfo);
OT_UNUSED_VARIABLE(aResult);
static_cast<MleRouter *>(aContext)->HandleDetachGracefullyAddressReleaseResponse();
}
void Mle::HandleDetachGracefullyAddressReleaseResponse(void)
{
if (IsDetachingGracefully())
{
Stop();
}
}
#endif // OPENTHREAD_FTD
//---------------------------------------------------------------------------------------------------------------------
// TlvList
+2 -3
View File
@@ -3760,7 +3760,7 @@ exit:
return error;
}
void MleRouter::SendAddressRelease(Coap::ResponseHandler aResponseHandler, void *aResponseHandlerContext)
void MleRouter::SendAddressRelease(void)
{
Error error = kErrorNone;
Tmf::MessageInfo messageInfo(GetInstance());
@@ -3774,8 +3774,7 @@ void MleRouter::SendAddressRelease(Coap::ResponseHandler aResponseHandler, void
SuccessOrExit(error = messageInfo.SetSockAddrToRlocPeerAddrToLeaderRloc());
SuccessOrExit(error =
Get<Tmf::Agent>().SendMessage(*message, messageInfo, aResponseHandler, aResponseHandlerContext));
SuccessOrExit(error = Get<Tmf::Agent>().SendMessage(*message, messageInfo));
Log(kMessageSend, kTypeAddressRelease, messageInfo.GetPeerAddr());
+1 -9
View File
@@ -570,15 +570,6 @@ public:
void SetThreadVersionCheckEnabled(bool aEnabled) { mThreadVersionCheckEnabled = aEnabled; }
#endif
/**
* This function sends an Address Release.
*
* @param[in] aResponseHandler A pointer to a function that is called upon response reception or time-out.
* @param[in] aResponseHandlerContext A pointer to callback application-specific context.
*
*/
void SendAddressRelease(Coap::ResponseHandler aResponseHandler = nullptr, void *aResponseHandlerContext = nullptr);
private:
static constexpr uint16_t kDiscoveryMaxJitter = 250; // Max jitter delay Discovery Responses (in msec).
static constexpr uint32_t kStateUpdatePeriod = 1000; // State update period (in msec).
@@ -615,6 +606,7 @@ private:
ThreadStatusTlv::Status aResponseStatus,
const Router * aRouter,
const Ip6::MessageInfo &aMessageInfo);
void SendAddressRelease(void);
void SendAdvertisement(void);
Error SendLinkAccept(const Ip6::MessageInfo &aMessageInfo,
Neighbor * aNeighbor,