mirror of
https://github.com/espressif/openthread.git
synced 2026-08-16 15:47:46 +00:00
[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:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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>;
|
||||
|
||||
Reference in New Issue
Block a user