mirror of
https://github.com/espressif/openthread.git
synced 2026-08-11 05:07:47 +00:00
[mle] clean up MleRouter::HandleAdvertisement (#4338)
- Ensure there are no side effects if MLE frame counters have not yet been syncrhonzied. - Do not remove stale neighbor until end of processing Advertisement. This allows for complete processing of Advertisement if frame counters have already been established.
This commit is contained in:
@@ -2834,7 +2834,7 @@ otError Mle::HandleAdvertisement(const Message &aMessage, const Ip6::MessageInfo
|
||||
{
|
||||
if (IsFullThreadDevice())
|
||||
{
|
||||
SuccessOrExit(error = Get<MleRouter>().HandleAdvertisement(aMessage, aMessageInfo));
|
||||
SuccessOrExit(error = Get<MleRouter>().HandleAdvertisement(aMessage, aMessageInfo, aNeighbor));
|
||||
}
|
||||
else if ((aNeighbor == &mParent) && (mParent.GetRloc16() != sourceAddress.GetRloc16()))
|
||||
{
|
||||
|
||||
@@ -1138,7 +1138,9 @@ exit:
|
||||
return rval;
|
||||
}
|
||||
|
||||
otError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
otError MleRouter::HandleAdvertisement(const Message & aMessage,
|
||||
const Ip6::MessageInfo &aMessageInfo,
|
||||
Neighbor * aNeighbor)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
const otThreadLinkInfo *linkInfo = static_cast<const otThreadLinkInfo *>(aMessageInfo.GetLinkInfo());
|
||||
@@ -1149,7 +1151,6 @@ otError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::Messa
|
||||
RouteTlv route;
|
||||
uint32_t partitionId;
|
||||
Router * router;
|
||||
Neighbor * neighbor;
|
||||
uint8_t routerId;
|
||||
uint8_t routerCount;
|
||||
|
||||
@@ -1159,12 +1160,6 @@ otError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::Messa
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kSourceAddress, sizeof(sourceAddress), sourceAddress));
|
||||
VerifyOrExit(sourceAddress.IsValid(), error = OT_ERROR_PARSE);
|
||||
|
||||
// Remove stale neighbors
|
||||
if ((neighbor = GetNeighbor(macAddr)) != NULL && neighbor->GetRloc16() != sourceAddress.GetRloc16())
|
||||
{
|
||||
RemoveNeighbor(*neighbor);
|
||||
}
|
||||
|
||||
// Leader Data
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLeaderData, sizeof(leaderData), leaderData));
|
||||
VerifyOrExit(leaderData.IsValid(), error = OT_ERROR_PARSE);
|
||||
@@ -1196,7 +1191,7 @@ otError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::Messa
|
||||
error = OT_ERROR_DROP);
|
||||
}
|
||||
|
||||
if (mRole == OT_DEVICE_ROLE_CHILD && (mParent.GetExtAddress() == macAddr || !IsFullThreadDevice()))
|
||||
if (mRole == OT_DEVICE_ROLE_CHILD && (aNeighbor == &mParent || !IsFullThreadDevice()))
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
@@ -1215,6 +1210,8 @@ otError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::Messa
|
||||
}
|
||||
else if (leaderData.GetLeaderRouterId() != GetLeaderId())
|
||||
{
|
||||
VerifyOrExit(aNeighbor && aNeighbor->IsStateValid());
|
||||
|
||||
if (mRole != OT_DEVICE_ROLE_CHILD)
|
||||
{
|
||||
otLogInfoMle("Leader ID mismatch");
|
||||
@@ -1232,7 +1229,7 @@ otError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::Messa
|
||||
Get<TimeSync>().HandleTimeSyncMessage(aMessage);
|
||||
#endif
|
||||
|
||||
if (IsFullThreadDevice() &&
|
||||
if (IsFullThreadDevice() && (aNeighbor && aNeighbor->IsStateValid()) &&
|
||||
((mRouterTable.GetActiveRouterCount() == 0) ||
|
||||
(static_cast<int8_t>(route.GetRouterIdSequence() - mRouterTable.GetRouterIdSequence()) > 0)))
|
||||
{
|
||||
@@ -1280,18 +1277,11 @@ otError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::Messa
|
||||
ExitNow();
|
||||
|
||||
case OT_DEVICE_ROLE_CHILD:
|
||||
router = (macAddr == mParent.GetExtAddress()) ? &mParent : mRouterTable.GetRouter(routerId);
|
||||
VerifyOrExit(router != NULL);
|
||||
|
||||
if (router->IsStateValid() && IsFullThreadDevice() && (mRouterSelectionJitterTimeout == 0) &&
|
||||
(mRouterTable.GetActiveRouterCount() < mRouterUpgradeThreshold))
|
||||
if (aNeighbor == &mParent)
|
||||
{
|
||||
mRouterSelectionJitterTimeout = 1 + Random::NonCrypto::GetUint8InRange(0, mRouterSelectionJitter);
|
||||
ExitNow();
|
||||
}
|
||||
// MLE Advertisement from parent
|
||||
router = &mParent;
|
||||
|
||||
if (router == &mParent)
|
||||
{
|
||||
if (mParent.GetRloc16() != sourceAddress.GetRloc16())
|
||||
{
|
||||
BecomeDetached();
|
||||
@@ -1300,7 +1290,16 @@ otError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::Messa
|
||||
|
||||
if (IsFullThreadDevice())
|
||||
{
|
||||
Router *leader = mRouterTable.GetLeader();
|
||||
Router *leader;
|
||||
|
||||
if ((mRouterSelectionJitterTimeout == 0) &&
|
||||
(mRouterTable.GetActiveRouterCount() < mRouterUpgradeThreshold))
|
||||
{
|
||||
mRouterSelectionJitterTimeout = 1 + Random::NonCrypto::GetUint8InRange(0, mRouterSelectionJitter);
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
leader = mRouterTable.GetLeader();
|
||||
|
||||
if (leader != NULL)
|
||||
{
|
||||
@@ -1333,17 +1332,24 @@ otError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::Messa
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (IsFullThreadDevice() && !router->IsStateValid() && !router->IsStateLinkRequest() &&
|
||||
(mRouterTable.GetActiveLinkCount() < OPENTHREAD_CONFIG_MLE_CHILD_ROUTER_LINKS))
|
||||
else
|
||||
{
|
||||
router->SetExtAddress(macAddr);
|
||||
router->GetLinkInfo().Clear();
|
||||
router->GetLinkInfo().AddRss(Get<Mac::Mac>().GetNoiseFloor(), linkInfo->mRss);
|
||||
router->ResetLinkFailures();
|
||||
router->SetLastHeard(TimerMilli::GetNow());
|
||||
router->SetState(Neighbor::kStateLinkRequest);
|
||||
SendLinkRequest(router);
|
||||
ExitNow(error = OT_ERROR_NO_ROUTE);
|
||||
// MLE Advertisement not from parent, but from some other neighboring router
|
||||
router = mRouterTable.GetRouter(routerId);
|
||||
VerifyOrExit(router != NULL);
|
||||
|
||||
if (IsFullThreadDevice() && !router->IsStateValid() && !router->IsStateLinkRequest() &&
|
||||
(mRouterTable.GetActiveLinkCount() < OPENTHREAD_CONFIG_MLE_CHILD_ROUTER_LINKS))
|
||||
{
|
||||
router->SetExtAddress(macAddr);
|
||||
router->GetLinkInfo().Clear();
|
||||
router->GetLinkInfo().AddRss(Get<Mac::Mac>().GetNoiseFloor(), linkInfo->mRss);
|
||||
router->ResetLinkFailures();
|
||||
router->SetLastHeard(TimerMilli::GetNow());
|
||||
router->SetState(Neighbor::kStateLinkRequest);
|
||||
SendLinkRequest(router);
|
||||
ExitNow(error = OT_ERROR_NO_ROUTE);
|
||||
}
|
||||
}
|
||||
|
||||
router->SetLastHeard(TimerMilli::GetNow());
|
||||
@@ -1403,6 +1409,12 @@ otError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::Messa
|
||||
#endif
|
||||
|
||||
exit:
|
||||
if (aNeighbor && aNeighbor->GetRloc16() != sourceAddress.GetRloc16())
|
||||
{
|
||||
// Remove stale neighbors
|
||||
RemoveNeighbor(*aNeighbor);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -688,7 +688,7 @@ private:
|
||||
const Ip6::MessageInfo &aMessageInfo,
|
||||
uint32_t aKeySequence,
|
||||
Neighbor * aNeighbor);
|
||||
otError HandleAdvertisement(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
otError HandleAdvertisement(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Neighbor *);
|
||||
otError HandleParentRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
otError HandleChildIdRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, uint32_t aKeySequence);
|
||||
otError HandleChildUpdateRequest(const Message & aMessage,
|
||||
|
||||
@@ -139,7 +139,7 @@ private:
|
||||
{
|
||||
return OT_ERROR_DROP;
|
||||
}
|
||||
otError HandleAdvertisement(const Message &, const Ip6::MessageInfo &) { return OT_ERROR_DROP; }
|
||||
otError HandleAdvertisement(const Message &, const Ip6::MessageInfo &, Neighbor *) { return OT_ERROR_DROP; }
|
||||
otError HandleParentRequest(const Message &, const Ip6::MessageInfo &) { return OT_ERROR_DROP; }
|
||||
otError HandleChildIdRequest(const Message &, const Ip6::MessageInfo &, uint32_t) { return OT_ERROR_DROP; }
|
||||
otError HandleChildUpdateRequest(const Message &, const Ip6::MessageInfo &, uint32_t) { return OT_ERROR_DROP; }
|
||||
|
||||
Reference in New Issue
Block a user