[routing-manager] enhance and streamline PdPrefixManager (#10146)

This commit updates the `PdPrefixManager` class for improved
readability and efficiency:

- Relocated all Prefix PD methods in the header file for logical
  grouping within the same `#if` block.
- Reordered method definitions for better organization (e.g., moved
  `SetEnabled()` closer to the constructor, and logging-related
  methods to the end).
- Renamed variables and types for conciseness (e.g., `Dhcp6PdState` to
  `State`).
- Simplified prefix processing logic, regardless of whether it's from
  RA or directly set.
- Moved additional functions into `PdPrefixManager::Process()`,
  including checking `mEnabled`, logging failures, and updating
  counters.
- Optimized `Process()` to update the timer only when the prefix
  changes.
- Introduced a new nested `PrefixEntry` class with helper methods like
  `IsFavoredOver()` and `IsEmpty()`, simplifying the code and
  improving readability.
- The `IsFavoredOver()` method determines if one PD prefix is favored
  over another.
This commit is contained in:
Abtin Keshavarzian
2024-05-07 12:24:37 -07:00
committed by GitHub
parent 42ccf281fb
commit 6f0b7631e9
2 changed files with 195 additions and 197 deletions
+118 -94
View File
@@ -3537,21 +3537,6 @@ exit:
#if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
const char *RoutingManager::PdPrefixManager::StateToString(Dhcp6PdState aState)
{
static const char *const kStateStrings[] = {
"Disabled", // (0) kDisabled
"Stopped", // (1) kStopped
"Running", // (2) kRunning
};
static_assert(0 == kDhcp6PdStateDisabled, "kDhcp6PdStateDisabled value is incorrect");
static_assert(1 == kDhcp6PdStateStopped, "kDhcp6PdStateStopped value is incorrect");
static_assert(2 == kDhcp6PdStateRunning, "kDhcp6PdStateRunning value is incorrect");
return kStateStrings[aState];
}
RoutingManager::PdPrefixManager::PdPrefixManager(Instance &aInstance)
: InstanceLocator(aInstance)
, mEnabled(false)
@@ -3561,12 +3546,23 @@ RoutingManager::PdPrefixManager::PdPrefixManager(Instance &aInstance)
, mLastPlatformRaTime(0)
, mTimer(aInstance)
{
mPrefix.Clear();
}
void RoutingManager::PdPrefixManager::SetEnabled(bool aEnabled)
{
State oldState = GetState();
VerifyOrExit(mEnabled != aEnabled);
mEnabled = aEnabled;
EvaluateStateChange(oldState);
exit:
return;
}
void RoutingManager::PdPrefixManager::StartStop(bool aStart)
{
Dhcp6PdState oldState = GetState();
State oldState = GetState();
VerifyOrExit(aStart != mIsRunning);
mIsRunning = aStart;
@@ -3576,9 +3572,9 @@ exit:
return;
}
RoutingManager::Dhcp6PdState RoutingManager::PdPrefixManager::GetState(void) const
RoutingManager::PdPrefixManager::State RoutingManager::PdPrefixManager::GetState(void) const
{
Dhcp6PdState state = kDhcp6PdStateDisabled;
State state = kDhcp6PdStateDisabled;
if (mEnabled)
{
@@ -3590,7 +3586,7 @@ RoutingManager::Dhcp6PdState RoutingManager::PdPrefixManager::GetState(void) con
void RoutingManager::PdPrefixManager::EvaluateStateChange(Dhcp6PdState aOldState)
{
Dhcp6PdState newState = GetState();
State newState = GetState();
VerifyOrExit(aOldState != newState);
LogInfo("PdPrefixManager: %s -> %s", StateToString(aOldState), StateToString(newState));
@@ -3605,7 +3601,7 @@ void RoutingManager::PdPrefixManager::EvaluateStateChange(Dhcp6PdState aOldState
break;
}
mExternalCallback.InvokeIfSet(static_cast<otBorderRoutingDhcp6PdState>(newState));
mStateCallback.InvokeIfSet(static_cast<otBorderRoutingDhcp6PdState>(newState));
exit:
return;
@@ -3644,7 +3640,7 @@ void RoutingManager::PdPrefixManager::WithdrawPrefix(void)
{
VerifyOrExit(HasPrefix());
LogInfo("Withdrew platform provided outdated prefix: %s", mPrefix.GetPrefix().ToString().AsCString());
LogInfo("Withdrew DHCPv6 PD prefix %s", mPrefix.GetPrefix().ToString().AsCString());
mPrefix.Clear();
mTimer.Stop();
@@ -3655,64 +3651,51 @@ exit:
return;
}
void RoutingManager::PdPrefixManager::ProcessPlatformGeneratedRa(const uint8_t *aRouterAdvert, const uint16_t aLength)
void RoutingManager::PdPrefixManager::ProcessRa(const uint8_t *aRouterAdvert, const uint16_t aLength)
{
Error error = kErrorNone;
// Processes a Router Advertisement (RA) message received on the
// platform's Thread interface. This RA message, generated by
// software entities like dnsmasq, radvd, or systemd-networkd, is
// part of the DHCPv6 prefix delegation process for distributing
// prefixes to interfaces.
RouterAdvert::Icmp6Packet packet;
if (mEnabled)
{
packet.Init(aRouterAdvert, aLength);
RouterAdvert::RxMessage aMessage = RouterAdvert::RxMessage(packet);
error = Process(&aMessage, nullptr);
mNumPlatformRaReceived++;
mLastPlatformRaTime = TimerMilli::GetNow();
}
else
{
LogWarn("Ignore platform generated RA since PD is disabled.");
}
if (error != kErrorNone)
{
LogCrit("Failed to process platform generated ND OnMeshPrefix: %s", ErrorToString(error));
}
packet.Init(aRouterAdvert, aLength);
Process(&packet, nullptr);
}
void RoutingManager::PdPrefixManager::ProcessDhcpPdPrefix(const PrefixTableEntry &aPrefixTableEntry)
void RoutingManager::PdPrefixManager::ProcessPrefix(const PrefixTableEntry &aPrefixTableEntry)
{
Error error = kErrorNone;
// Processes a prefix delegated by a DHCPv6 Prefix Delegation
// (PD) server. Similar to `ProcessRa()`, but sets the prefix
// directly instead of parsing an RA message. Calling this method
// again with new values can update the prefix's lifetime.
VerifyOrExit(mEnabled, LogWarn("Ignore DHCPv6 delegated prefix since PD is disabled."));
error = Process(nullptr, &aPrefixTableEntry);
exit:
if (error != kErrorNone)
{
LogCrit("Failed to process DHCPv6 delegated prefix: %s", ErrorToString(error));
}
Process(nullptr, &aPrefixTableEntry);
}
Error RoutingManager::PdPrefixManager::Process(const RouterAdvert::RxMessage *aMessage,
const PrefixTableEntry *aPrefixTableEntry)
void RoutingManager::PdPrefixManager::Process(const RouterAdvert::Icmp6Packet *aRaPacket,
const PrefixTableEntry *aPrefixTableEntry)
{
bool currentPrefixUpdated = false;
Error error = kErrorNone;
DiscoveredPrefixTable::Entry favoredEntry;
DiscoveredPrefixTable::Entry entry;
// Processes DHCPv6 Prefix Delegation (PD) prefixes, either from
// an RA message or directly set. Requires either `aRaPacket` or
// `aPrefixTableEntry` to be non-null.
favoredEntry.Clear();
bool currentPrefixUpdated = false;
Error error = kErrorNone;
PrefixEntry favoredEntry;
PrefixEntry entry;
// Either `aMessage` or `aPrefixTableEntry` must be non-null.
VerifyOrExit(mEnabled, error = kErrorInvalidState);
if (aMessage != nullptr)
if (aRaPacket != nullptr)
{
VerifyOrExit(aMessage->IsValid(), error = kErrorParse);
RouterAdvert::RxMessage raMsg = RouterAdvert::RxMessage(*aRaPacket);
for (const Option &option : *aMessage)
VerifyOrExit(raMsg.IsValid(), error = kErrorParse);
for (const Option &option : raMsg)
{
if (option.GetType() != Option::kTypePrefixInfo || !static_cast<const PrefixInfoOption &>(option).IsValid())
{
@@ -3723,6 +3706,9 @@ Error RoutingManager::PdPrefixManager::Process(const RouterAdvert::RxMessage *aM
entry.SetFrom(static_cast<const PrefixInfoOption &>(option));
currentPrefixUpdated |= ProcessPrefixEntry(entry, favoredEntry);
}
mNumPlatformRaReceived++;
mLastPlatformRaTime = TimerMilli::GetNow();
}
else // aPrefixTableEntry != nullptr
{
@@ -3732,46 +3718,46 @@ Error RoutingManager::PdPrefixManager::Process(const RouterAdvert::RxMessage *aM
if (currentPrefixUpdated && mPrefix.IsDeprecated())
{
LogInfo("PdPrefixManager: Prefix %s is deprecated", mPrefix.GetPrefix().ToString().AsCString());
LogInfo("DHCPv6 PD prefix %s is deprecated", mPrefix.GetPrefix().ToString().AsCString());
mPrefix.Clear();
Get<RoutingManager>().ScheduleRoutingPolicyEvaluation(kImmediately);
}
if (!HasPrefix() || (favoredEntry.GetPrefix().GetLength() != 0 && favoredEntry.GetPrefix() < mPrefix.GetPrefix()))
if (favoredEntry.IsFavoredOver(mPrefix))
{
mPrefix = favoredEntry;
mPrefix = favoredEntry;
currentPrefixUpdated = true;
LogInfo("DHCPv6 PD prefix set to %s", mPrefix.GetPrefix().ToString().AsCString());
Get<RoutingManager>().ScheduleRoutingPolicyEvaluation(kImmediately);
}
exit:
if (HasPrefix())
if (HasPrefix() && currentPrefixUpdated)
{
// If prefix has been set from aPrefixTableEntry use only preferred lifetime to calculate stale time
if (aPrefixTableEntry)
{
mTimer.FireAt(mPrefix.GetStaleTimeFromPreferredLifetime());
}
else
{
mTimer.FireAt(mPrefix.GetStaleTime());
}
// If the prefix is obtained from an RA message, use
// `GetStaleTime()` to apply the minimum `RA_STABLE_TIME`.
// Otherwise, calculate it directly from the prefix's
// preferred lifetime.
mTimer.FireAt((aPrefixTableEntry != nullptr) ? mPrefix.GetStaleTimeFromPreferredLifetime()
: mPrefix.GetStaleTime());
}
else
{
mTimer.Stop();
}
return error;
exit:
LogWarnOnError(error, "process DHCPv6 delegated prefix");
OT_UNUSED_VARIABLE(error);
}
bool RoutingManager::PdPrefixManager::ProcessPrefixEntry(DiscoveredPrefixTable::Entry &aEntry,
DiscoveredPrefixTable::Entry &aFavoredEntry)
bool RoutingManager::PdPrefixManager::ProcessPrefixEntry(PrefixEntry &aEntry, PrefixEntry &aFavoredEntry)
{
bool currentPrefixUpdated = false;
if (!IsValidPdPrefix(aEntry.GetPrefix()))
if (!aEntry.IsValidPdPrefix())
{
LogWarn("PdPrefixManager: Ignore invalid prefix entry %s", aEntry.GetPrefix().ToString().AsCString());
LogWarn("Ignore invalid DHCPv6 PD prefix %s", aEntry.GetPrefix().ToString().AsCString());
ExitNow();
}
@@ -3781,7 +3767,7 @@ bool RoutingManager::PdPrefixManager::ProcessPrefixEntry(DiscoveredPrefixTable::
// Check if there is an update to the current prefix. The valid or
// preferred lifetime may have changed.
if (aEntry.GetPrefix() == GetPrefix())
if (HasPrefix() && (mPrefix.GetPrefix() == aEntry.GetPrefix()))
{
currentPrefixUpdated = true;
mPrefix = aEntry;
@@ -3794,7 +3780,7 @@ bool RoutingManager::PdPrefixManager::ProcessPrefixEntry(DiscoveredPrefixTable::
// smaller than ULA prefixes (`fc00::/7`). This rule prefers GUA
// prefixes over ULA.
if (aFavoredEntry.GetPrefix().GetLength() == 0 || aEntry.GetPrefix() < aFavoredEntry.GetPrefix())
if (aEntry.IsFavoredOver(aFavoredEntry))
{
aFavoredEntry = aEntry;
}
@@ -3803,21 +3789,59 @@ exit:
return currentPrefixUpdated;
}
void RoutingManager::PdPrefixManager::SetEnabled(bool aEnabled)
bool RoutingManager::PdPrefixManager::PrefixEntry::IsValidPdPrefix(void) const
{
Dhcp6PdState oldState = GetState();
// We should accept ULA prefix since it could be used by the internet infrastructure like NAT64.
VerifyOrExit(mEnabled != aEnabled);
mEnabled = aEnabled;
EvaluateStateChange(oldState);
return !IsEmpty() && (GetPrefix().GetLength() <= kOmrPrefixLength) && !GetPrefix().IsLinkLocal() &&
!GetPrefix().IsMulticast();
}
bool RoutingManager::PdPrefixManager::PrefixEntry::IsFavoredOver(const PrefixEntry &aOther) const
{
bool isFavored;
if (IsEmpty())
{
// Empty prefix is not favored over any (including another
// empty prefix).
isFavored = false;
ExitNow();
}
if (aOther.IsEmpty())
{
// A non-empty prefix is favored over an empty one.
isFavored = true;
ExitNow();
}
// Numerically smaller prefix is favored.
isFavored = GetPrefix() < aOther.GetPrefix();
exit:
return;
return isFavored;
}
const char *RoutingManager::PdPrefixManager::StateToString(State aState)
{
static const char *const kStateStrings[] = {
"Disabled", // (0) kDisabled
"Stopped", // (1) kStopped
"Running", // (2) kRunning
};
static_assert(0 == kDhcp6PdStateDisabled, "kDhcp6PdStateDisabled value is incorrect");
static_assert(1 == kDhcp6PdStateStopped, "kDhcp6PdStateStopped value is incorrect");
static_assert(2 == kDhcp6PdStateRunning, "kDhcp6PdStateRunning value is incorrect");
return kStateStrings[aState];
}
extern "C" void otPlatBorderRoutingProcessIcmp6Ra(otInstance *aInstance, const uint8_t *aMessage, uint16_t aLength)
{
AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().ProcessPlatformGeneratedRa(aMessage, aLength);
AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().mPdPrefixManager.ProcessRa(aMessage, aLength);
}
extern "C" void otPlatBorderRoutingProcessDhcp6PdPrefix(otInstance *aInstance,
@@ -3825,7 +3849,7 @@ extern "C" void otPlatBorderRoutingProcessDhcp6PdPrefix(otInstance
{
AssertPointerIsNotNull(aPrefixInfo);
AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().ProcessDhcpPdPrefix(*aPrefixInfo);
AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().mPdPrefixManager.ProcessPrefix(*aPrefixInfo);
}
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
+77 -103
View File
@@ -75,6 +75,10 @@ namespace ot {
namespace BorderRouter {
extern "C" void otPlatBorderRoutingProcessIcmp6Ra(otInstance *aInstance, const uint8_t *aMessage, uint16_t aLength);
extern "C" void otPlatBorderRoutingProcessDhcp6PdPrefix(otInstance *aInstance,
const otBorderRoutingPrefixTableEntry *aPrefixInfo);
/**
* Implements bi-directional routing between Thread and Infrastructure networks.
*
@@ -87,6 +91,12 @@ class RoutingManager : public InstanceLocator
friend class ot::Notifier;
friend class ot::Instance;
#if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
friend void otPlatBorderRoutingProcessIcmp6Ra(otInstance *aInstance, const uint8_t *aMessage, uint16_t aLength);
friend void otPlatBorderRoutingProcessDhcp6PdPrefix(otInstance *aInstance,
const otBorderRoutingPrefixTableEntry *aPrefixInfo);
#endif
public:
typedef NetworkData::RoutePreference RoutePreference; ///< Route preference (high, medium, low).
typedef otBorderRoutingPrefixTableIterator PrefixTableIterator; ///< Prefix Table Iterator.
@@ -300,34 +310,6 @@ public:
*/
Error GetOmrPrefix(Ip6::Prefix &aPrefix) const;
#if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
/**
* Returns the platform provided off-mesh-routable (OMR) prefix.
*
* The prefix is extracted from the platform generated RA messages handled by `ProcessPlatformGeneratedNd()`.
*
* @param[out] aPrefixInfo A reference to where the prefix info will be output to.
*
* @retval kErrorNone Successfully retrieved the OMR prefix.
* @retval kErrorNotFound There are no valid PD prefix on this BR.
* @retval kErrorInvalidState The Border Routing Manager is not initialized yet.
*
*/
Error GetPdOmrPrefix(PrefixTableEntry &aPrefixInfo) const;
/**
* Returns platform generated RA message processed information.
*
* @param[out] aPdProcessedRaInfo A reference to where the PD processed RA info will be output to.
*
* @retval kErrorNone Successfully retrieved the Info.
* @retval kErrorNotFound There are no valid RA process info on this BR.
* @retval kErrorInvalidState The Border Routing Manager is not initialized yet.
*
*/
Error GetPdProcessedRaInfo(PdProcessedRaInfo &aPdProcessedRaInfo);
#endif
/**
* Returns the currently favored off-mesh-routable (OMR) prefix.
*
@@ -528,65 +510,57 @@ public:
#if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
/**
* Handles a router advertisement message received on platform's Thread interface.
* Enables / Disables the DHCPv6 Prefix Delegation.
*
* Note: This method is a part of DHCPv6 PD support on Thread border routers. The message should be generated by the
* software like dnamasq, radvd, systemd-networkd on the platform as a part of the DHCPv6 prefix delegation process
* for distributing the prefix to the interfaces (links).
*
* @param[in] aRouterAdvert A pointer to the buffer of the router advertisement message.
* @param[in] aLength The length of the router advertisement message.
*
*/
void ProcessPlatformGeneratedRa(const uint8_t *aRouterAdvert, uint16_t aLength)
{
mPdPrefixManager.ProcessPlatformGeneratedRa(aRouterAdvert, aLength);
}
/**
* Handles a prefix delegated from a DHCPv6 PD server. The prefix is received on the DHCPv6 PD client callback and
* then this method can be used to configure the prefix in the Routing Manager module.
*
* Note: This method is a part of DHCPv6 PD support on Thread border routers. For platforms where it doesn't make
* sense to generate a RA to set a DHCPv6 PD prefix this method can be used to set the prefix directly. The lifetime
* of the prefix can be updated by calling the function again with updated values.
*
* @param[in] aPrefixInfo Prefix information structure received from the DHCPv6 PD server.
*
*/
void ProcessDhcpPdPrefix(const PrefixTableEntry &aPrefixInfo) { mPdPrefixManager.ProcessDhcpPdPrefix(aPrefixInfo); }
/**
* Enables / Disables the functions for DHCPv6 PD.
*
* @param[in] aEnabled Whether to accept platform generated RA messages.
* @param[in] aEnabled Whether to enable or disable.
*
*/
void SetDhcp6PdEnabled(bool aEnabled) { return mPdPrefixManager.SetEnabled(aEnabled); }
/**
* Returns the state of accpeting RouterAdvertisement messages on platform interface.
* Returns the state DHCPv6 Prefix Delegation manager.
*
* @retval kDhcp6PdStateRunning DHCPv6 PD should be enabled and running on this border router.
* @retval kDhcp6PdStateDisabled DHCPv6 PD should be disabled on this border router..
* @returns The DHCPv6 PD state.
*
*/
Dhcp6PdState GetDhcp6PdState(void) const { return mPdPrefixManager.GetState(); }
/**
* Sets the callback whenever the state of a prefix request or release, via the DHCPv6 Prefix Delegation (PD),
* changes on the Thread interface.
* Sets the callback to notify when DHCPv6 Prefix Delegation manager state gets changed.
*
* @param[in] aCallback A pointer to a function that is called whenever the state of a prefix request or release
* changes.
* @param[in] aCallback A pointer to a callback function
* @param[in] aContext A pointer to arbitrary context information.
*
*/
void SetRequestDhcp6PdCallback(PdCallback aCallback, void *aContext)
{
mPdPrefixManager.SetRequestDhcp6PdCallback(aCallback, aContext);
mPdPrefixManager.SetStateCallback(aCallback, aContext);
}
/**
* Returns the DHCPv6-PD based off-mesh-routable (OMR) prefix.
*
* @param[out] aPrefixInfo A reference to where the prefix info will be output to.
*
* @retval kErrorNone Successfully retrieved the OMR prefix.
* @retval kErrorNotFound There are no valid PD prefix on this BR.
* @retval kErrorInvalidState The Border Routing Manager is not initialized yet.
*
*/
Error GetPdOmrPrefix(PrefixTableEntry &aPrefixInfo) const;
/**
* Returns platform generated RA message processed counters and information.
*
* @param[out] aPdProcessedRaInfo A reference to where the PD processed RA info will be output to.
*
* @retval kErrorNone Successfully retrieved the Info.
* @retval kErrorNotFound There are no valid RA process info on this BR.
* @retval kErrorInvalidState The Border Routing Manager is not initialized yet.
*
*/
Error GetPdProcessedRaInfo(PdProcessedRaInfo &aPdProcessedRaInfo);
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
private:
@@ -1294,58 +1268,58 @@ private:
class PdPrefixManager : public InstanceLocator
{
public:
// This class implements handling (including management of the lifetime) of the prefix obtained from platform's
// DHCPv6 PD client. We expect the platform will send ICMP6 RA messages to the platform's interface for the
// information of the prefix.
// This class manages the state of the PD prefix in OmrPrefixManager
// This class implements handling (including management of the
// lifetime) of the prefix obtained from platform's DHCPv6 PD
// client.
typedef Dhcp6PdState State;
explicit PdPrefixManager(Instance &aInstance);
void SetEnabled(bool aEnabled);
void Start(void) { StartStop(/* aStart= */ true); }
void Stop(void) { StartStop(/* aStart= */ false); }
bool IsRunning(void) const { return GetState() == Dhcp6PdState::kDhcp6PdStateRunning; }
bool IsRunning(void) const { return GetState() == kDhcp6PdStateRunning; }
bool HasPrefix(void) const { return IsValidOmrPrefix(mPrefix.GetPrefix()); }
const Ip6::Prefix &GetPrefix(void) const { return mPrefix.GetPrefix(); }
Dhcp6PdState GetState(void) const;
State GetState(void) const;
void ProcessPlatformGeneratedRa(const uint8_t *aRouterAdvert, uint16_t aLength);
void ProcessDhcpPdPrefix(const PrefixTableEntry &aPrefixTableEntry);
void ProcessRa(const uint8_t *aRouterAdvert, uint16_t aLength);
void ProcessPrefix(const PrefixTableEntry &aPrefixTableEntry);
Error GetPrefixInfo(PrefixTableEntry &aInfo) const;
Error GetProcessedRaInfo(PdProcessedRaInfo &aPdProcessedRaInfo) const;
void HandleTimer(void) { WithdrawPrefix(); }
void SetRequestDhcp6PdCallback(PdCallback aCallback, void *aContext)
{
mExternalCallback.Set(aCallback, aContext);
}
static const char *StateToString(Dhcp6PdState aState);
static bool IsValidPdPrefix(const Ip6::Prefix &aPrefix)
{
// We should accept ULA prefix since it could be used by the internet infrastructure like NAT64.
return aPrefix.GetLength() != 0 && aPrefix.GetLength() <= kOmrPrefixLength && !aPrefix.IsLinkLocal() &&
!aPrefix.IsMulticast();
}
void SetStateCallback(PdCallback aCallback, void *aContext) { mStateCallback.Set(aCallback, aContext); }
private:
Error Process(const RouterAdvert::RxMessage *aMessage, const PrefixTableEntry *aPrefixTableEntry);
bool ProcessPrefixEntry(DiscoveredPrefixTable::Entry &aEntry, DiscoveredPrefixTable::Entry &aFavoredEntry);
void EvaluateStateChange(Dhcp6PdState aOldState);
void WithdrawPrefix(void);
void StartStop(bool aStart);
class PrefixEntry : public DiscoveredPrefixTable::Entry
{
public:
PrefixEntry(void) { Clear(); }
bool IsEmpty(void) const { return (GetPrefix().GetLength() == 0); }
bool IsValidPdPrefix(void) const;
bool IsFavoredOver(const PrefixEntry &aOther) const;
};
using PlatformOmrPrefixTimer = TimerMilliIn<RoutingManager, &RoutingManager::HandlePdPrefixManagerTimer>;
using ExternalCallback = Callback<PdCallback>;
void Process(const RouterAdvert::Icmp6Packet *aRaPacket, const PrefixTableEntry *aPrefixTableEntry);
bool ProcessPrefixEntry(PrefixEntry &aEntry, PrefixEntry &aFavoredEntry);
void EvaluateStateChange(State aOldState);
void WithdrawPrefix(void);
void StartStop(bool aStart);
bool mEnabled;
bool mIsRunning;
uint32_t mNumPlatformPioProcessed;
uint32_t mNumPlatformRaReceived;
TimeMilli mLastPlatformRaTime;
ExternalCallback mExternalCallback;
PlatformOmrPrefixTimer mTimer;
DiscoveredPrefixTable::Entry mPrefix;
static const char *StateToString(State aState);
using PrefixTimer = TimerMilliIn<RoutingManager, &RoutingManager::HandlePdPrefixManagerTimer>;
using StateCallback = Callback<PdCallback>;
bool mEnabled;
bool mIsRunning;
uint32_t mNumPlatformPioProcessed;
uint32_t mNumPlatformRaReceived;
TimeMilli mLastPlatformRaTime;
StateCallback mStateCallback;
PrefixTimer mTimer;
PrefixEntry mPrefix;
};
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE