[mle] improve address registration in SendChildUpdateResponse() (#12863)

This commit improves the address registration behavior in
`Mle::SendChildUpdateResponse()` for non-FTD devices.

Previously, the device would always append only the mesh-local address
and then unconditionally attempt to send a follow-up Child Update
Request. The updated logic now checks if the parent's request
included a Challenge TLV. If not, all addresses are appended directly
to the response, eliminating the extra message exchange. If a
Challenge is present (indicating the parent is restoring its link),
only the mesh-local address is included to prevent message
fragmentation. In this case, if the device is attached and has
unregistered addresses, a follow-up Child Update Request is scheduled
via `mDelayedSender`.

The previous implementation indirectly assumed the parent would only
request the `Address Registration` TLV when restoring its link (the
current behavior of OpenThread parents). However, such behavior on the
parent is not strictly required and could change. This update on the
child side ensures robust address registration regardless of the
parent's specific behavior.
This commit is contained in:
Abtin Keshavarzian
2026-04-09 17:54:31 -05:00
committed by GitHub
parent fc3ffa7a69
commit f2c081b5ae
+23 -12
View File
@@ -1303,7 +1303,6 @@ Error Mle::SendChildUpdateResponse(const ChildUpdateResponseInfo &aInfo)
{
Error error = kErrorNone;
TxMessage *message;
bool checkAddress = false;
VerifyOrExit((message = NewMleMessage(kCommandChildUpdateResponse)) != nullptr, error = kErrorNoBufs);
@@ -1330,13 +1329,30 @@ Error Mle::SendChildUpdateResponse(const ChildUpdateResponseInfo &aInfo)
case Tlv::kAddressRegistration:
if (!IsFullThreadDevice())
{
// We only register the mesh-local address in the "Child
// Update Response" message and if there are additional
// addresses to register we follow up with a "Child Update
// Request".
AddressRegistrationMode addrRegMode = kAppendAllAddresses;
SuccessOrExit(error = message->AppendAddressRegistrationTlv(kAppendMeshLocalOnly));
checkAddress = true;
if (!aInfo.mChallenge.IsEmpty())
{
// If the parent is restoring its link, its request
// will include a Challenge. In this case, we only
// register the mesh-local address in the response
// message (to ensure it does not get fragmented).
// If there are additional addresses to register
// and the child itself is attached (it is not
// itself restoring its link to the parent), we
// schedule a follow-up "Child Update Request" to
// register the remaining addresses.
addrRegMode = kAppendMeshLocalOnly;
if (IsAttached() && HasUnregisteredAddress())
{
mDelayedSender.RemoveScheduledChildUpdateRequestToParent();
mDelayedSender.ScheduleChildUpdateRequestToParent(0);
}
}
SuccessOrExit(error = message->AppendAddressRegistrationTlv(addrRegMode));
}
break;
@@ -1372,11 +1388,6 @@ Error Mle::SendChildUpdateResponse(const ChildUpdateResponseInfo &aInfo)
Log(kMessageSend, kTypeChildUpdateResponseAsChild, aInfo.mDestination);
if (checkAddress && HasUnregisteredAddress())
{
IgnoreError(SendChildUpdateRequestToParent());
}
exit:
FreeMessageOnError(message, error);
return error;