[border-router] call RxRaTracker message handlers from InfraIf (#12055)

This change modifies the handling of incoming ICMPv6 ND messages on the
infrastructure interface. `InfraIf::HandledReceived()` now inspects the
message type and calls the appropriate handler directly.

- Router Advertisement (RA) and Neighbor Advertisement (NA) messages are
  now passed directly to `RxRaTracker::HandleRouterAdvertisement()` and
  `RxRaTracker::HandleNeighborAdvertisement()` respectively.

- The generic `RoutingManager::HandleReceived()` method is removed.
  `RoutingManager` now only handles Router Solicit (RS) messages via
  `RoutingManager::HandleRouterSolicit()`.

This simplifies code and gives `RxRaTracker` direct ownership of RA
and NA processing, which aligns better with its role of tracking
information from received RAs and allowing it to run independently of
the `RoutingManager`.
This commit is contained in:
Abtin Keshavarzian
2025-10-28 08:47:45 -07:00
committed by GitHub
parent f52cf29454
commit a495e4a395
5 changed files with 108 additions and 140 deletions
+18 -2
View File
@@ -107,14 +107,30 @@ Error InfraIf::Send(const Icmp6Packet &aPacket, const Ip6::Address &aDestination
void InfraIf::HandledReceived(uint32_t aIfIndex, const Ip6::Address &aSource, const Icmp6Packet &aPacket)
{
Error error = kErrorNone;
Error error = kErrorNone;
const Ip6::Icmp::Header *icmp6Header;
VerifyOrExit(mInitialized && mIsRunning, error = kErrorInvalidState);
VerifyOrExit(aIfIndex == mIfIndex, error = kErrorDrop);
VerifyOrExit(aPacket.GetBytes() != nullptr, error = kErrorInvalidArgs);
VerifyOrExit(aPacket.GetLength() >= sizeof(Ip6::Icmp::Header), error = kErrorParse);
Get<RoutingManager>().HandleReceived(aPacket, aSource);
icmp6Header = reinterpret_cast<const Ip6::Icmp::Header *>(aPacket.GetBytes());
switch (icmp6Header->GetType())
{
case Ip6::Icmp::Header::kTypeRouterAdvert:
Get<RxRaTracker>().HandleRouterAdvertisement(aPacket, aSource);
break;
case Ip6::Icmp::Header::kTypeNeighborAdvert:
Get<RxRaTracker>().HandleNeighborAdvertisement(aPacket);
break;
case Ip6::Icmp::Header::kTypeRouterSolicit:
Get<RoutingManager>().HandleRouterSolicit(aPacket, aSource);
break;
default:
break;
}
exit:
if (error != kErrorNone)
+2 -88
View File
@@ -348,33 +348,6 @@ exit:
}
#endif
void RoutingManager::HandleReceived(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress)
{
const Ip6::Icmp::Header *icmp6Header;
VerifyOrExit(mIsRunning);
icmp6Header = reinterpret_cast<const Ip6::Icmp::Header *>(aPacket.GetBytes());
switch (icmp6Header->GetType())
{
case Ip6::Icmp::Header::kTypeRouterAdvert:
HandleRouterAdvertisement(aPacket, aSrcAddress);
break;
case Ip6::Icmp::Header::kTypeRouterSolicit:
HandleRouterSolicit(aPacket, aSrcAddress);
break;
case Ip6::Icmp::Header::kTypeNeighborAdvert:
HandleNeighborAdvertisement(aPacket);
break;
default:
break;
}
exit:
return;
}
void RoutingManager::HandleNotifierEvents(Events aEvents)
{
if (aEvents.Contains(kEventThreadRoleChanged))
@@ -608,48 +581,12 @@ void RoutingManager::HandleRouterSolicit(const InfraIf::Icmp6Packet &aPacket, co
OT_UNUSED_VARIABLE(aPacket);
OT_UNUSED_VARIABLE(aSrcAddress);
VerifyOrExit(mIsRunning);
Get<Ip6::Ip6>().GetBorderRoutingCounters().mRsRx++;
LogInfo("Received RS from %s on %s", aSrcAddress.ToString().AsCString(), Get<InfraIf>().ToString().AsCString());
ScheduleRoutingPolicyEvaluation(kToReplyToRs);
}
void RoutingManager::HandleNeighborAdvertisement(const InfraIf::Icmp6Packet &aPacket)
{
const NeighborAdvertMessage *naMsg;
VerifyOrExit(aPacket.GetLength() >= sizeof(NeighborAdvertMessage));
naMsg = reinterpret_cast<const NeighborAdvertMessage *>(aPacket.GetBytes());
Get<RxRaTracker>().ProcessNeighborAdvertMessage(*naMsg);
exit:
return;
}
void RoutingManager::HandleRouterAdvertisement(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress)
{
RouterAdvert::RxMessage raMsg(aPacket);
RxRaTracker::RouterAdvOrigin raOrigin = RxRaTracker::kAnotherRouter;
OT_ASSERT(mIsRunning);
VerifyOrExit(raMsg.IsValid());
Get<Ip6::Ip6>().GetBorderRoutingCounters().mRaRx++;
if (Get<InfraIf>().HasAddress(aSrcAddress))
{
raOrigin =
mTxRaInfo.IsRaFromManager(raMsg) ? RxRaTracker::kThisBrRoutingManager : RxRaTracker::kThisBrOtherEntity;
}
LogInfo("Received RA from %s on %s %s", aSrcAddress.ToString().AsCString(), Get<InfraIf>().ToString().AsCString(),
RouterAdvOriginToString(raOrigin));
DumpDebg("[BR-CERT] direction=recv | type=RA |", aPacket.GetBytes(), aPacket.GetLength());
Get<RxRaTracker>().ProcessRouterAdvertMessage(raMsg, aSrcAddress, raOrigin);
exit:
return;
@@ -767,29 +704,6 @@ exit:
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_REACHABILITY_CHECK_ICMP6_ERROR_ENABLE
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
const char *RoutingManager::RouterAdvOriginToString(RxRaTracker::RouterAdvOrigin aRaOrigin)
{
static const char *const kOriginStrings[] = {
"", // (0) kAnotherRouter
"(this BR routing-manager)", // (1) kThisBrRoutingManager
"(this BR other sw entity)", // (2) kThisBrOtherEntity
};
struct EnumCheck
{
InitEnumValidatorCounter();
ValidateNextEnum(RxRaTracker::kAnotherRouter);
ValidateNextEnum(RxRaTracker::kThisBrRoutingManager);
ValidateNextEnum(RxRaTracker::kThisBrOtherEntity);
};
return kOriginStrings[aRaOrigin];
}
#endif // OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
//---------------------------------------------------------------------------------------------------------------------
// OmrPrefixManager
+15 -7
View File
@@ -422,14 +422,27 @@ public:
#endif // OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
/**
* Processes a received ICMPv6 message from the infrastructure interface.
* Indicates whether or not a received Router Advertisement message is generated by the `RoutingManager` itself.
*
* @param[in] aRaMessage The RA message to check.
*
* @retval TRUE The @p aRaMessage is generated by the `RoutingManager`.
* @retval FALSE The @p aRaMessage is not generated by the `RoutingManager`.
*/
bool IsRouterAdvertFromManager(const RouterAdvert::RxMessage &aRaMessage) const
{
return mTxRaInfo.IsRaFromManager(aRaMessage);
}
/**
* Processes a received Router Solicit message from the infrastructure interface.
*
* Malformed or undesired messages are dropped silently.
*
* @param[in] aPacket The received ICMPv6 packet.
* @param[in] aSrcAddress The source address this message is sent from.
*/
void HandleReceived(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress);
void HandleRouterSolicit(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress);
/**
* Handles infrastructure interface state changes.
@@ -1011,9 +1024,6 @@ private:
void ScheduleRoutingPolicyEvaluation(ScheduleMode aMode);
void SendRouterAdvertisement(RouterAdvTxMode aRaTxMode);
void HandleRouterAdvertisement(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress);
void HandleRouterSolicit(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress);
void HandleNeighborAdvertisement(const InfraIf::Icmp6Packet &aPacket);
bool NetworkDataContainsUlaRoute(void) const;
void HandleRxRaTrackerDecisionFactorChanged(void);
@@ -1021,8 +1031,6 @@ private:
static bool IsValidBrUlaPrefix(const Ip6::Prefix &aBrUlaPrefix);
static const char *RouterAdvOriginToString(RxRaTracker::RouterAdvOrigin aRaOrigin);
//------------------------------------------------------------------------------------------------------------------
// Variables
+59 -14
View File
@@ -137,15 +137,31 @@ void RxRaTracker::HandleRsSenderFinished(TimeMilli aStartTime)
Get<RoutingManager>().ScheduleRoutingPolicyEvaluation(RoutingManager::kImmediately);
}
void RxRaTracker::ProcessRouterAdvertMessage(const RouterAdvert::RxMessage &aRaMessage,
const Ip6::Address &aSrcAddress,
RouterAdvOrigin aRaOrigin)
void RxRaTracker::HandleRouterAdvertisement(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress)
{
// Process a received RA message and update the prefix table.
RouterAdvert::RxMessage raMsg(aPacket);
RouterAdvOrigin origin = kAnotherRouter;
Router *router;
Router *router;
VerifyOrExit(mIsRunning);
switch (aRaOrigin)
VerifyOrExit(raMsg.IsValid());
Get<Ip6::Ip6>().GetBorderRoutingCounters().mRaRx++;
if (Get<InfraIf>().HasAddress(aSrcAddress))
{
origin = Get<RoutingManager>().IsRouterAdvertFromManager(raMsg) ? kThisBrRoutingManager : kThisBrOtherEntity;
}
LogInfo("Received RA from %s on %s %s", aSrcAddress.ToString().AsCString(), Get<InfraIf>().ToString().AsCString(),
RouterAdvOriginToString(origin));
DumpDebg("[BR-CERT] direction=recv | type=RA |", aPacket.GetBytes(), aPacket.GetLength());
// Process the received RA message.
switch (origin)
{
case kThisBrOtherEntity:
case kThisBrRoutingManager:
@@ -155,7 +171,7 @@ void RxRaTracker::ProcessRouterAdvertMessage(const RouterAdvert::RxMessage &aRaM
break;
}
VerifyOrExit(aRaOrigin != kThisBrRoutingManager);
VerifyOrExit(origin != kThisBrRoutingManager);
router = mRouters.FindMatching(aSrcAddress);
@@ -183,9 +199,9 @@ void RxRaTracker::ProcessRouterAdvertMessage(const RouterAdvert::RxMessage &aRaM
// in a `::/0` RIO override the preference and lifetime values in
// the RA header (per RFC 4191 section 3.1).
ProcessRaHeader(aRaMessage.GetHeader(), *router, aRaOrigin);
ProcessRaHeader(raMsg.GetHeader(), *router, origin);
for (const Option &option : aRaMessage)
for (const Option &option : raMsg)
{
switch (option.GetType())
{
@@ -206,7 +222,7 @@ void RxRaTracker::ProcessRouterAdvertMessage(const RouterAdvert::RxMessage &aRaM
}
}
router->mIsLocalDevice = (aRaOrigin == kThisBrOtherEntity);
router->mIsLocalDevice = (origin == kThisBrOtherEntity);
router->ResetReachabilityState();
@@ -880,13 +896,19 @@ void RxRaTracker::HandleSignalTask(void) { Get<RoutingManager>().HandleRxRaTrack
void RxRaTracker::HandleRdnssAddrTask(void) { mRdnssCallback.InvokeIfSet(); }
void RxRaTracker::ProcessNeighborAdvertMessage(const NeighborAdvertMessage &aNaMessage)
void RxRaTracker::HandleNeighborAdvertisement(const InfraIf::Icmp6Packet &aPacket)
{
Router *router;
const NeighborAdvertMessage *naMsg;
Router *router;
VerifyOrExit(aNaMessage.IsValid());
VerifyOrExit(mIsRunning);
router = mRouters.FindMatching(aNaMessage.GetTargetAddress());
VerifyOrExit(aPacket.GetLength() >= sizeof(NeighborAdvertMessage));
naMsg = reinterpret_cast<const NeighborAdvertMessage *>(aPacket.GetBytes());
VerifyOrExit(naMsg->IsValid());
router = mRouters.FindMatching(naMsg->GetTargetAddress());
VerifyOrExit(router != nullptr);
LogInfo("Received NA from router %s", router->mAddress.ToString().AsCString());
@@ -1184,6 +1206,29 @@ exit:
#endif // OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
const char *RxRaTracker::RouterAdvOriginToString(RouterAdvOrigin aRaOrigin)
{
static const char *const kOriginStrings[] = {
"", // (0) kAnotherRouter
"(this BR routing-manager)", // (1) kThisBrRoutingManager
"(this BR other sw entity)", // (2) kThisBrOtherEntity
};
struct EnumCheck
{
InitEnumValidatorCounter();
ValidateNextEnum(kAnotherRouter);
ValidateNextEnum(kThisBrRoutingManager);
ValidateNextEnum(kThisBrOtherEntity);
};
return kOriginStrings[aRaOrigin];
}
#endif // OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
//---------------------------------------------------------------------------------------------------------------------
// RxRaTracker::Iterator
+14 -29
View File
@@ -77,16 +77,6 @@ class RxRaTracker : public InstanceLocator
friend class InfraIf;
public:
/**
* Represents the origin of a received Router Advertisement message.
*/
enum RouterAdvOrigin : uint8_t
{
kAnotherRouter, ///< From another router on the infrastructure interface.
kThisBrRoutingManager, ///< From this Border Router, generated by `RoutingManager` itself.
kThisBrOtherEntity, ///< From this Border Router, generated by another software entity.
};
/**
* Represents an entity requesting to enable/disable the `RxRaTracker`.
*/
@@ -128,24 +118,6 @@ public:
*/
bool IsRsTxInProgress(void) const { return mRsSender.IsInProgress(); }
/**
* Processes a received Router Advertisement (RA) message.
*
* @param[in] aRaMessage The received RA message.
* @param[in] aSrcAddress The source address of the RA message.
* @param[in] aRaOrigin The origin of the RA message.
*/
void ProcessRouterAdvertMessage(const RouterAdvert::RxMessage &aRaMessage,
const Ip6::Address &aSrcAddress,
RouterAdvOrigin aRaOrigin);
/**
* Processes a received Neighbor Advertisement (NA) message.
*
* @param[in] aNaMessage The received NA message.
*/
void ProcessNeighborAdvertMessage(const NeighborAdvertMessage &aNaMessage);
/**
* Initializes a `PrefixTableIterator`.
*
@@ -312,6 +284,15 @@ private:
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
enum RouterAdvOrigin : uint8_t
{
kAnotherRouter, // From another router on the infrastructure interface.
kThisBrRoutingManager, // From this Border Router, generated by `RoutingManager` itself.
kThisBrOtherEntity, // From this Border Router, generated by another software entity.
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template <class Type>
struct Entry : public Type,
public LinkedListEntry<Entry<Type>>,
@@ -566,8 +547,10 @@ private:
void HandleNotifierEvents(Events aEvents);
void HandleNetDataChange(void);
// Callback from `InfraIf`
// Callbacks from `InfraIf`
void HandleInfraIfStateChanged(void) { UpdateState(); }
void HandleRouterAdvertisement(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress);
void HandleNeighborAdvertisement(const InfraIf::Icmp6Packet &aPacket);
// Tasklet or timer callbacks
void HandleSignalTask(void);
@@ -583,6 +566,8 @@ private:
template <class Type> Entry<Type> *AllocateEntry(void);
#endif
static const char *RouterAdvOriginToString(RouterAdvOrigin aRaOrigin);
using SignalTask = TaskletIn<RxRaTracker, &RxRaTracker::HandleSignalTask>;
using RdnssAddrTask = TaskletIn<RxRaTracker, &RxRaTracker::HandleRdnssAddrTask>;
using ExpirationTimer = TimerMilliIn<RxRaTracker, &RxRaTracker::HandleExpirationTimer>;