[mle] fix NeighborHasComparableConnectivity() (#8535)

This commit updates `NeighborHasComparableConnectivity()` method which
is used as one of conditions to decide whether the router needs to
downgrade to REED. This method check whether a given neighboring
router has as good or better-quality links to all our neighboring
routers with two-way link quality of two or better.

The previous implementation assumed that routers in `RouterTable`
would match the same set of routers and their order as in the
received `RouteTlv` from the peer router. This may not necessarily be
the case (particularly after #8483). This commit changes the
implementation so that we iterate over all Router IDs and directly
track the index of each allocated router ID in the received
`RouteTlv`.
This commit is contained in:
Abtin Keshavarzian
2022-12-15 22:38:38 -08:00
committed by GitHub
parent f2ed78770e
commit 0f3de13ca8
2 changed files with 33 additions and 25 deletions
+32 -24
View File
@@ -1441,7 +1441,7 @@ Error MleRouter::HandleAdvertisement(RxInfo &aRxInfo)
if (routerCount > mRouterDowngradeThreshold && mRouterSelectionJitterTimeout == 0 &&
HasMinDowngradeNeighborRouters() && HasSmallNumberOfChildren() &&
HasOneNeighborWithComparableConnectivity(routeTlv, routerId)
NeighborHasComparableConnectivity(routeTlv, routerId)
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE && OPENTHREAD_CONFIG_BORDER_ROUTER_REQUEST_ROUTER_ROLE
&& !Get<NetworkData::Notifier>().IsEligibleForRouterRoleUpgradeAsBorderRouter()
#endif
@@ -4166,52 +4166,60 @@ bool MleRouter::HasMinDowngradeNeighborRouters(void)
return routerCount >= kMinDowngradeNeighbors;
}
bool MleRouter::HasOneNeighborWithComparableConnectivity(const RouteTlv &aRouteTlv, uint8_t aRouterId)
bool MleRouter::NeighborHasComparableConnectivity(const RouteTlv &aRouteTlv, uint8_t aNeighborId) const
{
uint8_t routerCount = 0;
bool rval = true;
// Check whether the neighboring router with Router ID `aNeighborId`
// (along with its `aRouteTlv`) has as good or better-quality links
// to all our neighboring routers which have a two-way link quality
// of two or better.
// process local neighbor routers
for (const Router &router : Get<RouterTable>())
bool isComparable = true;
for (uint8_t routerId = 0, index = 0; routerId <= kMaxRouterId;
index += aRouteTlv.IsRouterIdSet(routerId) ? 1 : 0, routerId++)
{
LinkQuality localLinkQuality;
LinkQuality peerLinkQuality;
const Router *router;
LinkQuality localLinkQuality;
LinkQuality peerLinkQuality;
if (!router.IsStateValid() || router.GetRouterId() == mRouterId || router.GetRouterId() == aRouterId)
if ((routerId == mRouterId) || (routerId == aNeighborId))
{
routerCount++;
continue;
}
localLinkQuality = router.GetTwoWayLinkQuality();
router = mRouterTable.FindRouterById(routerId);
if ((router == nullptr) || !router->IsStateValid())
{
continue;
}
localLinkQuality = router->GetTwoWayLinkQuality();
if (localLinkQuality < kLinkQuality2)
{
routerCount++;
continue;
}
// check if this neighbor router is in peer Route64 TLV
if (!aRouteTlv.IsRouterIdSet(router.GetRouterId()))
// `router` is our neighbor with two-way link quality of
// at least two. Check that `aRouteTlv` has as good or
// better-quality link to it as well.
if (!aRouteTlv.IsRouterIdSet(routerId))
{
ExitNow(rval = false);
ExitNow(isComparable = false);
}
// get the peer's two-way link quality to this router
peerLinkQuality = Min(aRouteTlv.GetLinkQualityIn(routerCount), aRouteTlv.GetLinkQualityOut(routerCount));
peerLinkQuality = Min(aRouteTlv.GetLinkQualityIn(index), aRouteTlv.GetLinkQualityOut(index));
// compare local link quality to this router with peer's
if (peerLinkQuality >= localLinkQuality)
if (peerLinkQuality < localLinkQuality)
{
routerCount++;
continue;
ExitNow(isComparable = false);
}
ExitNow(rval = false);
}
exit:
return rval;
return isComparable;
}
void MleRouter::SetChildStateToValid(Child &aChild)
+1 -1
View File
@@ -642,7 +642,7 @@ private:
bool HasChildren(void);
void RemoveChildren(void);
bool HasMinDowngradeNeighborRouters(void);
bool HasOneNeighborWithComparableConnectivity(const RouteTlv &aRouteTlv, uint8_t aRouterId);
bool NeighborHasComparableConnectivity(const RouteTlv &aRouteTlv, uint8_t aNeighborId) const;
bool HasSmallNumberOfChildren(void);
static void HandleAdvertiseTrickleTimer(TrickleTimer &aTimer);