mirror of
https://github.com/espressif/openthread.git
synced 2026-08-06 10:47:46 +00:00
[mesh-forwarder] inspect forwarded frames to determine if child moved (#2182)
This commit adds logic to inspect frames being forwarded to determine if a child has moved to a different parent. If the message was received from a neighboring router and the IPv6 source address matches that of a child, the child is assumed to have moved and invalidated.
This commit is contained in:
@@ -1859,6 +1859,8 @@ void MeshForwarder::HandleMesh(uint8_t *aFrame, uint8_t aFrameLength, const Mac:
|
||||
meshDest.mLength = sizeof(meshDest.mShortAddress);
|
||||
meshDest.mShortAddress = meshHeader.GetDestination();
|
||||
|
||||
UpdateRoutes(aFrame, aFrameLength, meshSource, meshDest);
|
||||
|
||||
if (meshDest.mShortAddress == netif.GetMac().GetShortAddress())
|
||||
{
|
||||
aFrame += meshHeader.GetHeaderLength();
|
||||
@@ -1920,6 +1922,48 @@ exit:
|
||||
}
|
||||
}
|
||||
|
||||
void MeshForwarder::UpdateRoutes(uint8_t *aFrame, uint8_t aFrameLength,
|
||||
const Mac::Address &aMeshSource, const Mac::Address &aMeshDest)
|
||||
{
|
||||
ThreadNetif &netif = GetNetif();
|
||||
Lowpan::MeshHeader meshHeader;
|
||||
Ip6::Header ip6Header;
|
||||
Neighbor *neighbor;
|
||||
|
||||
VerifyOrExit(meshHeader.Init(aFrame, aFrameLength) == OT_ERROR_NONE);
|
||||
|
||||
// skip mesh header
|
||||
aFrame += meshHeader.GetHeaderLength();
|
||||
aFrameLength -= meshHeader.GetHeaderLength();
|
||||
|
||||
// skip fragment header
|
||||
if (aFrameLength >= 1 &&
|
||||
reinterpret_cast<Lowpan::FragmentHeader *>(aFrame)->IsFragmentHeader())
|
||||
{
|
||||
VerifyOrExit(sizeof(Lowpan::FragmentHeader) <= aFrameLength);
|
||||
VerifyOrExit(reinterpret_cast<Lowpan::FragmentHeader *>(aFrame)->GetDatagramOffset() == 0);
|
||||
|
||||
aFrame += reinterpret_cast<Lowpan::FragmentHeader *>(aFrame)->GetHeaderLength();
|
||||
aFrameLength -= reinterpret_cast<Lowpan::FragmentHeader *>(aFrame)->GetHeaderLength();
|
||||
}
|
||||
|
||||
// only process IPv6 packets
|
||||
VerifyOrExit(aFrameLength >= 1 && Lowpan::Lowpan::IsLowpanHc(aFrame));
|
||||
|
||||
VerifyOrExit(netif.GetLowpan().DecompressBaseHeader(ip6Header, aMeshSource, aMeshDest, aFrame, aFrameLength) > 0);
|
||||
|
||||
neighbor = netif.GetMle().GetNeighbor(ip6Header.GetSource());
|
||||
VerifyOrExit(neighbor != NULL && !neighbor->IsFullThreadDevice());
|
||||
|
||||
if (Mle::Mle::GetRouterId(meshHeader.GetSource()) != Mle::Mle::GetRouterId(GetNetif().GetMac().GetShortAddress()))
|
||||
{
|
||||
netif.GetMle().RemoveNeighbor(*neighbor);
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
otError MeshForwarder::CheckReachability(uint8_t *aFrame, uint8_t aFrameLength,
|
||||
const Mac::Address &aMeshSource, const Mac::Address &aMeshDest)
|
||||
{
|
||||
|
||||
@@ -254,6 +254,8 @@ private:
|
||||
|
||||
otError CheckReachability(uint8_t *aFrame, uint8_t aFrameLength,
|
||||
const Mac::Address &aMeshSource, const Mac::Address &aMeshDest);
|
||||
void UpdateRoutes(uint8_t *aFrame, uint8_t aFrameLength,
|
||||
const Mac::Address &aMeshSource, const Mac::Address &aMeshDest);
|
||||
|
||||
otError GetMacDestinationAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr);
|
||||
otError GetMacSourceAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr);
|
||||
|
||||
Reference in New Issue
Block a user