mirror of
https://github.com/espressif/openthread.git
synced 2026-07-28 14:47:46 +00:00
[mesh-forwarder] ensure mesh dst checks for dst unreach (#4879)
An out-dated EID-to-RLOC map cache may lead a device to send an IPv6 datagram to a device that does not have the IPv6 Destination Address assigned to its interface. However, the existing implementation would not send back an ICMPv6 Destination Unreachable message necessary to invalidate the originator's EID-to-RLOC cache entry. This implementation adds reachability checks on the mesh destination receive path to ensure that reachability checks are performed in the above situation.
This commit is contained in:
@@ -1102,9 +1102,12 @@ void MeshForwarder::HandleFragment(const uint8_t * aFrame,
|
||||
message->SetNetworkTimeOffset(aLinkInfo.mNetworkTimeOffset);
|
||||
#endif
|
||||
|
||||
// Security Check
|
||||
VerifyOrExit(Get<Ip6::Filter>().Accept(*message), error = OT_ERROR_DROP);
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
SendIcmpErrorIfDstUnreach(*message, aMacSource, aMacDest);
|
||||
#endif
|
||||
|
||||
// Allow re-assembly of only one message at a time on a SED by clearing
|
||||
// any remaining fragments in reassembly list upon receiving of a new
|
||||
// (secure) first fragment.
|
||||
@@ -1301,9 +1304,12 @@ void MeshForwarder::HandleLowpanHC(const uint8_t * aFrame,
|
||||
message->SetNetworkTimeOffset(aLinkInfo.mNetworkTimeOffset);
|
||||
#endif
|
||||
|
||||
// Security Check
|
||||
VerifyOrExit(Get<Ip6::Filter>().Accept(*message), error = OT_ERROR_DROP);
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
SendIcmpErrorIfDstUnreach(*message, aMacSource, aMacDest);
|
||||
#endif
|
||||
|
||||
exit:
|
||||
|
||||
if (error == OT_ERROR_NONE)
|
||||
|
||||
@@ -336,6 +336,9 @@ private:
|
||||
kMessageEvict, ///< Indicates that the message was evicted.
|
||||
};
|
||||
|
||||
void SendIcmpErrorIfDstUnreach(const Message & aMessage,
|
||||
const Mac::Address &aMacSource,
|
||||
const Mac::Address &aMacDest);
|
||||
otError CheckReachability(const uint8_t * aFrame,
|
||||
uint16_t aFrameLength,
|
||||
const Mac::Address &aMeshSource,
|
||||
|
||||
@@ -500,11 +500,6 @@ otError MeshForwarder::UpdateIp6RouteFtd(Ip6::Header &ip6Header, Message &aMessa
|
||||
}
|
||||
|
||||
exit:
|
||||
if (error == OT_ERROR_NO_ROUTE)
|
||||
{
|
||||
SendDestinationUnreachable(mMeshSource, aMessage);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -521,6 +516,35 @@ otError MeshForwarder::GetIp6Header(const uint8_t * aFrame,
|
||||
nextHeaderCompressed);
|
||||
}
|
||||
|
||||
void MeshForwarder::SendIcmpErrorIfDstUnreach(const Message & aMessage,
|
||||
const Mac::Address &aMacSource,
|
||||
const Mac::Address &aMacDest)
|
||||
{
|
||||
otError error;
|
||||
Ip6::Header ip6header;
|
||||
Child * child;
|
||||
|
||||
VerifyOrExit(aMacSource.IsShort() && aMacDest.IsShort(), OT_NOOP);
|
||||
|
||||
child = Get<ChildTable>().FindChild(aMacSource.GetShort(), Child::kInStateAnyExceptInvalid);
|
||||
VerifyOrExit((child == NULL) || child->IsFullThreadDevice(), OT_NOOP);
|
||||
|
||||
aMessage.Read(0, sizeof(ip6header), &ip6header);
|
||||
VerifyOrExit(!ip6header.GetDestination().IsMulticast() &&
|
||||
Get<NetworkData::Leader>().IsOnMesh(ip6header.GetDestination()),
|
||||
OT_NOOP);
|
||||
|
||||
error = Get<Mle::MleRouter>().CheckReachability(aMacDest.GetShort(), ip6header);
|
||||
|
||||
if (error == OT_ERROR_NO_ROUTE)
|
||||
{
|
||||
SendDestinationUnreachable(aMacSource.GetShort(), aMessage);
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
otError MeshForwarder::CheckReachability(const uint8_t * aFrame,
|
||||
uint16_t aFrameLength,
|
||||
const Mac::Address &aMeshSource,
|
||||
|
||||
@@ -897,6 +897,11 @@ public:
|
||||
static bool IsRouterIdValid(uint8_t aRouterId) { return aRouterId <= kMaxRouterId; }
|
||||
|
||||
otError SendChildUpdateRequest(void) { return Mle::SendChildUpdateRequest(); }
|
||||
|
||||
otError CheckReachability(uint16_t aMeshDest, Ip6::Header &aIp6Header)
|
||||
{
|
||||
return Mle::CheckReachability(aMeshDest, aIp6Header);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // OPENTHREAD_MTD
|
||||
|
||||
Reference in New Issue
Block a user