mirror of
https://github.com/espressif/openthread.git
synced 2026-10-01 13:27:42 +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());
|
destination.SetToLinkLocalAddress(mParent.GetExtAddress());
|
||||||
SuccessOrExit(error = message->SendTo(destination));
|
SuccessOrExit(error = message->SendTo(destination));
|
||||||
|
|
||||||
Log(kMessageSend, kTypeChildUpdateRequestOfParent, destination);
|
Log(kMessageSend, kTypeChildUpdateRequestAsChild, destination);
|
||||||
|
|
||||||
if (!IsRxOnWhenIdle())
|
if (!IsRxOnWhenIdle())
|
||||||
{
|
{
|
||||||
@@ -2117,12 +2117,13 @@ exit:
|
|||||||
return error;
|
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;
|
Error error = kErrorNone;
|
||||||
Ip6::Address destination;
|
TxMessage *message;
|
||||||
TxMessage *message;
|
bool checkAddress = false;
|
||||||
bool checkAddress = false;
|
|
||||||
|
|
||||||
VerifyOrExit((message = NewMleMessage(kCommandChildUpdateResponse)) != nullptr, error = kErrorNoBufs);
|
VerifyOrExit((message = NewMleMessage(kCommandChildUpdateResponse)) != nullptr, error = kErrorNoBufs);
|
||||||
SuccessOrExit(error = message->AppendSourceAddressTlv());
|
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(aDestination));
|
||||||
SuccessOrExit(error = message->SendTo(destination));
|
|
||||||
|
|
||||||
Log(kMessageSend, kTypeChildUpdateResponseOfParent, destination);
|
Log(kMessageSend, kTypeChildUpdateResponseAsChild, aDestination);
|
||||||
|
|
||||||
if (checkAddress && HasUnregisteredAddress())
|
if (checkAddress && HasUnregisteredAddress())
|
||||||
{
|
{
|
||||||
@@ -3472,7 +3472,7 @@ void Mle::HandleChildUpdateRequest(RxInfo &aRxInfo)
|
|||||||
// Source Address
|
// Source Address
|
||||||
SuccessOrExit(error = Tlv::Find<SourceAddressTlv>(aRxInfo.mMessage, sourceAddress));
|
SuccessOrExit(error = Tlv::Find<SourceAddressTlv>(aRxInfo.mMessage, sourceAddress));
|
||||||
|
|
||||||
Log(kMessageReceive, kTypeChildUpdateRequestOfParent, aRxInfo.mMessageInfo.GetPeerAddr(), sourceAddress);
|
Log(kMessageReceive, kTypeChildUpdateRequestAsChild, aRxInfo.mMessageInfo.GetPeerAddr(), sourceAddress);
|
||||||
|
|
||||||
// Challenge
|
// Challenge
|
||||||
switch (aRxInfo.mMessage.ReadChallengeTlv(challenge))
|
switch (aRxInfo.mMessage.ReadChallengeTlv(challenge))
|
||||||
@@ -3553,10 +3553,11 @@ void Mle::HandleChildUpdateRequest(RxInfo &aRxInfo)
|
|||||||
}
|
}
|
||||||
#endif
|
#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:
|
exit:
|
||||||
LogProcessError(kTypeChildUpdateRequestOfParent, error);
|
LogProcessError(kTypeChildUpdateRequestAsChild, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mle::HandleChildUpdateResponse(RxInfo &aRxInfo)
|
void Mle::HandleChildUpdateResponse(RxInfo &aRxInfo)
|
||||||
@@ -3570,7 +3571,7 @@ void Mle::HandleChildUpdateResponse(RxInfo &aRxInfo)
|
|||||||
uint16_t sourceAddress;
|
uint16_t sourceAddress;
|
||||||
uint32_t timeout;
|
uint32_t timeout;
|
||||||
|
|
||||||
Log(kMessageReceive, kTypeChildUpdateResponseOfParent, aRxInfo.mMessageInfo.GetPeerAddr());
|
Log(kMessageReceive, kTypeChildUpdateResponseAsChild, aRxInfo.mMessageInfo.GetPeerAddr());
|
||||||
|
|
||||||
switch (aRxInfo.mMessage.ReadResponseTlv(response))
|
switch (aRxInfo.mMessage.ReadResponseTlv(response))
|
||||||
{
|
{
|
||||||
@@ -3711,7 +3712,7 @@ exit:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogProcessError(kTypeChildUpdateResponseOfParent, error);
|
LogProcessError(kTypeChildUpdateResponseAsChild, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mle::HandleAnnounce(RxInfo &aRxInfo)
|
void Mle::HandleAnnounce(RxInfo &aRxInfo)
|
||||||
@@ -4137,8 +4138,8 @@ const char *Mle::MessageTypeToString(MessageType aType)
|
|||||||
"Child ID Request", // (2) kTypeChildIdRequest
|
"Child ID Request", // (2) kTypeChildIdRequest
|
||||||
"Child ID Request", // (3) kTypeChildIdRequestShort
|
"Child ID Request", // (3) kTypeChildIdRequestShort
|
||||||
"Child ID Response", // (4) kTypeChildIdResponse
|
"Child ID Response", // (4) kTypeChildIdResponse
|
||||||
"Child Update Request", // (5) kTypeChildUpdateRequestOfParent
|
"Child Update Request", // (5) kTypeChildUpdateRequestAsChild
|
||||||
"Child Update Response", // (6) kTypeChildUpdateResponseOfParent
|
"Child Update Response", // (6) kTypeChildUpdateResponseAsChild
|
||||||
"Data Request", // (7) kTypeDataRequest
|
"Data Request", // (7) kTypeDataRequest
|
||||||
"Data Response", // (8) kTypeDataResponse
|
"Data Response", // (8) kTypeDataResponse
|
||||||
"Discovery Request", // (9) kTypeDiscoveryRequest
|
"Discovery Request", // (9) kTypeDiscoveryRequest
|
||||||
@@ -4177,8 +4178,8 @@ const char *Mle::MessageTypeToString(MessageType aType)
|
|||||||
static_assert(kTypeChildIdRequest == 2, "kTypeChildIdRequest value is incorrect");
|
static_assert(kTypeChildIdRequest == 2, "kTypeChildIdRequest value is incorrect");
|
||||||
static_assert(kTypeChildIdRequestShort == 3, "kTypeChildIdRequestShort value is incorrect");
|
static_assert(kTypeChildIdRequestShort == 3, "kTypeChildIdRequestShort value is incorrect");
|
||||||
static_assert(kTypeChildIdResponse == 4, "kTypeChildIdResponse value is incorrect");
|
static_assert(kTypeChildIdResponse == 4, "kTypeChildIdResponse value is incorrect");
|
||||||
static_assert(kTypeChildUpdateRequestOfParent == 5, "kTypeChildUpdateRequestOfParent value is incorrect");
|
static_assert(kTypeChildUpdateRequestAsChild == 5, "kTypeChildUpdateRequestAsChild value is incorrect");
|
||||||
static_assert(kTypeChildUpdateResponseOfParent == 6, "kTypeChildUpdateResponseOfParent value is incorrect");
|
static_assert(kTypeChildUpdateResponseAsChild == 6, "kTypeChildUpdateResponseAsChild value is incorrect");
|
||||||
static_assert(kTypeDataRequest == 7, "kTypeDataRequest value is incorrect");
|
static_assert(kTypeDataRequest == 7, "kTypeDataRequest value is incorrect");
|
||||||
static_assert(kTypeDataResponse == 8, "kTypeDataResponse value is incorrect");
|
static_assert(kTypeDataResponse == 8, "kTypeDataResponse value is incorrect");
|
||||||
static_assert(kTypeDiscoveryRequest == 9, "kTypeDiscoveryRequest 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 = "";
|
const char *str = "";
|
||||||
|
|
||||||
|
OT_UNUSED_VARIABLE(aAction); // Not currently used in non-FTD builds
|
||||||
|
|
||||||
switch (aType)
|
switch (aType)
|
||||||
{
|
{
|
||||||
case kTypeChildIdRequestShort:
|
case kTypeChildIdRequestShort:
|
||||||
str = " - short";
|
str = " - short";
|
||||||
break;
|
break;
|
||||||
case kTypeChildUpdateRequestOfParent:
|
case kTypeChildUpdateRequestAsChild:
|
||||||
case kTypeChildUpdateResponseOfParent:
|
case kTypeChildUpdateResponseAsChild:
|
||||||
str = (aAction == kMessageReceive) ? " from parent" : " to parent";
|
str = " as child";
|
||||||
break;
|
break;
|
||||||
case kTypeParentRequestToRouters:
|
case kTypeParentRequestToRouters:
|
||||||
str = " to routers";
|
str = " to routers";
|
||||||
|
|||||||
@@ -927,8 +927,8 @@ private:
|
|||||||
kTypeChildIdRequest,
|
kTypeChildIdRequest,
|
||||||
kTypeChildIdRequestShort,
|
kTypeChildIdRequestShort,
|
||||||
kTypeChildIdResponse,
|
kTypeChildIdResponse,
|
||||||
kTypeChildUpdateRequestOfParent,
|
kTypeChildUpdateRequestAsChild,
|
||||||
kTypeChildUpdateResponseOfParent,
|
kTypeChildUpdateResponseAsChild,
|
||||||
kTypeDataRequest,
|
kTypeDataRequest,
|
||||||
kTypeDataResponse,
|
kTypeDataResponse,
|
||||||
kTypeDiscoveryRequest,
|
kTypeDiscoveryRequest,
|
||||||
@@ -1230,7 +1230,9 @@ private:
|
|||||||
Error SendChildUpdateRequest(ChildUpdateRequestMode aMode);
|
Error SendChildUpdateRequest(ChildUpdateRequestMode aMode);
|
||||||
Error SendDataRequestAfterDelay(const Ip6::Address &aDestination, uint16_t aDelay);
|
Error SendDataRequestAfterDelay(const Ip6::Address &aDestination, uint16_t aDelay);
|
||||||
Error SendChildUpdateRequest(void);
|
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 SetRloc16(uint16_t aRloc16);
|
||||||
void SetStateDetached(void);
|
void SetStateDetached(void);
|
||||||
void SetStateChild(uint16_t aRloc16);
|
void SetStateChild(uint16_t aRloc16);
|
||||||
|
|||||||
Reference in New Issue
Block a user