[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:
Jonathan Hui
2017-09-11 09:00:44 -07:00
committed by GitHub
parent 9f73f67950
commit 50485f894e
2 changed files with 46 additions and 0 deletions
+44
View File
@@ -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)
{
+2
View File
@@ -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);