mirror of
https://github.com/espressif/openthread.git
synced 2026-07-30 23:57:47 +00:00
[mle] fix responding to "Child Update Request" from non-parent device (#9609)
After a router with children downgrades, it's former children will still send child update requests until they timeout. This allows the downgraded device to respond with status TLV indicating error to help those children realize they need to reattach sooner.
This commit is contained in:
+24
-21
@@ -2096,7 +2096,7 @@ Error Mle::SendChildUpdateRequest(ChildUpdateRequestMode aMode)
|
||||
destination.SetToLinkLocalAddress(mParent.GetExtAddress());
|
||||
SuccessOrExit(error = message->SendTo(destination));
|
||||
|
||||
Log(kMessageSend, kTypeChildUpdateRequestOfParent, destination);
|
||||
Log(kMessageSend, kTypeChildUpdateRequestAsChild, destination);
|
||||
|
||||
if (!IsRxOnWhenIdle())
|
||||
{
|
||||
@@ -2117,12 +2117,13 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error Mle::SendChildUpdateResponse(const TlvList &aTlvList, const RxChallenge &aChallenge)
|
||||
Error Mle::SendChildUpdateResponse(const TlvList &aTlvList,
|
||||
const RxChallenge &aChallenge,
|
||||
const Ip6::Address &aDestination)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Ip6::Address destination;
|
||||
TxMessage *message;
|
||||
bool checkAddress = false;
|
||||
Error error = kErrorNone;
|
||||
TxMessage *message;
|
||||
bool checkAddress = false;
|
||||
|
||||
VerifyOrExit((message = NewMleMessage(kCommandChildUpdateResponse)) != nullptr, error = kErrorNoBufs);
|
||||
SuccessOrExit(error = message->AppendSourceAddressTlv());
|
||||
@@ -2181,10 +2182,9 @@ Error Mle::SendChildUpdateResponse(const TlvList &aTlvList, const RxChallenge &a
|
||||
}
|
||||
}
|
||||
|
||||
destination.SetToLinkLocalAddress(mParent.GetExtAddress());
|
||||
SuccessOrExit(error = message->SendTo(destination));
|
||||
SuccessOrExit(error = message->SendTo(aDestination));
|
||||
|
||||
Log(kMessageSend, kTypeChildUpdateResponseOfParent, destination);
|
||||
Log(kMessageSend, kTypeChildUpdateResponseAsChild, aDestination);
|
||||
|
||||
if (checkAddress && HasUnregisteredAddress())
|
||||
{
|
||||
@@ -3472,7 +3472,7 @@ void Mle::HandleChildUpdateRequest(RxInfo &aRxInfo)
|
||||
// Source Address
|
||||
SuccessOrExit(error = Tlv::Find<SourceAddressTlv>(aRxInfo.mMessage, sourceAddress));
|
||||
|
||||
Log(kMessageReceive, kTypeChildUpdateRequestOfParent, aRxInfo.mMessageInfo.GetPeerAddr(), sourceAddress);
|
||||
Log(kMessageReceive, kTypeChildUpdateRequestAsChild, aRxInfo.mMessageInfo.GetPeerAddr(), sourceAddress);
|
||||
|
||||
// Challenge
|
||||
switch (aRxInfo.mMessage.ReadChallengeTlv(challenge))
|
||||
@@ -3553,10 +3553,11 @@ void Mle::HandleChildUpdateRequest(RxInfo &aRxInfo)
|
||||
}
|
||||
#endif
|
||||
|
||||
SuccessOrExit(error = SendChildUpdateResponse(tlvList, challenge));
|
||||
// Send the response to the requester, regardless if it's this device's parent or not
|
||||
SuccessOrExit(error = SendChildUpdateResponse(tlvList, challenge, aRxInfo.mMessageInfo.GetPeerAddr()));
|
||||
|
||||
exit:
|
||||
LogProcessError(kTypeChildUpdateRequestOfParent, error);
|
||||
LogProcessError(kTypeChildUpdateRequestAsChild, error);
|
||||
}
|
||||
|
||||
void Mle::HandleChildUpdateResponse(RxInfo &aRxInfo)
|
||||
@@ -3570,7 +3571,7 @@ void Mle::HandleChildUpdateResponse(RxInfo &aRxInfo)
|
||||
uint16_t sourceAddress;
|
||||
uint32_t timeout;
|
||||
|
||||
Log(kMessageReceive, kTypeChildUpdateResponseOfParent, aRxInfo.mMessageInfo.GetPeerAddr());
|
||||
Log(kMessageReceive, kTypeChildUpdateResponseAsChild, aRxInfo.mMessageInfo.GetPeerAddr());
|
||||
|
||||
switch (aRxInfo.mMessage.ReadResponseTlv(response))
|
||||
{
|
||||
@@ -3711,7 +3712,7 @@ exit:
|
||||
}
|
||||
}
|
||||
|
||||
LogProcessError(kTypeChildUpdateResponseOfParent, error);
|
||||
LogProcessError(kTypeChildUpdateResponseAsChild, error);
|
||||
}
|
||||
|
||||
void Mle::HandleAnnounce(RxInfo &aRxInfo)
|
||||
@@ -4137,8 +4138,8 @@ const char *Mle::MessageTypeToString(MessageType aType)
|
||||
"Child ID Request", // (2) kTypeChildIdRequest
|
||||
"Child ID Request", // (3) kTypeChildIdRequestShort
|
||||
"Child ID Response", // (4) kTypeChildIdResponse
|
||||
"Child Update Request", // (5) kTypeChildUpdateRequestOfParent
|
||||
"Child Update Response", // (6) kTypeChildUpdateResponseOfParent
|
||||
"Child Update Request", // (5) kTypeChildUpdateRequestAsChild
|
||||
"Child Update Response", // (6) kTypeChildUpdateResponseAsChild
|
||||
"Data Request", // (7) kTypeDataRequest
|
||||
"Data Response", // (8) kTypeDataResponse
|
||||
"Discovery Request", // (9) kTypeDiscoveryRequest
|
||||
@@ -4177,8 +4178,8 @@ const char *Mle::MessageTypeToString(MessageType aType)
|
||||
static_assert(kTypeChildIdRequest == 2, "kTypeChildIdRequest value is incorrect");
|
||||
static_assert(kTypeChildIdRequestShort == 3, "kTypeChildIdRequestShort value is incorrect");
|
||||
static_assert(kTypeChildIdResponse == 4, "kTypeChildIdResponse value is incorrect");
|
||||
static_assert(kTypeChildUpdateRequestOfParent == 5, "kTypeChildUpdateRequestOfParent value is incorrect");
|
||||
static_assert(kTypeChildUpdateResponseOfParent == 6, "kTypeChildUpdateResponseOfParent value is incorrect");
|
||||
static_assert(kTypeChildUpdateRequestAsChild == 5, "kTypeChildUpdateRequestAsChild value is incorrect");
|
||||
static_assert(kTypeChildUpdateResponseAsChild == 6, "kTypeChildUpdateResponseAsChild value is incorrect");
|
||||
static_assert(kTypeDataRequest == 7, "kTypeDataRequest value is incorrect");
|
||||
static_assert(kTypeDataResponse == 8, "kTypeDataResponse value is incorrect");
|
||||
static_assert(kTypeDiscoveryRequest == 9, "kTypeDiscoveryRequest value is incorrect");
|
||||
@@ -4230,14 +4231,16 @@ const char *Mle::MessageTypeActionToSuffixString(MessageType aType, MessageActio
|
||||
{
|
||||
const char *str = "";
|
||||
|
||||
OT_UNUSED_VARIABLE(aAction); // Not currently used in non-FTD builds
|
||||
|
||||
switch (aType)
|
||||
{
|
||||
case kTypeChildIdRequestShort:
|
||||
str = " - short";
|
||||
break;
|
||||
case kTypeChildUpdateRequestOfParent:
|
||||
case kTypeChildUpdateResponseOfParent:
|
||||
str = (aAction == kMessageReceive) ? " from parent" : " to parent";
|
||||
case kTypeChildUpdateRequestAsChild:
|
||||
case kTypeChildUpdateResponseAsChild:
|
||||
str = " as child";
|
||||
break;
|
||||
case kTypeParentRequestToRouters:
|
||||
str = " to routers";
|
||||
|
||||
@@ -927,8 +927,8 @@ private:
|
||||
kTypeChildIdRequest,
|
||||
kTypeChildIdRequestShort,
|
||||
kTypeChildIdResponse,
|
||||
kTypeChildUpdateRequestOfParent,
|
||||
kTypeChildUpdateResponseOfParent,
|
||||
kTypeChildUpdateRequestAsChild,
|
||||
kTypeChildUpdateResponseAsChild,
|
||||
kTypeDataRequest,
|
||||
kTypeDataResponse,
|
||||
kTypeDiscoveryRequest,
|
||||
@@ -1230,7 +1230,9 @@ private:
|
||||
Error SendChildUpdateRequest(ChildUpdateRequestMode aMode);
|
||||
Error SendDataRequestAfterDelay(const Ip6::Address &aDestination, uint16_t aDelay);
|
||||
Error SendChildUpdateRequest(void);
|
||||
Error SendChildUpdateResponse(const TlvList &aTlvList, const RxChallenge &aChallenge);
|
||||
Error SendChildUpdateResponse(const TlvList &aTlvList,
|
||||
const RxChallenge &aChallenge,
|
||||
const Ip6::Address &aDestination);
|
||||
void SetRloc16(uint16_t aRloc16);
|
||||
void SetStateDetached(void);
|
||||
void SetStateChild(uint16_t aRloc16);
|
||||
|
||||
Reference in New Issue
Block a user