[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()); 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";
+5 -3
View File
@@ -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);