[routing-manager] skip self-prepared RA when learning host RA header (#7846)

This commit updates how `RoutingManager` learns the RA header from
host daemons. It adds a new method to determine whether a received RA
message is prepared by the `RoutingManager` itself by checking the
options (PIO and RIO) from the RA message. When learning/updating the
host RA header, we check and skip over such self-prepared RA
messages.
This commit is contained in:
Abtin Keshavarzian
2022-06-30 12:18:31 -07:00
committed by GitHub
parent 0132362815
commit f2f98c565f
2 changed files with 74 additions and 0 deletions
@@ -913,6 +913,68 @@ void RoutingManager::SendRouterAdvertisement(const OmrPrefixArray &aNewOmrPrefix
}
}
bool RoutingManager::IsReceivdRouterAdvertFromManager(const Ip6::Nd::RouterAdvertMessage &aRaMessage) const
{
// Determines whether or not a received RA message was prepared by
// by `RoutingManager` itself.
bool isFromManager = false;
uint16_t rioCount = 0;
Ip6::Prefix prefix;
VerifyOrExit(aRaMessage.ContainsAnyOptions());
for (const Ip6::Nd::Option &option : aRaMessage)
{
switch (option.GetType())
{
case Ip6::Nd::Option::kTypePrefixInfo:
{
// PIO should match `mLocalOnLinkPrefix`.
const Ip6::Nd::PrefixInfoOption &pio = static_cast<const Ip6::Nd::PrefixInfoOption &>(option);
VerifyOrExit(pio.IsValid());
pio.GetPrefix(prefix);
VerifyOrExit(prefix == mLocalOnLinkPrefix);
break;
}
case Ip6::Nd::Option::kTypeRouteInfo:
{
// RIO (with non-zero lifetime) should match entries from
// `mAdvertisedOmrPrefixes`. We keep track of the number
// of matched RIOs and check after the loop ends that all
// entries were seen.
const Ip6::Nd::RouteInfoOption &rio = static_cast<const Ip6::Nd::RouteInfoOption &>(option);
VerifyOrExit(rio.IsValid());
rio.GetPrefix(prefix);
if (rio.GetRouteLifetime() != 0)
{
VerifyOrExit(mAdvertisedOmrPrefixes.ContainsMatching(prefix));
rioCount++;
}
break;
}
default:
ExitNow();
}
}
VerifyOrExit(rioCount == mAdvertisedOmrPrefixes.GetLength());
isFromManager = true;
exit:
return isFromManager;
}
bool RoutingManager::IsValidBrUlaPrefix(const Ip6::Prefix &aBrUlaPrefix)
{
return aBrUlaPrefix.mLength == kBrUlaPrefixLength && aBrUlaPrefix.mPrefix.mFields.m8[0] == 0xfd;
@@ -1174,6 +1236,14 @@ void RoutingManager::UpdateRouterAdvertHeader(const Ip6::Nd::RouterAdvertMessage
Ip6::Nd::RouterAdvertMessage::Header oldHeader;
if (aRouterAdvertMessage != nullptr)
{
// We skip and do not update RA header if the received RA message
// was not prepared and sent by `RoutingManager` itself.
VerifyOrExit(!IsReceivdRouterAdvertFromManager(*aRouterAdvertMessage));
}
oldHeader = mRouterAdvertHeader;
mTimeRouterAdvMessageLastUpdate = TimerMilli::GetNow();
@@ -1203,6 +1273,9 @@ void RoutingManager::UpdateRouterAdvertHeader(const Ip6::Nd::RouterAdvertMessage
StartRoutingPolicyEvaluationJitter(kRoutingPolicyEvaluationJitter);
}
exit:
return;
}
void RoutingManager::ResetDiscoveredPrefixStaleTimer(void)
@@ -478,6 +478,7 @@ private:
void HandleDiscoveredPrefixTableChanged(void);
bool NetworkDataContainsOmrPrefix(const Ip6::Prefix &aPrefix) const;
void UpdateRouterAdvertHeader(const Ip6::Nd::RouterAdvertMessage *aRouterAdvertMessage);
bool IsReceivdRouterAdvertFromManager(const Ip6::Nd::RouterAdvertMessage &aRaMessage) const;
void ResetDiscoveredPrefixStaleTimer(void);
static bool IsValidBrUlaPrefix(const Ip6::Prefix &aBrUlaPrefix);