From 50485f894e2b4a1bd48910559d180fa465e2ac4b Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Mon, 11 Sep 2017 09:00:44 -0700 Subject: [PATCH] [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. --- src/core/thread/mesh_forwarder.cpp | 44 ++++++++++++++++++++++++++++++ src/core/thread/mesh_forwarder.hpp | 2 ++ 2 files changed, 46 insertions(+) diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp index ebd168609..066f54a11 100644 --- a/src/core/thread/mesh_forwarder.cpp +++ b/src/core/thread/mesh_forwarder.cpp @@ -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(aFrame)->IsFragmentHeader()) + { + VerifyOrExit(sizeof(Lowpan::FragmentHeader) <= aFrameLength); + VerifyOrExit(reinterpret_cast(aFrame)->GetDatagramOffset() == 0); + + aFrame += reinterpret_cast(aFrame)->GetHeaderLength(); + aFrameLength -= reinterpret_cast(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) { diff --git a/src/core/thread/mesh_forwarder.hpp b/src/core/thread/mesh_forwarder.hpp index 115c24066..76585a517 100644 --- a/src/core/thread/mesh_forwarder.hpp +++ b/src/core/thread/mesh_forwarder.hpp @@ -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);