[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:
Tom Rebbert
2023-11-16 04:34:50 +01:00
committed by GitHub
parent 68426231a5
commit 5c34ca2cc3
2 changed files with 29 additions and 24 deletions
+24 -21
View File
@@ -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";
+5 -3
View File
@@ -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);