mirror of
https://github.com/espressif/openthread.git
synced 2026-09-08 10:10:06 +00:00
[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:
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user