mirror of
https://github.com/espressif/openthread.git
synced 2026-07-29 23:27:46 +00:00
Implement 2-hop loop avoidance. (#1091)
This commit is contained in:
@@ -1487,7 +1487,7 @@ void MeshForwarder::HandleReceivedFrame(Mac::Frame &aFrame)
|
||||
if (payloadLength >= sizeof(Lowpan::MeshHeader) &&
|
||||
reinterpret_cast<Lowpan::MeshHeader *>(payload)->IsMeshHeader())
|
||||
{
|
||||
HandleMesh(payload, payloadLength, messageInfo);
|
||||
HandleMesh(payload, payloadLength, macSource, messageInfo);
|
||||
}
|
||||
else if (payloadLength >= sizeof(Lowpan::FragmentHeader) &&
|
||||
reinterpret_cast<Lowpan::FragmentHeader *>(payload)->IsFragmentHeader())
|
||||
@@ -1521,7 +1521,8 @@ exit:
|
||||
}
|
||||
}
|
||||
|
||||
void MeshForwarder::HandleMesh(uint8_t *aFrame, uint8_t aFrameLength, const ThreadMessageInfo &aMessageInfo)
|
||||
void MeshForwarder::HandleMesh(uint8_t *aFrame, uint8_t aFrameLength, const Mac::Address &aMacSource,
|
||||
const ThreadMessageInfo &aMessageInfo)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
Message *message = NULL;
|
||||
@@ -1560,6 +1561,8 @@ void MeshForwarder::HandleMesh(uint8_t *aFrame, uint8_t aFrameLength, const Thre
|
||||
}
|
||||
else if (meshHeader.GetHopsLeft() > 0)
|
||||
{
|
||||
mMle.ResolveRoutingLoops(aMacSource.mShortAddress, meshDest.mShortAddress);
|
||||
|
||||
SuccessOrExit(error = CheckReachability(aFrame, aFrameLength, meshSource, meshDest));
|
||||
|
||||
meshHeader.SetHopsLeft(meshHeader.GetHopsLeft() - 1);
|
||||
|
||||
@@ -225,7 +225,8 @@ private:
|
||||
ThreadError GetMacSourceAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr);
|
||||
Message *GetDirectTransmission(void);
|
||||
Message *GetIndirectTransmission(const Child &aChild);
|
||||
void HandleMesh(uint8_t *aFrame, uint8_t aPayloadLength, const ThreadMessageInfo &aMessageInfo);
|
||||
void HandleMesh(uint8_t *aFrame, uint8_t aPayloadLength, const Mac::Address &aMacSource,
|
||||
const ThreadMessageInfo &aMessageInfo);
|
||||
void HandleFragment(uint8_t *aFrame, uint8_t aPayloadLength,
|
||||
const Mac::Address &aMacSource, const Mac::Address &aMacDest,
|
||||
const ThreadMessageInfo &aMessageInfo);
|
||||
|
||||
@@ -3530,6 +3530,20 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void MleRouter::ResolveRoutingLoops(uint16_t aSourceMac, uint16_t aDestRloc16)
|
||||
{
|
||||
if (aSourceMac == GetNextHop(aDestRloc16))
|
||||
{
|
||||
// loop detected
|
||||
Router *router = GetRouter(GetRouterId(aDestRloc16));
|
||||
assert(router != NULL);
|
||||
|
||||
// invalidate next hop
|
||||
router->mNextHop = kInvalidRouterId;
|
||||
ResetAdvertiseInterval();
|
||||
}
|
||||
}
|
||||
|
||||
ThreadError MleRouter::CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, Ip6::Header &aIp6Header)
|
||||
{
|
||||
Ip6::Address destination;
|
||||
|
||||
@@ -665,6 +665,15 @@ public:
|
||||
*/
|
||||
ThreadError CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, Ip6::Header &aIp6Header);
|
||||
|
||||
/**
|
||||
* This method resolves 2-hop routing loops.
|
||||
*
|
||||
* @param[in] aSourceMac The RLOC16 of the previous hop.
|
||||
* @param[in] aDestRloc16 The RLOC16 of the final destination.
|
||||
*
|
||||
*/
|
||||
void ResolveRoutingLoops(uint16_t aSourceMac, uint16_t aDestRloc16);
|
||||
|
||||
/**
|
||||
* This method checks if a given Router ID has correct value.
|
||||
*
|
||||
|
||||
@@ -135,6 +135,8 @@ public:
|
||||
|
||||
static int ComparePartitions(bool, const LeaderDataTlv &, bool, const LeaderDataTlv &) { return 0; }
|
||||
|
||||
void ResolveRoutingLoops(uint16_t, uint16_t) { }
|
||||
|
||||
ThreadError CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, Ip6::Header &aIp6Header) {
|
||||
return Mle::CheckReachability(aMeshSource, aMeshDest, aIp6Header);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user