mirror of
https://github.com/espressif/openthread.git
synced 2026-08-11 13:17:48 +00:00
[routing-manager] track origin of received RA messages (#10229)
This commit adds `RouterAdvOrigin` enumeration to track the origin of a received RA message, whether it is from another router on the infrastructure, or self-generated by either the `RoutingManager` module or another software entity running on the device. This is used to exclude prefixes from self-generated `RoutingManager` RAs in the prefix table and simplifies learning and adopting of RA headers from other software entities on the same device. The origin is now logged when a new RA is received for improved debugging. This commit also updates `test_routing_manager` to pass back any sent RA messages to the OT stack. This validates the mechanism for identifying self-generated RA messages.
This commit is contained in:
@@ -699,7 +699,7 @@ void RoutingManager::HandleRsSenderFinished(TimeMilli aStartTime)
|
||||
|
||||
if (mRaInfo.mHeaderUpdateTime <= aStartTime)
|
||||
{
|
||||
UpdateRouterAdvertHeader(/* aRouterAdvertMessage */ nullptr);
|
||||
UpdateRouterAdvertHeader(/* aRouterAdvertMessage */ nullptr, kThisBrOtherEntity);
|
||||
}
|
||||
|
||||
ScheduleRoutingPolicyEvaluation(kImmediately);
|
||||
@@ -737,26 +737,29 @@ exit:
|
||||
|
||||
void RoutingManager::HandleRouterAdvertisement(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress)
|
||||
{
|
||||
RouterAdvert::RxMessage routerAdvMessage(aPacket);
|
||||
RouterAdvert::RxMessage raMsg(aPacket);
|
||||
RouterAdvOrigin raOrigin = kAnotherRouter;
|
||||
|
||||
OT_ASSERT(mIsRunning);
|
||||
|
||||
VerifyOrExit(routerAdvMessage.IsValid());
|
||||
VerifyOrExit(raMsg.IsValid());
|
||||
|
||||
Get<Ip6::Ip6>().GetBorderRoutingCounters().mRaRx++;
|
||||
|
||||
LogInfo("Received RA from %s on %s", aSrcAddress.ToString().AsCString(), mInfraIf.ToString().AsCString());
|
||||
DumpDebg("[BR-CERT] direction=recv | type=RA |", aPacket.GetBytes(), aPacket.GetLength());
|
||||
|
||||
mDiscoveredPrefixTable.ProcessRouterAdvertMessage(routerAdvMessage, aSrcAddress);
|
||||
|
||||
// Remember the header and parameters of RA messages which are
|
||||
// initiated from the infra interface.
|
||||
if (mInfraIf.HasAddress(aSrcAddress))
|
||||
{
|
||||
UpdateRouterAdvertHeader(&routerAdvMessage);
|
||||
raOrigin = mRaInfo.IsRaFromManager(raMsg) ? kThisBrRoutingManager : kThisBrOtherEntity;
|
||||
}
|
||||
|
||||
LogInfo("Received RA from %s on %s %s", aSrcAddress.ToString().AsCString(), mInfraIf.ToString().AsCString(),
|
||||
RouterAdvOriginToString(raOrigin));
|
||||
|
||||
DumpDebg("[BR-CERT] direction=recv | type=RA |", aPacket.GetBytes(), aPacket.GetLength());
|
||||
|
||||
mDiscoveredPrefixTable.ProcessRouterAdvertMessage(raMsg, aSrcAddress, raOrigin);
|
||||
|
||||
UpdateRouterAdvertHeader(&raMsg, raOrigin);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
@@ -885,24 +888,18 @@ bool RoutingManager::NetworkDataContainsUlaRoute(void) const
|
||||
return contains;
|
||||
}
|
||||
|
||||
void RoutingManager::UpdateRouterAdvertHeader(const RouterAdvert::RxMessage *aRouterAdvertMessage)
|
||||
void RoutingManager::UpdateRouterAdvertHeader(const RouterAdvert::RxMessage *aRaMsg, RouterAdvOrigin aRaOrigin)
|
||||
{
|
||||
// Updates the `mRaInfo` from the given RA message.
|
||||
|
||||
RouterAdvert::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(!mRaInfo.IsRaFromManager(*aRouterAdvertMessage));
|
||||
}
|
||||
VerifyOrExit(aRaOrigin == kThisBrOtherEntity);
|
||||
|
||||
oldHeader = mRaInfo.mHeader;
|
||||
mRaInfo.mHeaderUpdateTime = TimerMilli::GetNow();
|
||||
|
||||
if (aRouterAdvertMessage == nullptr || aRouterAdvertMessage->GetHeader().GetRouterLifetime() == 0)
|
||||
if (aRaMsg == nullptr || aRaMsg->GetHeader().GetRouterLifetime() == 0)
|
||||
{
|
||||
mRaInfo.mHeader.SetToDefault();
|
||||
mRaInfo.mIsHeaderFromHost = false;
|
||||
@@ -913,7 +910,7 @@ void RoutingManager::UpdateRouterAdvertHeader(const RouterAdvert::RxMessage *aRo
|
||||
// which indicates to platform that it needs to do the
|
||||
// calculation and update it.
|
||||
|
||||
mRaInfo.mHeader = aRouterAdvertMessage->GetHeader();
|
||||
mRaInfo.mHeader = aRaMsg->GetHeader();
|
||||
mRaInfo.mHeader.SetChecksum(0);
|
||||
mRaInfo.mIsHeaderFromHost = true;
|
||||
}
|
||||
@@ -970,6 +967,7 @@ void RoutingManager::ResetDiscoveredPrefixStaleTimer(void)
|
||||
}
|
||||
|
||||
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
|
||||
|
||||
void RoutingManager::LogPrefixInfoOption(const Ip6::Prefix &aPrefix,
|
||||
uint32_t aValidLifetime,
|
||||
uint32_t aPreferredLifetime)
|
||||
@@ -983,10 +981,28 @@ void RoutingManager::LogRouteInfoOption(const Ip6::Prefix &aPrefix, uint32_t aLi
|
||||
LogInfo("- RIO %s (lifetime:%lu, prf:%s)", aPrefix.ToString().AsCString(), ToUlong(aLifetime),
|
||||
RoutePreferenceToString(aPreference));
|
||||
}
|
||||
|
||||
const char *RoutingManager::RouterAdvOriginToString(RouterAdvOrigin aRaOrigin)
|
||||
{
|
||||
static const char *const kOriginStrings[] = {
|
||||
"", // (0) kAnotherRouter
|
||||
"(this BR routing-manager)", // (1) kThisBrRoutingManager
|
||||
"(this BR other sw entity)", // (2) kThisBrOtherEntity
|
||||
};
|
||||
|
||||
static_assert(0 == kAnotherRouter, "kAnotherRouter value is incorrect");
|
||||
static_assert(1 == kThisBrRoutingManager, "kThisBrRoutingManager value is incorrect");
|
||||
static_assert(2 == kThisBrOtherEntity, "kThisBrOtherEntity value is incorrect");
|
||||
|
||||
return kOriginStrings[aRaOrigin];
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void RoutingManager::LogPrefixInfoOption(const Ip6::Prefix &, uint32_t, uint32_t) {}
|
||||
void RoutingManager::LogRouteInfoOption(const Ip6::Prefix &, uint32_t, RoutePreference) {}
|
||||
#endif
|
||||
|
||||
#endif // OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// LifetimedPrefix
|
||||
@@ -1118,11 +1134,16 @@ RoutingManager::DiscoveredPrefixTable::DiscoveredPrefixTable(Instance &aInstance
|
||||
}
|
||||
|
||||
void RoutingManager::DiscoveredPrefixTable::ProcessRouterAdvertMessage(const RouterAdvert::RxMessage &aRaMessage,
|
||||
const Ip6::Address &aSrcAddress)
|
||||
const Ip6::Address &aSrcAddress,
|
||||
RouterAdvOrigin aRaOrigin)
|
||||
{
|
||||
// Process a received RA message and update the prefix table.
|
||||
|
||||
Router *router = mRouters.FindMatching(aSrcAddress);
|
||||
Router *router;
|
||||
|
||||
VerifyOrExit(aRaOrigin != kThisBrRoutingManager);
|
||||
|
||||
router = mRouters.FindMatching(aSrcAddress);
|
||||
|
||||
if (router == nullptr)
|
||||
{
|
||||
|
||||
@@ -629,6 +629,13 @@ private:
|
||||
kAdvPrefixesFromNetData,
|
||||
};
|
||||
|
||||
enum RouterAdvOrigin : uint8_t // Origin of a received Router Advert message.
|
||||
{
|
||||
kAnotherRouter, // From another router on infra-if.
|
||||
kThisBrRoutingManager, // From this BR generated by `RoutingManager` itself.
|
||||
kThisBrOtherEntity, // From this BR generated by another sw entity.
|
||||
};
|
||||
|
||||
enum ScheduleMode : uint8_t // Used in `ScheduleRoutingPolicyEvaluation()`
|
||||
{
|
||||
kImmediately,
|
||||
@@ -738,7 +745,9 @@ private:
|
||||
public:
|
||||
explicit DiscoveredPrefixTable(Instance &aInstance);
|
||||
|
||||
void ProcessRouterAdvertMessage(const RouterAdvert::RxMessage &aRaMessage, const Ip6::Address &aSrcAddress);
|
||||
void ProcessRouterAdvertMessage(const RouterAdvert::RxMessage &aRaMessage,
|
||||
const Ip6::Address &aSrcAddress,
|
||||
RouterAdvOrigin aRaOrigin);
|
||||
void ProcessNeighborAdvertMessage(const NeighborAdvertMessage &aNaMessage);
|
||||
|
||||
bool ContainsDefaultOrNonUlaRoutePrefix(void) const;
|
||||
@@ -1392,7 +1401,7 @@ private:
|
||||
void UpdateDiscoveredPrefixTableOnNetDataChange(void);
|
||||
bool NetworkDataContainsOmrPrefix(const Ip6::Prefix &aPrefix) const;
|
||||
bool NetworkDataContainsUlaRoute(void) const;
|
||||
void UpdateRouterAdvertHeader(const RouterAdvert::RxMessage *aRouterAdvertMessage);
|
||||
void UpdateRouterAdvertHeader(const RouterAdvert::RxMessage *aRaMsg, RouterAdvOrigin aRaOrigin);
|
||||
void ResetDiscoveredPrefixStaleTimer(void);
|
||||
|
||||
static bool IsValidBrUlaPrefix(const Ip6::Prefix &aBrUlaPrefix);
|
||||
@@ -1402,6 +1411,8 @@ private:
|
||||
static void LogPrefixInfoOption(const Ip6::Prefix &aPrefix, uint32_t aValidLifetime, uint32_t aPreferredLifetime);
|
||||
static void LogRouteInfoOption(const Ip6::Prefix &aPrefix, uint32_t aLifetime, RoutePreference aPreference);
|
||||
|
||||
static const char *RouterAdvOriginToString(RouterAdvOrigin aRaOrigin);
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Variables
|
||||
|
||||
|
||||
@@ -317,6 +317,7 @@ otError otPlatInfraIfSendIcmp6Nd(uint32_t aInfraIfIndex,
|
||||
Log(" Router Advertisement message");
|
||||
LogRouterAdvert(packet);
|
||||
ValidateRouterAdvert(packet);
|
||||
otPlatInfraIfRecvIcmp6Nd(sInstance, kInfraIfIndex, &sInfraIfAddress, aBuffer, aBufferLength);
|
||||
break;
|
||||
|
||||
case Ip6::Icmp::Header::kTypeNeighborSolicit:
|
||||
|
||||
Reference in New Issue
Block a user