mirror of
https://github.com/espressif/openthread.git
synced 2026-08-22 18:39:50 +00:00
[border-router] introduce br_types.hpp for common types (#11992)
Introduces a new `br_types.hpp` header and `br_types.cpp` source file to centralize common data structures and type definitions used across border router modules. This change moves several classes from `routing_manager.hpp` to the new `br_types.hpp` header. The moved classes include `LifetimedPrefix`, `OnLinkPrefix`, `RoutePrefix`, `RdnssAddress`, `IfAddress`, `OmrPrefix`, and `FavoredOmrPrefix`. Additionally, common `typedef`s (e.g., `RoutePreference`, `PrefixTableEntry`) and helper functions like `IsValidOmrPrefix()` are relocated to the new files. This improves the code structure by decoupling these shared types from the main `RoutingManager` class, making them more reusable and easier to maintain.
This commit is contained in:
@@ -377,6 +377,8 @@ openthread_core_files = [
|
||||
"backbone_router/ndproxy_table.hpp",
|
||||
"border_router/br_tracker.cpp",
|
||||
"border_router/br_tracker.hpp",
|
||||
"border_router/br_types.cpp",
|
||||
"border_router/br_types.hpp",
|
||||
"border_router/dhcp6_pd_client.cpp",
|
||||
"border_router/dhcp6_pd_client.hpp",
|
||||
"border_router/infra_if.cpp",
|
||||
|
||||
@@ -96,6 +96,7 @@ set(COMMON_SOURCES
|
||||
backbone_router/multicast_listeners_table.cpp
|
||||
backbone_router/ndproxy_table.cpp
|
||||
border_router/br_tracker.cpp
|
||||
border_router/br_types.cpp
|
||||
border_router/dhcp6_pd_client.cpp
|
||||
border_router/infra_if.cpp
|
||||
border_router/routing_manager.cpp
|
||||
|
||||
@@ -74,16 +74,15 @@ otError otBorderRoutingSetOmrConfig(otInstance *aInstance,
|
||||
otRoutePreference aPreference)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().SetOmrConfig(
|
||||
MapEnum(aConfig), AsCoreTypePtr(aOmrPrefix),
|
||||
static_cast<BorderRouter::RoutingManager::RoutePreference>(aPreference));
|
||||
MapEnum(aConfig), AsCoreTypePtr(aOmrPrefix), static_cast<BorderRouter::RoutePreference>(aPreference));
|
||||
}
|
||||
|
||||
otBorderRoutingOmrConfig otBorderRoutingGetOmrConfig(otInstance *aInstance,
|
||||
otIp6Prefix *aOmrPrefix,
|
||||
otRoutePreference *aPreference)
|
||||
{
|
||||
BorderRouter::RoutingManager::RoutePreference preference;
|
||||
BorderRouter::RoutingManager::OmrConfig omrConfig;
|
||||
BorderRouter::RoutePreference preference;
|
||||
BorderRouter::RoutingManager::OmrConfig omrConfig;
|
||||
|
||||
omrConfig =
|
||||
AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().GetOmrConfig(AsCoreTypePtr(aOmrPrefix), &preference);
|
||||
@@ -158,8 +157,8 @@ otError otBorderRoutingGetPdProcessedRaInfo(otInstance *aInstance, otPdProcessed
|
||||
|
||||
otError otBorderRoutingGetFavoredOmrPrefix(otInstance *aInstance, otIp6Prefix *aPrefix, otRoutePreference *aPreference)
|
||||
{
|
||||
otError error;
|
||||
BorderRouter::RoutingManager::RoutePreference preference;
|
||||
otError error;
|
||||
BorderRouter::RoutePreference preference;
|
||||
|
||||
AssertPointerIsNotNull(aPreference);
|
||||
|
||||
@@ -191,8 +190,8 @@ otError otBorderRoutingGetFavoredNat64Prefix(otInstance *aInstance,
|
||||
otIp6Prefix *aPrefix,
|
||||
otRoutePreference *aPreference)
|
||||
{
|
||||
otError error;
|
||||
BorderRouter::RoutingManager::RoutePreference preference;
|
||||
otError error;
|
||||
BorderRouter::RoutePreference preference;
|
||||
|
||||
AssertPointerIsNotNull(aPreference);
|
||||
|
||||
|
||||
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Copyright (c) 2025, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file implements common type definitions for Border Router modules.
|
||||
*/
|
||||
|
||||
#include "br_types.hpp"
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
#include "instance/instance.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace BorderRouter {
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// LifetimedPrefix
|
||||
|
||||
TimeMilli LifetimedPrefix::CalculateExpirationTime(uint32_t aLifetime) const
|
||||
{
|
||||
// `aLifetime` is in unit of seconds. This method ensures
|
||||
// that the time calculation fits with `TimeMilli` range.
|
||||
|
||||
return CalculateClampedExpirationTime(mLastUpdateTime, aLifetime);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// OnLinkPrefix
|
||||
|
||||
void OnLinkPrefix::SetFrom(const PrefixInfoOption &aPio)
|
||||
{
|
||||
aPio.GetPrefix(mPrefix);
|
||||
mValidLifetime = aPio.GetValidLifetime();
|
||||
mPreferredLifetime = aPio.GetPreferredLifetime();
|
||||
mAutoAddrConfigFlag = aPio.IsAutoAddrConfigFlagSet();
|
||||
mDhcp6PdPreferredFlag = aPio.IsDhcp6PdPreferredFlagSet();
|
||||
mLastUpdateTime = TimerMilli::GetNow();
|
||||
}
|
||||
|
||||
void OnLinkPrefix::SetFrom(const PrefixTableEntry &aPrefixTableEntry)
|
||||
{
|
||||
mPrefix = AsCoreType(&aPrefixTableEntry.mPrefix);
|
||||
mValidLifetime = aPrefixTableEntry.mValidLifetime;
|
||||
mPreferredLifetime = aPrefixTableEntry.mPreferredLifetime;
|
||||
mLastUpdateTime = TimerMilli::GetNow();
|
||||
}
|
||||
|
||||
bool OnLinkPrefix::IsDeprecated(void) const { return GetDeprecationTime() <= TimerMilli::GetNow(); }
|
||||
|
||||
TimeMilli OnLinkPrefix::GetDeprecationTime(void) const { return CalculateExpirationTime(mPreferredLifetime); }
|
||||
|
||||
TimeMilli OnLinkPrefix::GetStaleTime(void) const
|
||||
{
|
||||
return CalculateExpirationTime(Min(kStaleTime, mPreferredLifetime));
|
||||
}
|
||||
|
||||
void OnLinkPrefix::AdoptFlagsAndValidAndPreferredLifetimesFrom(const OnLinkPrefix &aPrefix)
|
||||
{
|
||||
constexpr uint32_t kTwoHoursInSeconds = 2 * 3600;
|
||||
|
||||
// Per RFC 4862 section 5.5.3.e:
|
||||
//
|
||||
// 1. If the received Valid Lifetime is greater than 2 hours or
|
||||
// greater than RemainingLifetime, set the valid lifetime of the
|
||||
// corresponding address to the advertised Valid Lifetime.
|
||||
// 2. If RemainingLifetime is less than or equal to 2 hours, ignore
|
||||
// the Prefix Information option with regards to the valid
|
||||
// lifetime, unless ...
|
||||
// 3. Otherwise, reset the valid lifetime of the corresponding
|
||||
// address to 2 hours.
|
||||
|
||||
if (aPrefix.mValidLifetime > kTwoHoursInSeconds || aPrefix.GetExpireTime() > GetExpireTime())
|
||||
{
|
||||
mValidLifetime = aPrefix.mValidLifetime;
|
||||
}
|
||||
else if (GetExpireTime() > TimerMilli::GetNow() + TimeMilli::SecToMsec(kTwoHoursInSeconds))
|
||||
{
|
||||
mValidLifetime = kTwoHoursInSeconds;
|
||||
}
|
||||
|
||||
mPreferredLifetime = aPrefix.GetPreferredLifetime();
|
||||
mAutoAddrConfigFlag = aPrefix.mAutoAddrConfigFlag;
|
||||
mDhcp6PdPreferredFlag = aPrefix.mDhcp6PdPreferredFlag;
|
||||
mLastUpdateTime = aPrefix.GetLastUpdateTime();
|
||||
}
|
||||
|
||||
void OnLinkPrefix::CopyInfoTo(PrefixTableEntry &aEntry, TimeMilli aNow) const
|
||||
{
|
||||
aEntry.mPrefix = GetPrefix();
|
||||
aEntry.mIsOnLink = true;
|
||||
aEntry.mMsecSinceLastUpdate = aNow - GetLastUpdateTime();
|
||||
aEntry.mValidLifetime = GetValidLifetime();
|
||||
aEntry.mPreferredLifetime = GetPreferredLifetime();
|
||||
}
|
||||
|
||||
bool OnLinkPrefix::IsFavoredOver(const Ip6::Prefix &aPrefix) const
|
||||
{
|
||||
bool isFavored = false;
|
||||
|
||||
// Validate that the `OnLinkPrefix` is eligible to be a favored
|
||||
// on-link prefix. It must have a valid length and either the
|
||||
// AutoAddrConfig (`A`) or Dhcp6PdPreferred (`P`) flag.
|
||||
// Additionally, it must not be deprecated and its preferred
|
||||
// lifetime must be at least `kFavoredMinPreferredLifetime`
|
||||
// (1800) seconds.
|
||||
|
||||
VerifyOrExit(mPrefix.GetLength() == kExpectedFavoredPrefixLength);
|
||||
VerifyOrExit(mAutoAddrConfigFlag || mDhcp6PdPreferredFlag);
|
||||
VerifyOrExit(!IsDeprecated());
|
||||
VerifyOrExit(GetPreferredLifetime() >= kFavoredMinPreferredLifetime);
|
||||
|
||||
// Numerically smaller prefix is favored (unless `aPrefix` is empty).
|
||||
|
||||
VerifyOrExit(aPrefix.GetLength() != 0, isFavored = true);
|
||||
|
||||
isFavored = GetPrefix() < aPrefix;
|
||||
|
||||
exit:
|
||||
return isFavored;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// RoutePrefix
|
||||
|
||||
void RoutePrefix::SetFrom(const RouteInfoOption &aRio)
|
||||
{
|
||||
aRio.GetPrefix(mPrefix);
|
||||
mValidLifetime = aRio.GetRouteLifetime();
|
||||
mRoutePreference = aRio.GetPreference();
|
||||
mLastUpdateTime = TimerMilli::GetNow();
|
||||
}
|
||||
|
||||
void RoutePrefix::SetFrom(const RouterAdvert::Header &aRaHeader)
|
||||
{
|
||||
mPrefix.Clear();
|
||||
mValidLifetime = aRaHeader.GetRouterLifetime();
|
||||
mRoutePreference = aRaHeader.GetDefaultRouterPreference();
|
||||
mLastUpdateTime = TimerMilli::GetNow();
|
||||
}
|
||||
|
||||
TimeMilli RoutePrefix::GetStaleTime(void) const { return CalculateExpirationTime(Min(kStaleTime, mValidLifetime)); }
|
||||
|
||||
void RoutePrefix::CopyInfoTo(PrefixTableEntry &aEntry, TimeMilli aNow) const
|
||||
{
|
||||
aEntry.mPrefix = GetPrefix();
|
||||
aEntry.mIsOnLink = false;
|
||||
aEntry.mMsecSinceLastUpdate = aNow - GetLastUpdateTime();
|
||||
aEntry.mValidLifetime = GetValidLifetime();
|
||||
aEntry.mPreferredLifetime = 0;
|
||||
aEntry.mRoutePreference = static_cast<otRoutePreference>(GetRoutePreference());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// RdnssAddress
|
||||
|
||||
void RdnssAddress::SetFrom(const RecursiveDnsServerOption &aRdnss, uint16_t aAddressIndex)
|
||||
{
|
||||
mAddress = aRdnss.GetAddressAt(aAddressIndex);
|
||||
mLifetime = aRdnss.GetLifetime();
|
||||
mLastUpdateTime = TimerMilli::GetNow();
|
||||
}
|
||||
|
||||
TimeMilli RdnssAddress::GetExpireTime(void) const { return CalculateClampedExpirationTime(mLastUpdateTime, mLifetime); }
|
||||
|
||||
void RdnssAddress::CopyInfoTo(RdnssAddrEntry &aEntry, TimeMilli aNow) const
|
||||
{
|
||||
aEntry.mAddress = GetAddress();
|
||||
aEntry.mMsecSinceLastUpdate = aNow - GetLastUpdateTime();
|
||||
aEntry.mLifetime = GetLifetime();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// IfAddress
|
||||
|
||||
void IfAddress::SetFrom(const Ip6::Address &aAddress, uint32_t aUptimeNow)
|
||||
{
|
||||
mAddress = aAddress;
|
||||
mLastUseUptime = aUptimeNow;
|
||||
}
|
||||
|
||||
bool IfAddress::Matches(const InvalidChecker &aChecker) const { return !aChecker.Get<InfraIf>().HasAddress(mAddress); }
|
||||
|
||||
void IfAddress::CopyInfoTo(IfAddrEntry &aEntry, uint32_t aUptimeNow) const
|
||||
{
|
||||
aEntry.mAddress = mAddress;
|
||||
aEntry.mSecSinceLastUse = aUptimeNow - mLastUseUptime;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// OmrPrefix
|
||||
|
||||
void OmrPrefix::SetPrefix(const Ip6::Prefix &aPrefix, RoutePreference aPreference)
|
||||
{
|
||||
Clear();
|
||||
mPrefix = aPrefix;
|
||||
mPreference = aPreference;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// FavoredOmrPrefix
|
||||
|
||||
bool FavoredOmrPrefix::IsInfrastructureDerived(void) const
|
||||
{
|
||||
// Indicate whether the OMR prefix is infrastructure-derived which
|
||||
// can be identified as a valid OMR prefix with preference of
|
||||
// medium or higher.
|
||||
|
||||
return !IsEmpty() && (mPreference >= NetworkData::kRoutePreferenceMedium);
|
||||
}
|
||||
|
||||
void FavoredOmrPrefix::SetFrom(const NetworkData::OnMeshPrefixConfig &aOnMeshPrefixConfig)
|
||||
{
|
||||
mPrefix = aOnMeshPrefixConfig.GetPrefix();
|
||||
mPreference = aOnMeshPrefixConfig.GetPreference();
|
||||
mIsDomainPrefix = aOnMeshPrefixConfig.mDp;
|
||||
}
|
||||
|
||||
void FavoredOmrPrefix::SetFrom(const OmrPrefix &aOmrPrefix)
|
||||
{
|
||||
mPrefix = aOmrPrefix.GetPrefix();
|
||||
mPreference = aOmrPrefix.GetPreference();
|
||||
mIsDomainPrefix = aOmrPrefix.IsDomainPrefix();
|
||||
}
|
||||
|
||||
bool FavoredOmrPrefix::IsFavoredOver(const NetworkData::OnMeshPrefixConfig &aOmrPrefixConfig) const
|
||||
{
|
||||
// This method determines whether this OMR prefix is favored
|
||||
// over another prefix. A prefix with higher preference is
|
||||
// favored. If the preference is the same, then the smaller
|
||||
// prefix (in the sense defined by `Ip6::Prefix`) is favored.
|
||||
|
||||
bool isFavored = (mPreference > aOmrPrefixConfig.GetPreference());
|
||||
|
||||
OT_ASSERT(IsValidOmrPrefix(aOmrPrefixConfig));
|
||||
|
||||
if (mPreference == aOmrPrefixConfig.GetPreference())
|
||||
{
|
||||
isFavored = (mPrefix < aOmrPrefixConfig.GetPrefix());
|
||||
}
|
||||
|
||||
return isFavored;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
bool IsValidOmrPrefix(const NetworkData::OnMeshPrefixConfig &aOnMeshPrefixConfig)
|
||||
{
|
||||
return IsValidOmrPrefix(aOnMeshPrefixConfig.GetPrefix()) && aOnMeshPrefixConfig.mOnMesh &&
|
||||
aOnMeshPrefixConfig.mSlaac && aOnMeshPrefixConfig.mStable;
|
||||
}
|
||||
|
||||
bool IsValidOmrPrefix(const Ip6::Prefix &aPrefix)
|
||||
{
|
||||
// Accept ULA/GUA prefixes with 64-bit length.
|
||||
return (aPrefix.GetLength() == OmrPrefix::kPrefixLength) && !aPrefix.IsLinkLocal() && !aPrefix.IsMulticast();
|
||||
}
|
||||
|
||||
TimeMilli CalculateClampedExpirationTime(TimeMilli aUpdateTime, uint32_t aLifetime)
|
||||
{
|
||||
static constexpr uint32_t kMaxLifetime = Time::MsecToSec(Timer::kMaxDelay);
|
||||
|
||||
return aUpdateTime + Time::SecToMsec(Min(aLifetime, kMaxLifetime));
|
||||
}
|
||||
|
||||
} // namespace BorderRouter
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
@@ -0,0 +1,631 @@
|
||||
/*
|
||||
* Copyright (c) 2025, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file includes common type definitions for Border Router modules.
|
||||
*/
|
||||
|
||||
#ifndef BR_TYPES_HPP_
|
||||
#define BR_TYPES_HPP_
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
#include <openthread/border_routing.h>
|
||||
|
||||
#include "common/clearable.hpp"
|
||||
#include "common/equatable.hpp"
|
||||
#include "common/error.hpp"
|
||||
#include "common/locator.hpp"
|
||||
#include "common/string.hpp"
|
||||
#include "common/time.hpp"
|
||||
#include "common/timer.hpp"
|
||||
#include "net/ip6_address.hpp"
|
||||
#include "net/nd6.hpp"
|
||||
#include "thread/network_data.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace BorderRouter {
|
||||
|
||||
typedef NetworkData::RoutePreference RoutePreference; ///< Route preference (high, medium, low).
|
||||
typedef otBorderRoutingPrefixTableIterator PrefixTableIterator; ///< Prefix Table Iterator.
|
||||
typedef otBorderRoutingPrefixTableEntry PrefixTableEntry; ///< Prefix Table Entry.
|
||||
typedef otBorderRoutingRouterEntry RouterEntry; ///< Router Entry.
|
||||
typedef otBorderRoutingRdnssAddrEntry RdnssAddrEntry; ///< RDNSS Address Entry.
|
||||
typedef otBorderRoutingRdnssAddrCallback RdnssAddrCallback; ///< RDNS Address changed callback.
|
||||
typedef otBorderRoutingIfAddrEntry IfAddrEntry; ///< Infra-if IPv6 Address Entry.
|
||||
typedef otBorderRoutingPeerBorderRouterEntry PeerBrEntry; ///< Peer Border Router Entry.
|
||||
typedef otBorderRoutingPrefixTableEntry Dhcp6PdPrefix; ///< DHCPv6 PD prefix.
|
||||
typedef otPdProcessedRaInfo Dhcp6PdCounters; ///< DHCPv6 PD counters.
|
||||
typedef otBorderRoutingRequestDhcp6PdCallback Dhcp6PdCallback; ///< DHCPv6 PD callback.
|
||||
typedef otBorderRoutingMultiAilCallback MultiAilCallback; ///< Multi AIL detection callback.
|
||||
|
||||
// IPv6 Neighbor Discovery (ND) types
|
||||
typedef Ip6::Nd::PrefixInfoOption PrefixInfoOption; ///< Prefix Info Option (PIO).
|
||||
typedef Ip6::Nd::RouteInfoOption RouteInfoOption; ///< Route Info Option (RIO).
|
||||
typedef Ip6::Nd::RaFlagsExtOption RaFlagsExtOption; ///< RA Flags Extension Option.
|
||||
typedef Ip6::Nd::RecursiveDnsServerOption RecursiveDnsServerOption; ///< Recursive DNS Server (RDNSS) Option.
|
||||
typedef Ip6::Nd::RouterAdvert RouterAdvert; ///< Router Advertisement (RA).
|
||||
typedef Ip6::Nd::NeighborAdvertMessage NeighborAdvertMessage; ///< Neighbor Advertisement message.
|
||||
typedef Ip6::Nd::NeighborSolicitHeader NeighborSolicitHeader; ///< Neighbor Solicitation (NS) message.
|
||||
typedef Ip6::Nd::RouterSolicitHeader RouterSolicitHeader; ///< Router Solicitation (RS) message.
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
/**
|
||||
* Represents an IPv6 prefix with an associated lifetime.
|
||||
*
|
||||
* This class serves as a base for other prefix types like `OnLinkPrefix` or `RoutePrefix`.
|
||||
*/
|
||||
class LifetimedPrefix
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Gets the IPv6 prefix.
|
||||
*
|
||||
* @returns A const reference to the IPv6 prefix.
|
||||
*/
|
||||
const Ip6::Prefix &GetPrefix(void) const { return mPrefix; }
|
||||
|
||||
/**
|
||||
* Gets the IPv6 prefix.
|
||||
*
|
||||
* @returns A reference to the IPv6 prefix.
|
||||
*/
|
||||
Ip6::Prefix &GetPrefix(void) { return mPrefix; }
|
||||
|
||||
/**
|
||||
* Gets the time when this prefix was last updated.
|
||||
*
|
||||
* @returns The last update time.
|
||||
*/
|
||||
const TimeMilli &GetLastUpdateTime(void) const { return mLastUpdateTime; }
|
||||
|
||||
/**
|
||||
* Gets the valid lifetime of the prefix.
|
||||
*
|
||||
* @returns The valid lifetime in seconds.
|
||||
*/
|
||||
uint32_t GetValidLifetime(void) const { return mValidLifetime; }
|
||||
|
||||
/**
|
||||
* Gets the expiration time of the prefix.
|
||||
*
|
||||
* @returns The expiration time.
|
||||
*/
|
||||
TimeMilli GetExpireTime(void) const { return CalculateExpirationTime(mValidLifetime); }
|
||||
|
||||
/**
|
||||
* Indicates whether the prefix matches a given IPv6 prefix.
|
||||
*
|
||||
* @param[in] aPrefix The IPv6 prefix to match against.
|
||||
*
|
||||
* @retval TRUE If the prefix matches @p aPrefix.
|
||||
* @retval FALSE If the prefix does not match @p aPrefix.
|
||||
*/
|
||||
bool Matches(const Ip6::Prefix &aPrefix) const { return (mPrefix == aPrefix); }
|
||||
|
||||
/**
|
||||
* Indicates whether the prefix is considered expired by a given `ExpirationChecker`.
|
||||
*
|
||||
* @param[in] aChecker An `ExpirationChecker` to use for checking.
|
||||
*
|
||||
* @retval TRUE If the prefix is expired.
|
||||
* @retval FALSE If the prefix is not expired.
|
||||
*/
|
||||
bool Matches(const ExpirationChecker &aChecker) const { return aChecker.IsExpired(GetExpireTime()); }
|
||||
|
||||
/**
|
||||
* Sets the flag indicating whether the stale time for this prefix has been calculated.
|
||||
*
|
||||
* @param[in] aFlag `true` to indicate that stale time has been calculated, `false` otherwise.
|
||||
*/
|
||||
void SetStaleTimeCalculated(bool aFlag) { mStaleTimeCalculated = aFlag; }
|
||||
|
||||
/**
|
||||
* Indicates whether the stale time for this prefix has been calculated.
|
||||
*
|
||||
* @returns `true` if the stale time has been calculated, `false` otherwise.
|
||||
*/
|
||||
bool IsStaleTimeCalculated(void) const { return mStaleTimeCalculated; }
|
||||
|
||||
/**
|
||||
* Sets the flag indicating that this prefix entry should be disregarded.
|
||||
*
|
||||
* @param[in] aFlag `true` to disregard the prefix, `false` otherwise.
|
||||
*/
|
||||
void SetDisregardFlag(bool aFlag) { mDisregard = aFlag; }
|
||||
|
||||
/**
|
||||
* Indicates whether this prefix entry should be disregarded.
|
||||
*
|
||||
* @returns `true` if the prefix should be disregarded, `false` otherwise.
|
||||
*/
|
||||
bool ShouldDisregard(void) const { return mDisregard; }
|
||||
|
||||
protected:
|
||||
// The stale time in seconds.
|
||||
//
|
||||
// The amount of time that can pass after the last time an RA from
|
||||
// a particular router has been received advertising an on-link
|
||||
// or route prefix before we assume the prefix entry is stale.
|
||||
//
|
||||
// If multiple routers advertise the same on-link or route prefix,
|
||||
// the stale time for the prefix is determined by the latest
|
||||
// stale time among all corresponding entries. Stale time
|
||||
// expiration triggers tx of Router Solicitation (RS) messages
|
||||
|
||||
static constexpr uint32_t kStaleTime = 600; // 10 minutes.
|
||||
|
||||
LifetimedPrefix(void) = default;
|
||||
|
||||
TimeMilli CalculateExpirationTime(uint32_t aLifetime) const;
|
||||
|
||||
Ip6::Prefix mPrefix;
|
||||
bool mDisregard : 1;
|
||||
bool mStaleTimeCalculated : 1;
|
||||
uint32_t mValidLifetime;
|
||||
TimeMilli mLastUpdateTime;
|
||||
};
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
/**
|
||||
* Represents an on-link prefix.
|
||||
*/
|
||||
class OnLinkPrefix : public LifetimedPrefix, public Clearable<OnLinkPrefix>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Sets the on-link prefix information from a Prefix Information Option (PIO).
|
||||
*
|
||||
* @param[in] aPio The Prefix Information Option to set from.
|
||||
*/
|
||||
void SetFrom(const PrefixInfoOption &aPio);
|
||||
|
||||
/**
|
||||
* Sets the on-link prefix information from a `PrefixTableEntry`.
|
||||
*
|
||||
* @param[in] aPrefixTableEntry The `PrefixTableEntry` to set from.
|
||||
*/
|
||||
void SetFrom(const PrefixTableEntry &aPrefixTableEntry);
|
||||
|
||||
/**
|
||||
* Gets the preferred lifetime of the prefix.
|
||||
*
|
||||
* @returns The preferred lifetime in seconds.
|
||||
*/
|
||||
uint32_t GetPreferredLifetime(void) const { return mPreferredLifetime; }
|
||||
|
||||
/**
|
||||
* Clears (sets to zero) the preferred lifetime of the prefix.
|
||||
*/
|
||||
void ClearPreferredLifetime(void) { mPreferredLifetime = 0; }
|
||||
|
||||
/**
|
||||
* Indicates whether the on-link prefix is deprecated.
|
||||
*
|
||||
* @retval TRUE If the prefix is deprecated.
|
||||
* @retval FALSE If the prefix is not deprecated.
|
||||
*/
|
||||
bool IsDeprecated(void) const;
|
||||
|
||||
/**
|
||||
* Gets the time when the on-link prefix will be deprecated.
|
||||
*
|
||||
* @returns The deprecation time.
|
||||
*/
|
||||
TimeMilli GetDeprecationTime(void) const;
|
||||
|
||||
/**
|
||||
* Gets the time when the on-link prefix will become stale.
|
||||
*
|
||||
* @returns The stale time.
|
||||
*/
|
||||
TimeMilli GetStaleTime(void) const;
|
||||
|
||||
/**
|
||||
* Adopts flags, valid lifetime, and preferred lifetime from another `OnLinkPrefix` object.
|
||||
*
|
||||
* @param[in] aPrefix The `OnLinkPrefix` to adopt information from.
|
||||
*/
|
||||
void AdoptFlagsAndValidAndPreferredLifetimesFrom(const OnLinkPrefix &aPrefix);
|
||||
|
||||
/**
|
||||
* Copies the on-link prefix information to a `PrefixTableEntry`.
|
||||
*
|
||||
* @param[out] aEntry The `PrefixTableEntry` to copy information to.
|
||||
* @param[in] aNow The current time.
|
||||
*/
|
||||
void CopyInfoTo(PrefixTableEntry &aEntry, TimeMilli aNow) const;
|
||||
|
||||
/**
|
||||
* Indicates whether this on-link prefix is favored over another IPv6 prefix.
|
||||
*
|
||||
* @param[in] aPrefix The IPv6 prefix to compare against.
|
||||
*
|
||||
* @retval TRUE If this prefix is favored over @p aPrefix.
|
||||
* @retval FALSE If this prefix is not favored over @p aPrefix.
|
||||
*/
|
||||
bool IsFavoredOver(const Ip6::Prefix &aPrefix) const;
|
||||
|
||||
private:
|
||||
static constexpr uint32_t kFavoredMinPreferredLifetime = 1800; // In sec.
|
||||
static constexpr uint8_t kExpectedFavoredPrefixLength = 64;
|
||||
|
||||
uint32_t mPreferredLifetime;
|
||||
bool mAutoAddrConfigFlag : 1;
|
||||
bool mDhcp6PdPreferredFlag : 1;
|
||||
};
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
/**
|
||||
* Represents a route prefix.
|
||||
*/
|
||||
class RoutePrefix : public LifetimedPrefix, public Clearable<RoutePrefix>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Sets the route prefix information from a Route Information Option (RIO).
|
||||
*
|
||||
* @param[in] aRio The Route Information Option to set from.
|
||||
*/
|
||||
void SetFrom(const RouteInfoOption &aRio);
|
||||
|
||||
/**
|
||||
* Sets the route prefix information from a Router Advertisement (RA) header.
|
||||
*
|
||||
* @param[in] aRaHeader The Router Advertisement header to set from.
|
||||
*/
|
||||
void SetFrom(const RouterAdvert::Header &aRaHeader);
|
||||
|
||||
/**
|
||||
* Clears (sets to zero) the valid lifetime of the route prefix.
|
||||
*/
|
||||
void ClearValidLifetime(void) { mValidLifetime = 0; }
|
||||
|
||||
/**
|
||||
* Gets the time when the route prefix will become stale.
|
||||
*
|
||||
* @returns The stale time.
|
||||
*/
|
||||
TimeMilli GetStaleTime(void) const;
|
||||
|
||||
/**
|
||||
* Gets the route preference of the prefix.
|
||||
*
|
||||
* @returns The route preference.
|
||||
*/
|
||||
RoutePreference GetRoutePreference(void) const { return mRoutePreference; }
|
||||
|
||||
/**
|
||||
* Copies the route prefix information to a `PrefixTableEntry`.
|
||||
*
|
||||
* @param[out] aEntry The `PrefixTableEntry` to copy information to.
|
||||
* @param[in] aNow The current time.
|
||||
*/
|
||||
void CopyInfoTo(PrefixTableEntry &aEntry, TimeMilli aNow) const;
|
||||
|
||||
private:
|
||||
RoutePreference mRoutePreference;
|
||||
};
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
/**
|
||||
* Represents an RDNSS (Recursive DNS Server) address.
|
||||
*/
|
||||
class RdnssAddress
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Sets the RDNSS address information from a Recursive DNS Server Option (RDNSS) and an address index.
|
||||
*
|
||||
* @param[in] aRdnss The Recursive DNS Server Option to set from.
|
||||
* @param[in] aAddressIndex The index of the address within the RDNSS option.
|
||||
*/
|
||||
void SetFrom(const RecursiveDnsServerOption &aRdnss, uint16_t aAddressIndex);
|
||||
|
||||
/**
|
||||
* Gets the IPv6 address of the RDNSS server.
|
||||
*
|
||||
* @returns A const reference to the IPv6 address.
|
||||
*/
|
||||
const Ip6::Address &GetAddress(void) const { return mAddress; }
|
||||
|
||||
/**
|
||||
* Gets the time when this RDNSS address was last updated.
|
||||
*
|
||||
* @returns The last update time.
|
||||
*/
|
||||
const TimeMilli &GetLastUpdateTime(void) const { return mLastUpdateTime; }
|
||||
|
||||
/**
|
||||
* Gets the lifetime of the RDNSS address.
|
||||
*
|
||||
* @returns The lifetime in seconds.
|
||||
*/
|
||||
uint32_t GetLifetime(void) const { return mLifetime; }
|
||||
|
||||
/**
|
||||
* Gets the expiration time of the RDNSS address.
|
||||
*
|
||||
* @returns The expiration time.
|
||||
*/
|
||||
TimeMilli GetExpireTime(void) const;
|
||||
|
||||
/**
|
||||
* Clears (sets to zero) the lifetime of the RDNSS address.
|
||||
*/
|
||||
void ClearLifetime(void) { mLifetime = 0; }
|
||||
|
||||
/**
|
||||
* Copies the RDNSS address information to an `RdnssAddrEntry`.
|
||||
*
|
||||
* @param[out] aEntry The `RdnssAddrEntry` to copy information to.
|
||||
* @param[in] aNow The current time.
|
||||
*/
|
||||
void CopyInfoTo(RdnssAddrEntry &aEntry, TimeMilli aNow) const;
|
||||
|
||||
/**
|
||||
* Indicates whether this RDNSS address entry matches a given IPv6 address.
|
||||
*
|
||||
* @param[in] aAddress The IPv6 address to match against.
|
||||
*
|
||||
* @retval TRUE If the RDNSS address matches @p aAddress.
|
||||
* @retval FALSE If the RDNSS address does not match @p aAddress.
|
||||
*/
|
||||
bool Matches(const Ip6::Address &aAddress) const { return (mAddress == aAddress); }
|
||||
|
||||
/**
|
||||
* Indicates whether the RDNSS address is considered expired by a given `ExpirationChecker`.
|
||||
*
|
||||
* @param[in] aChecker An `ExpirationChecker` to use for checking.
|
||||
*
|
||||
* @retval TRUE If the RDNSS address is expired.
|
||||
* @retval FALSE If the RDNSS address is not expired.
|
||||
*/
|
||||
bool Matches(const ExpirationChecker &aChecker) const { return aChecker.IsExpired(GetExpireTime()); }
|
||||
|
||||
private:
|
||||
Ip6::Address mAddress;
|
||||
uint32_t mLifetime;
|
||||
TimeMilli mLastUpdateTime;
|
||||
};
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
/**
|
||||
* Represents an interface address used by this BR itself (e.g. for sending RA).
|
||||
*/
|
||||
class IfAddress
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Represents an `InvalidChecker` used to check if an interface address is invalid.
|
||||
*/
|
||||
struct InvalidChecker : public InstanceLocator
|
||||
{
|
||||
/**
|
||||
* Initializes the `InvalidChecker`.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
*/
|
||||
explicit InvalidChecker(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the interface address.
|
||||
*
|
||||
* @param[in] aAddress The IPv6 address.
|
||||
* @param[in] aUptimeNow The current uptime (in seconds).
|
||||
*/
|
||||
void SetFrom(const Ip6::Address &aAddress, uint32_t aUptimeNow);
|
||||
|
||||
/**
|
||||
* Indicates whether this interface address entry matches a given IPv6 address.
|
||||
*
|
||||
* @param[in] aAddress The IPv6 address to match against.
|
||||
*
|
||||
* @retval TRUE If the interface address matches @p aAddress.
|
||||
* @retval FALSE If the interface address does not match @p aAddress.
|
||||
*/
|
||||
bool Matches(const Ip6::Address &aAddress) const { return (mAddress == aAddress); }
|
||||
|
||||
/**
|
||||
* Indicates whether the interface address is considered invalid by a given `InvalidChecker`.
|
||||
*
|
||||
* @param[in] aChecker An `InvalidChecker` to use for checking.
|
||||
*
|
||||
* @retval TRUE If the interface address is invalid.
|
||||
* @retval FALSE If the interface address is valid.
|
||||
*/
|
||||
bool Matches(const InvalidChecker &aChecker) const;
|
||||
|
||||
/**
|
||||
* Copies the interface address information to an `IfAddrEntry`.
|
||||
*
|
||||
* @param[out] aEntry The `IfAddrEntry` to copy information to.
|
||||
* @param[in] aUptimeNow The current uptime.
|
||||
*/
|
||||
void CopyInfoTo(IfAddrEntry &aEntry, uint32_t aUptimeNow) const;
|
||||
|
||||
private:
|
||||
Ip6::Address mAddress;
|
||||
uint32_t mLastUseUptime;
|
||||
};
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
/**
|
||||
* Represents an OMR (Off-Mesh Routable) prefix.
|
||||
*/
|
||||
class OmrPrefix : public Clearable<OmrPrefix>, public Equatable<OmrPrefix>
|
||||
{
|
||||
public:
|
||||
static constexpr uint8_t kPrefixLength = 64;
|
||||
|
||||
/**
|
||||
* Constructor for `OmrPrefix`.
|
||||
*/
|
||||
OmrPrefix(void) { Clear(); }
|
||||
|
||||
/**
|
||||
* Indicates whether the OMR prefix is empty.
|
||||
*
|
||||
* @retval TRUE If the OMR prefix is empty.
|
||||
* @retval FALSE If the OMR prefix is not empty.
|
||||
*/
|
||||
bool IsEmpty(void) const { return (mPrefix.GetLength() == 0); }
|
||||
|
||||
/**
|
||||
* Gets the IPv6 prefix.
|
||||
*
|
||||
* @returns The IPv6 prefix.
|
||||
*/
|
||||
const Ip6::Prefix &GetPrefix(void) const { return mPrefix; }
|
||||
|
||||
/**
|
||||
* Gets the preference of the OMR prefix.
|
||||
*
|
||||
* @returns The preference.
|
||||
*/
|
||||
RoutePreference GetPreference(void) const { return mPreference; }
|
||||
|
||||
/**
|
||||
* Indicates whether the OMR prefix is a domain prefix.
|
||||
*
|
||||
* @retval TRUE If the OMR prefix is a domain prefix.
|
||||
* @retval FALSE If the OMR prefix is not a domain prefix.
|
||||
*/
|
||||
bool IsDomainPrefix(void) const { return mIsDomainPrefix; }
|
||||
|
||||
/**
|
||||
* Sets the OMR prefix and its preference.
|
||||
*
|
||||
* @param[in] aPrefix The IPv6 prefix to set.
|
||||
* @param[in] aPreference The preference to set.
|
||||
*/
|
||||
void SetPrefix(const Ip6::Prefix &aPrefix, RoutePreference aPreference);
|
||||
|
||||
protected:
|
||||
Ip6::Prefix mPrefix;
|
||||
RoutePreference mPreference;
|
||||
bool mIsDomainPrefix;
|
||||
};
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
class FavoredOmrPrefix : public OmrPrefix
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Indicates whether the favored OMR prefix is derived from the infrastructure.
|
||||
*
|
||||
* This is identified as a valid OMR prefix with preference of medium or higher.
|
||||
*
|
||||
* @retval TRUE If the prefix is infrastructure-derived.
|
||||
* @retval FALSE If the prefix is not infrastructure-derived.
|
||||
*/
|
||||
bool IsInfrastructureDerived(void) const;
|
||||
|
||||
/**
|
||||
* Sets the favored OMR prefix from an on-mesh prefix configuration.
|
||||
*
|
||||
* @param[in] aOnMeshPrefixConfig The on-mesh prefix configuration to set from.
|
||||
*/
|
||||
void SetFrom(const NetworkData::OnMeshPrefixConfig &aOnMeshPrefixConfig);
|
||||
|
||||
/**
|
||||
* Sets the favored OMR prefix from an `OmrPrefix` object.
|
||||
*
|
||||
* @param[in] aOmrPrefix The `OmrPrefix` object to set from.
|
||||
*/
|
||||
void SetFrom(const OmrPrefix &aOmrPrefix);
|
||||
|
||||
/**
|
||||
* Indicates whether this favored OMR prefix is favored over another on-mesh prefix configuration.
|
||||
*
|
||||
* @param[in] aOmrPrefixConfig The on-mesh prefix configuration to compare against.
|
||||
*
|
||||
* @retval TRUE If this prefix is favored over @p aOmrPrefixConfig.
|
||||
* @retval FALSE If this prefix is not favored over @p aOmrPrefixConfig.
|
||||
*/
|
||||
bool IsFavoredOver(const NetworkData::OnMeshPrefixConfig &aOmrPrefixConfig) const;
|
||||
};
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Helper functions
|
||||
|
||||
/**
|
||||
* Checks whether the on-mesh prefix configuration is a valid OMR prefix.
|
||||
*
|
||||
* @param[in] aOnMeshPrefixConfig The on-mesh prefix configuration to check.
|
||||
*
|
||||
* @retval TRUE The prefix is a valid OMR prefix.
|
||||
* @retval FALSE The prefix is not a valid OMR prefix.
|
||||
*/
|
||||
bool IsValidOmrPrefix(const NetworkData::OnMeshPrefixConfig &aOnMeshPrefixConfig);
|
||||
|
||||
/**
|
||||
* Checks whether a given prefix is a valid OMR prefix.
|
||||
*
|
||||
* @param[in] aPrefix The prefix to check.
|
||||
*
|
||||
* @retval TRUE The prefix is a valid OMR prefix.
|
||||
* @retval FALSE The prefix is not a valid OMR prefix.
|
||||
*/
|
||||
bool IsValidOmrPrefix(const Ip6::Prefix &aPrefix);
|
||||
|
||||
/**
|
||||
* Calculates the expiration time based on an update time and a lifetime, ensuring it is clamped to fit within the
|
||||
* `TimerMilli` range.
|
||||
*
|
||||
* The @p aLifetime` is provided in seconds. The calculated expiration time is clamped to the maximum interval
|
||||
* supported by `Timer` (`2^31` msec or approximately 24.8 days). This clamping ensures that the time calculation
|
||||
* fits within the `TimeMilli` range, preventing overflow issues for very long lifetimes.
|
||||
*
|
||||
* @param[in] aUpdateTime The base time from which the lifetime is calculated.
|
||||
* @param[in] aLifetime The lifetime in seconds.
|
||||
*
|
||||
* @returns The expiration time.
|
||||
*/
|
||||
TimeMilli CalculateClampedExpirationTime(TimeMilli aUpdateTime, uint32_t aLifetime);
|
||||
|
||||
} // namespace BorderRouter
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
#endif // BR_TYPES_HPP_
|
||||
@@ -747,7 +747,7 @@ void Dhcp6PdClient::CommitPdPrefix(const PdPrefix &aPdPrefix)
|
||||
|
||||
void Dhcp6PdClient::ReportPdPrefixToRoutingManager(void)
|
||||
{
|
||||
RoutingManager::Dhcp6PdPrefix prefix;
|
||||
Dhcp6PdPrefix prefix;
|
||||
|
||||
LogInfo("Delegated prefix:%s, adj:%s, T1:%lu, T2:%lu, prf:%lu, valid:%lu", mPdPrefix.mPrefix.ToString().AsCString(),
|
||||
mPdPrefix.mAdjustedPrefix.ToString().AsCString(), ToUlong(mPdPrefix.mT1), ToUlong(mPdPrefix.mT2),
|
||||
|
||||
@@ -578,12 +578,12 @@ exit:
|
||||
|
||||
void RoutingManager::SendRouterAdvertisement(RouterAdvTxMode aRaTxMode)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
RouterAdvert::TxMessage raMsg;
|
||||
RouterAdvert::Header header;
|
||||
Ip6::Address destAddress;
|
||||
InfraIf::Icmp6Packet packet;
|
||||
LinkLayerAddress linkAddr;
|
||||
Error error = kErrorNone;
|
||||
RouterAdvert::TxMessage raMsg;
|
||||
RouterAdvert::Header header;
|
||||
Ip6::Address destAddress;
|
||||
InfraIf::Icmp6Packet packet;
|
||||
InfraIf::LinkLayerAddress linkAddr;
|
||||
|
||||
LogInfo("Preparing RA");
|
||||
|
||||
@@ -652,35 +652,11 @@ exit:
|
||||
}
|
||||
}
|
||||
|
||||
TimeMilli RoutingManager::CalculateExpirationTime(TimeMilli aUpdateTime, uint32_t aLifetime)
|
||||
{
|
||||
// `aLifetime` is in unit of seconds. We clamp the lifetime to max
|
||||
// interval supported by `Timer` (`2^31` msec or ~24.8 days).
|
||||
// This ensures that the time calculation fits within `TimeMilli`
|
||||
// range.
|
||||
|
||||
static constexpr uint32_t kMaxLifetime = Time::MsecToSec(Timer::kMaxDelay);
|
||||
|
||||
return aUpdateTime + Time::SecToMsec(Min(aLifetime, kMaxLifetime));
|
||||
}
|
||||
|
||||
bool RoutingManager::IsValidBrUlaPrefix(const Ip6::Prefix &aBrUlaPrefix)
|
||||
{
|
||||
return aBrUlaPrefix.mLength == kBrUlaPrefixLength && aBrUlaPrefix.mPrefix.mFields.m8[0] == 0xfd;
|
||||
}
|
||||
|
||||
bool RoutingManager::IsValidOmrPrefix(const NetworkData::OnMeshPrefixConfig &aOnMeshPrefixConfig)
|
||||
{
|
||||
return IsValidOmrPrefix(aOnMeshPrefixConfig.GetPrefix()) && aOnMeshPrefixConfig.mOnMesh &&
|
||||
aOnMeshPrefixConfig.mSlaac && aOnMeshPrefixConfig.mStable;
|
||||
}
|
||||
|
||||
bool RoutingManager::IsValidOmrPrefix(const Ip6::Prefix &aPrefix)
|
||||
{
|
||||
// Accept ULA/GUA prefixes with 64-bit length.
|
||||
return (aPrefix.GetLength() == kOmrPrefixLength) && !aPrefix.IsLinkLocal() && !aPrefix.IsMulticast();
|
||||
}
|
||||
|
||||
void RoutingManager::HandleRsSenderFinished(TimeMilli aStartTime)
|
||||
{
|
||||
// This is a callback from `RsSender` and is invoked when it
|
||||
@@ -917,191 +893,6 @@ void RoutingManager::LogRecursiveDnsServerOption(const Ip6::Address &, uint32_t)
|
||||
|
||||
#endif // OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// LifetimedPrefix
|
||||
|
||||
TimeMilli RoutingManager::LifetimedPrefix::CalculateExpirationTime(uint32_t aLifetime) const
|
||||
{
|
||||
// `aLifetime` is in unit of seconds. This method ensures
|
||||
// that the time calculation fits with `TimeMilli` range.
|
||||
|
||||
return RoutingManager::CalculateExpirationTime(mLastUpdateTime, aLifetime);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// OnLinkPrefix
|
||||
|
||||
void RoutingManager::OnLinkPrefix::SetFrom(const PrefixInfoOption &aPio)
|
||||
{
|
||||
aPio.GetPrefix(mPrefix);
|
||||
mValidLifetime = aPio.GetValidLifetime();
|
||||
mPreferredLifetime = aPio.GetPreferredLifetime();
|
||||
mAutoAddrConfigFlag = aPio.IsAutoAddrConfigFlagSet();
|
||||
mDhcp6PdPreferredFlag = aPio.IsDhcp6PdPreferredFlagSet();
|
||||
mLastUpdateTime = TimerMilli::GetNow();
|
||||
}
|
||||
|
||||
void RoutingManager::OnLinkPrefix::SetFrom(const PrefixTableEntry &aPrefixTableEntry)
|
||||
{
|
||||
mPrefix = AsCoreType(&aPrefixTableEntry.mPrefix);
|
||||
mValidLifetime = aPrefixTableEntry.mValidLifetime;
|
||||
mPreferredLifetime = aPrefixTableEntry.mPreferredLifetime;
|
||||
mLastUpdateTime = TimerMilli::GetNow();
|
||||
}
|
||||
|
||||
bool RoutingManager::OnLinkPrefix::IsDeprecated(void) const { return GetDeprecationTime() <= TimerMilli::GetNow(); }
|
||||
|
||||
TimeMilli RoutingManager::OnLinkPrefix::GetDeprecationTime(void) const
|
||||
{
|
||||
return CalculateExpirationTime(mPreferredLifetime);
|
||||
}
|
||||
|
||||
TimeMilli RoutingManager::OnLinkPrefix::GetStaleTime(void) const
|
||||
{
|
||||
return CalculateExpirationTime(Min(kStaleTime, mPreferredLifetime));
|
||||
}
|
||||
|
||||
void RoutingManager::OnLinkPrefix::AdoptFlagsAndValidAndPreferredLifetimesFrom(const OnLinkPrefix &aPrefix)
|
||||
{
|
||||
constexpr uint32_t kTwoHoursInSeconds = 2 * 3600;
|
||||
|
||||
// Per RFC 4862 section 5.5.3.e:
|
||||
//
|
||||
// 1. If the received Valid Lifetime is greater than 2 hours or
|
||||
// greater than RemainingLifetime, set the valid lifetime of the
|
||||
// corresponding address to the advertised Valid Lifetime.
|
||||
// 2. If RemainingLifetime is less than or equal to 2 hours, ignore
|
||||
// the Prefix Information option with regards to the valid
|
||||
// lifetime, unless ...
|
||||
// 3. Otherwise, reset the valid lifetime of the corresponding
|
||||
// address to 2 hours.
|
||||
|
||||
if (aPrefix.mValidLifetime > kTwoHoursInSeconds || aPrefix.GetExpireTime() > GetExpireTime())
|
||||
{
|
||||
mValidLifetime = aPrefix.mValidLifetime;
|
||||
}
|
||||
else if (GetExpireTime() > TimerMilli::GetNow() + TimeMilli::SecToMsec(kTwoHoursInSeconds))
|
||||
{
|
||||
mValidLifetime = kTwoHoursInSeconds;
|
||||
}
|
||||
|
||||
mPreferredLifetime = aPrefix.GetPreferredLifetime();
|
||||
mAutoAddrConfigFlag = aPrefix.mAutoAddrConfigFlag;
|
||||
mDhcp6PdPreferredFlag = aPrefix.mDhcp6PdPreferredFlag;
|
||||
mLastUpdateTime = aPrefix.GetLastUpdateTime();
|
||||
}
|
||||
|
||||
void RoutingManager::OnLinkPrefix::CopyInfoTo(PrefixTableEntry &aEntry, TimeMilli aNow) const
|
||||
{
|
||||
aEntry.mPrefix = GetPrefix();
|
||||
aEntry.mIsOnLink = true;
|
||||
aEntry.mMsecSinceLastUpdate = aNow - GetLastUpdateTime();
|
||||
aEntry.mValidLifetime = GetValidLifetime();
|
||||
aEntry.mPreferredLifetime = GetPreferredLifetime();
|
||||
}
|
||||
|
||||
bool RoutingManager::OnLinkPrefix::IsFavoredOver(const Ip6::Prefix &aPrefix) const
|
||||
{
|
||||
bool isFavored = false;
|
||||
|
||||
// Validate that the `OnLinkPrefix` is eligible to be a favored
|
||||
// on-link prefix. It must have a valid length and either the
|
||||
// AutoAddrConfig (`A`) or Dhcp6PdPreferred (`P`) flag.
|
||||
// Additionally, it must not be deprecated and its preferred
|
||||
// lifetime must be at least `kFavoredMinPreferredLifetime`
|
||||
// (1800) seconds.
|
||||
|
||||
VerifyOrExit(mPrefix.GetLength() == kOnLinkPrefixLength);
|
||||
VerifyOrExit(mAutoAddrConfigFlag || mDhcp6PdPreferredFlag);
|
||||
VerifyOrExit(!IsDeprecated());
|
||||
VerifyOrExit(GetPreferredLifetime() >= kFavoredMinPreferredLifetime);
|
||||
|
||||
// Numerically smaller prefix is favored (unless `aPrefix` is empty).
|
||||
|
||||
VerifyOrExit(aPrefix.GetLength() != 0, isFavored = true);
|
||||
|
||||
isFavored = GetPrefix() < aPrefix;
|
||||
|
||||
exit:
|
||||
return isFavored;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// RoutePrefix
|
||||
|
||||
void RoutingManager::RoutePrefix::SetFrom(const RouteInfoOption &aRio)
|
||||
{
|
||||
aRio.GetPrefix(mPrefix);
|
||||
mValidLifetime = aRio.GetRouteLifetime();
|
||||
mRoutePreference = aRio.GetPreference();
|
||||
mLastUpdateTime = TimerMilli::GetNow();
|
||||
}
|
||||
|
||||
void RoutingManager::RoutePrefix::SetFrom(const RouterAdvert::Header &aRaHeader)
|
||||
{
|
||||
mPrefix.Clear();
|
||||
mValidLifetime = aRaHeader.GetRouterLifetime();
|
||||
mRoutePreference = aRaHeader.GetDefaultRouterPreference();
|
||||
mLastUpdateTime = TimerMilli::GetNow();
|
||||
}
|
||||
|
||||
TimeMilli RoutingManager::RoutePrefix::GetStaleTime(void) const
|
||||
{
|
||||
return CalculateExpirationTime(Min(kStaleTime, mValidLifetime));
|
||||
}
|
||||
|
||||
void RoutingManager::RoutePrefix::CopyInfoTo(PrefixTableEntry &aEntry, TimeMilli aNow) const
|
||||
{
|
||||
aEntry.mPrefix = GetPrefix();
|
||||
aEntry.mIsOnLink = false;
|
||||
aEntry.mMsecSinceLastUpdate = aNow - GetLastUpdateTime();
|
||||
aEntry.mValidLifetime = GetValidLifetime();
|
||||
aEntry.mPreferredLifetime = 0;
|
||||
aEntry.mRoutePreference = static_cast<otRoutePreference>(GetRoutePreference());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// RdnssAddress
|
||||
|
||||
void RoutingManager::RdnssAddress::SetFrom(const RecursiveDnsServerOption &aRdnss, uint16_t aAddressIndex)
|
||||
{
|
||||
mAddress = aRdnss.GetAddressAt(aAddressIndex);
|
||||
mLifetime = aRdnss.GetLifetime();
|
||||
mLastUpdateTime = TimerMilli::GetNow();
|
||||
}
|
||||
|
||||
TimeMilli RoutingManager::RdnssAddress::GetExpireTime(void) const
|
||||
{
|
||||
return RoutingManager::CalculateExpirationTime(mLastUpdateTime, mLifetime);
|
||||
}
|
||||
|
||||
void RoutingManager::RdnssAddress::CopyInfoTo(RdnssAddrEntry &aEntry, TimeMilli aNow) const
|
||||
{
|
||||
aEntry.mAddress = GetAddress();
|
||||
aEntry.mMsecSinceLastUpdate = aNow - GetLastUpdateTime();
|
||||
aEntry.mLifetime = GetLifetime();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// IfAddress
|
||||
|
||||
void RoutingManager::IfAddress::SetFrom(const Ip6::Address &aAddress, uint32_t aUptimeNow)
|
||||
{
|
||||
mAddress = aAddress;
|
||||
mLastUseUptime = aUptimeNow;
|
||||
}
|
||||
|
||||
bool RoutingManager::IfAddress::Matches(const InvalidChecker &aChecker) const
|
||||
{
|
||||
return !aChecker.Get<InfraIf>().HasAddress(mAddress);
|
||||
}
|
||||
|
||||
void RoutingManager::IfAddress::CopyInfoTo(IfAddrEntry &aEntry, uint32_t aUptimeNow) const
|
||||
{
|
||||
aEntry.mAddress = mAddress;
|
||||
aEntry.mSecSinceLastUse = aUptimeNow - mLastUseUptime;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// MultiAilDetector
|
||||
|
||||
@@ -1858,7 +1649,7 @@ void RoutingManager::RxRaTracker::Evaluate(void)
|
||||
interval = Min(interval, mLocalRaHeader.GetRouterLifetime());
|
||||
}
|
||||
|
||||
staleTime.UpdateIfEarlier(CalculateExpirationTime(mLocalRaHeaderUpdateTime, interval));
|
||||
staleTime.UpdateIfEarlier(CalculateClampedExpirationTime(mLocalRaHeaderUpdateTime, interval));
|
||||
}
|
||||
|
||||
mRouterTimer.FireAt(routerTimeoutTime);
|
||||
@@ -2027,10 +1818,10 @@ void RoutingManager::RxRaTracker::HandleRdnssAddrTimer(void) { Evaluate(); }
|
||||
|
||||
void RoutingManager::RxRaTracker::SendNeighborSolicitToRouter(const Router &aRouter)
|
||||
{
|
||||
InfraIf::Icmp6Packet packet;
|
||||
NeighborSolicitHeader nsHdr;
|
||||
TxMessage nsMsg;
|
||||
LinkLayerAddress linkAddr;
|
||||
InfraIf::Icmp6Packet packet;
|
||||
NeighborSolicitHeader nsHdr;
|
||||
TxMessage nsMsg;
|
||||
InfraIf::LinkLayerAddress linkAddr;
|
||||
|
||||
VerifyOrExit(!Get<RoutingManager>().mRsSender.IsInProgress());
|
||||
|
||||
@@ -2586,51 +2377,6 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// FavoredOmrPrefix
|
||||
|
||||
bool RoutingManager::FavoredOmrPrefix::IsInfrastructureDerived(void) const
|
||||
{
|
||||
// Indicate whether the OMR prefix is infrastructure-derived which
|
||||
// can be identified as a valid OMR prefix with preference of
|
||||
// medium or higher.
|
||||
|
||||
return !IsEmpty() && (mPreference >= NetworkData::kRoutePreferenceMedium);
|
||||
}
|
||||
|
||||
void RoutingManager::FavoredOmrPrefix::SetFrom(const NetworkData::OnMeshPrefixConfig &aOnMeshPrefixConfig)
|
||||
{
|
||||
mPrefix = aOnMeshPrefixConfig.GetPrefix();
|
||||
mPreference = aOnMeshPrefixConfig.GetPreference();
|
||||
mIsDomainPrefix = aOnMeshPrefixConfig.mDp;
|
||||
}
|
||||
|
||||
void RoutingManager::FavoredOmrPrefix::SetFrom(const OmrPrefix &aOmrPrefix)
|
||||
{
|
||||
mPrefix = aOmrPrefix.GetPrefix();
|
||||
mPreference = aOmrPrefix.GetPreference();
|
||||
mIsDomainPrefix = aOmrPrefix.IsDomainPrefix();
|
||||
}
|
||||
|
||||
bool RoutingManager::FavoredOmrPrefix::IsFavoredOver(const NetworkData::OnMeshPrefixConfig &aOmrPrefixConfig) const
|
||||
{
|
||||
// This method determines whether this OMR prefix is favored
|
||||
// over another prefix. A prefix with higher preference is
|
||||
// favored. If the preference is the same, then the smaller
|
||||
// prefix (in the sense defined by `Ip6::Prefix`) is favored.
|
||||
|
||||
bool isFavored = (mPreference > aOmrPrefixConfig.GetPreference());
|
||||
|
||||
OT_ASSERT(IsValidOmrPrefix(aOmrPrefixConfig));
|
||||
|
||||
if (mPreference == aOmrPrefixConfig.GetPreference())
|
||||
{
|
||||
isFavored = (mPrefix < aOmrPrefixConfig.GetPrefix());
|
||||
}
|
||||
|
||||
return isFavored;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// OmrPrefixManager
|
||||
|
||||
@@ -2705,8 +2451,7 @@ Error RoutingManager::OmrPrefixManager::SetConfig(OmrConfig aConfig,
|
||||
{
|
||||
VerifyOrExit((aPrefix != nullptr) && IsValidOmrPrefix(*aPrefix), error = kErrorInvalidArgs);
|
||||
|
||||
customPrefix.mPrefix = *aPrefix;
|
||||
customPrefix.mPreference = aPreference;
|
||||
customPrefix.SetPrefix(*aPrefix, aPreference);
|
||||
}
|
||||
|
||||
VerifyOrExit((aConfig != mConfig) || (customPrefix != mCustomPrefix));
|
||||
@@ -2786,9 +2531,8 @@ void RoutingManager::OmrPrefixManager::UpdateLocalPrefix(void)
|
||||
if (mLocalPrefix.GetPrefix() != Get<RoutingManager>().mPdPrefixManager.GetPrefix())
|
||||
{
|
||||
RemoveLocalFromNetData();
|
||||
mLocalPrefix.mPrefix = Get<RoutingManager>().mPdPrefixManager.GetPrefix();
|
||||
mLocalPrefix.mPreference = PdPrefixManager::kPdRoutePreference;
|
||||
mLocalPrefix.mIsDomainPrefix = false;
|
||||
mLocalPrefix.SetPrefix(Get<RoutingManager>().mPdPrefixManager.GetPrefix(),
|
||||
PdPrefixManager::kPdRoutePreference);
|
||||
LogInfo("Setting local OMR prefix to PD prefix: %s", mLocalPrefix.GetPrefix().ToString().AsCString());
|
||||
}
|
||||
}
|
||||
@@ -2797,9 +2541,7 @@ void RoutingManager::OmrPrefixManager::UpdateLocalPrefix(void)
|
||||
if (mLocalPrefix.GetPrefix() != mGeneratedPrefix)
|
||||
{
|
||||
RemoveLocalFromNetData();
|
||||
mLocalPrefix.mPrefix = mGeneratedPrefix;
|
||||
mLocalPrefix.mPreference = RoutePreference::kRoutePreferenceLow;
|
||||
mLocalPrefix.mIsDomainPrefix = false;
|
||||
mLocalPrefix.SetPrefix(mGeneratedPrefix, RoutePreference::kRoutePreferenceLow);
|
||||
LogInfo("Setting local OMR prefix to generated prefix: %s",
|
||||
mLocalPrefix.GetPrefix().ToString().AsCString());
|
||||
}
|
||||
@@ -4446,12 +4188,12 @@ void RoutingManager::RsSender::Stop(void) { mTimer.Stop(); }
|
||||
|
||||
Error RoutingManager::RsSender::SendRs(void)
|
||||
{
|
||||
Ip6::Address destAddress;
|
||||
RouterSolicitHeader rsHdr;
|
||||
TxMessage rsMsg;
|
||||
LinkLayerAddress linkAddr;
|
||||
InfraIf::Icmp6Packet packet;
|
||||
Error error;
|
||||
Ip6::Address destAddress;
|
||||
RouterSolicitHeader rsHdr;
|
||||
TxMessage rsMsg;
|
||||
InfraIf::LinkLayerAddress linkAddr;
|
||||
InfraIf::Icmp6Packet packet;
|
||||
Error error;
|
||||
|
||||
SuccessOrExit(error = rsMsg.Append(rsHdr));
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
#include <openthread/platform/border_routing.h>
|
||||
|
||||
#include "border_router/br_tracker.hpp"
|
||||
#include "border_router/br_types.hpp"
|
||||
#include "border_router/infra_if.hpp"
|
||||
#include "common/array.hpp"
|
||||
#include "common/callback.hpp"
|
||||
@@ -100,19 +101,6 @@ class RoutingManager : public InstanceLocator
|
||||
friend class NetDataBrTracker;
|
||||
|
||||
public:
|
||||
typedef NetworkData::RoutePreference RoutePreference; ///< Route preference (high, medium, low).
|
||||
typedef otBorderRoutingPrefixTableIterator PrefixTableIterator; ///< Prefix Table Iterator.
|
||||
typedef otBorderRoutingPrefixTableEntry PrefixTableEntry; ///< Prefix Table Entry.
|
||||
typedef otBorderRoutingRouterEntry RouterEntry; ///< Router Entry.
|
||||
typedef otBorderRoutingRdnssAddrEntry RdnssAddrEntry; ///< RDNSS Address Entry.
|
||||
typedef otBorderRoutingRdnssAddrCallback RdnssAddrCallback; ///< RDNS Address changed callback.
|
||||
typedef otBorderRoutingIfAddrEntry IfAddrEntry; ///< Infra-if IPv6 Address Entry.
|
||||
typedef otBorderRoutingPeerBorderRouterEntry PeerBrEntry; ///< Peer Border Router Entry.
|
||||
typedef otBorderRoutingPrefixTableEntry Dhcp6PdPrefix; ///< DHCPv6 PD prefix.
|
||||
typedef otPdProcessedRaInfo Dhcp6PdCounters; ///< DHCPv6 PD counters.
|
||||
typedef otBorderRoutingRequestDhcp6PdCallback Dhcp6PdCallback; ///< DHCPv6 PD callback.
|
||||
typedef otBorderRoutingMultiAilCallback MultiAilCallback; ///< Multi AIL detection callback.
|
||||
|
||||
/**
|
||||
* This constant specifies the maximum number of route prefixes that may be published by `RoutingManager`
|
||||
* in Thread Network Data.
|
||||
@@ -466,26 +454,6 @@ public:
|
||||
*/
|
||||
void HandleInfraIfStateChanged(void) { EvaluateState(); }
|
||||
|
||||
/**
|
||||
* Checks whether the on-mesh prefix configuration is a valid OMR prefix.
|
||||
*
|
||||
* @param[in] aOnMeshPrefixConfig The on-mesh prefix configuration to check.
|
||||
*
|
||||
* @retval TRUE The prefix is a valid OMR prefix.
|
||||
* @retval FALSE The prefix is not a valid OMR prefix.
|
||||
*/
|
||||
static bool IsValidOmrPrefix(const NetworkData::OnMeshPrefixConfig &aOnMeshPrefixConfig);
|
||||
|
||||
/**
|
||||
* Checks whether a given prefix is a valid OMR prefix.
|
||||
*
|
||||
* @param[in] aPrefix The prefix to check.
|
||||
*
|
||||
* @retval TRUE The prefix is a valid OMR prefix.
|
||||
* @retval FALSE The prefix is not a valid OMR prefix.
|
||||
*/
|
||||
static bool IsValidOmrPrefix(const Ip6::Prefix &aPrefix);
|
||||
|
||||
/**
|
||||
* Initializes a `PrefixTableIterator`.
|
||||
*
|
||||
@@ -715,10 +683,9 @@ private:
|
||||
static constexpr uint8_t kMaxOnMeshPrefixes = OPENTHREAD_CONFIG_BORDER_ROUTING_MAX_ON_MESH_PREFIXES;
|
||||
|
||||
// Prefix length in bits.
|
||||
static constexpr uint8_t kOmrPrefixLength = 64;
|
||||
static constexpr uint8_t kOnLinkPrefixLength = 64;
|
||||
static constexpr uint8_t kBrUlaPrefixLength = 48;
|
||||
static constexpr uint8_t kNat64PrefixLength = 96;
|
||||
static constexpr uint8_t kOmrPrefixLength = OmrPrefix::kPrefixLength;
|
||||
static constexpr uint8_t kBrUlaPrefixLength = 48;
|
||||
static constexpr uint8_t kNat64PrefixLength = 96;
|
||||
|
||||
// Subnet IDs for OMR and NAT64 prefixes.
|
||||
static constexpr uint16_t kOmrPrefixSubnetId = 1;
|
||||
@@ -729,17 +696,6 @@ private:
|
||||
static constexpr uint32_t kDefaultOnLinkPrefixLifetime = 1800;
|
||||
static constexpr uint32_t kDefaultNat64PrefixLifetime = 300;
|
||||
|
||||
// The entry stale time in seconds.
|
||||
//
|
||||
// The amount of time that can pass after the last time an RA from
|
||||
// a particular router has been received advertising an on-link
|
||||
// or route prefix before we assume the prefix entry is stale.
|
||||
//
|
||||
// If multiple routers advertise the same on-link or route prefix,
|
||||
// the stale time for the prefix is determined by the latest
|
||||
// stale time among all corresponding entries. Stale time
|
||||
// expiration triggers tx of Router Solicitation (RS) messages
|
||||
|
||||
static constexpr uint32_t kStaleTime = 600; // 10 minutes.
|
||||
|
||||
// RA transmission constants (in milliseconds). Initially, three
|
||||
@@ -760,20 +716,8 @@ private:
|
||||
static constexpr uint32_t kEvaluationInterval = Time::kOneSecondInMsec * 3;
|
||||
static constexpr uint16_t kEvaluationJitter = Time::kOneSecondInMsec * 1;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Typedefs
|
||||
|
||||
using Option = Ip6::Nd::Option;
|
||||
using PrefixInfoOption = Ip6::Nd::PrefixInfoOption;
|
||||
using RouteInfoOption = Ip6::Nd::RouteInfoOption;
|
||||
using RaFlagsExtOption = Ip6::Nd::RaFlagsExtOption;
|
||||
using RecursiveDnsServerOption = Ip6::Nd::RecursiveDnsServerOption;
|
||||
using RouterAdvert = Ip6::Nd::RouterAdvert;
|
||||
using NeighborAdvertMessage = Ip6::Nd::NeighborAdvertMessage;
|
||||
using TxMessage = Ip6::Nd::TxMessage;
|
||||
using NeighborSolicitHeader = Ip6::Nd::NeighborSolicitHeader;
|
||||
using RouterSolicitHeader = Ip6::Nd::RouterSolicitHeader;
|
||||
using LinkLayerAddress = InfraIf::LinkLayerAddress;
|
||||
typedef Ip6::Nd::Option Option;
|
||||
typedef Ip6::Nd::TxMessage TxMessage;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Enumerations
|
||||
@@ -802,130 +746,6 @@ private:
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Nested types
|
||||
|
||||
class LifetimedPrefix
|
||||
{
|
||||
// Represents an IPv6 prefix with its valid lifetime. Used as
|
||||
// base class for `OnLinkPrefix` or `RoutePrefix`.
|
||||
|
||||
public:
|
||||
const Ip6::Prefix &GetPrefix(void) const { return mPrefix; }
|
||||
Ip6::Prefix &GetPrefix(void) { return mPrefix; }
|
||||
const TimeMilli &GetLastUpdateTime(void) const { return mLastUpdateTime; }
|
||||
uint32_t GetValidLifetime(void) const { return mValidLifetime; }
|
||||
TimeMilli GetExpireTime(void) const { return CalculateExpirationTime(mValidLifetime); }
|
||||
|
||||
bool Matches(const Ip6::Prefix &aPrefix) const { return (mPrefix == aPrefix); }
|
||||
bool Matches(const ExpirationChecker &aChecker) const { return aChecker.IsExpired(GetExpireTime()); }
|
||||
|
||||
void SetStaleTimeCalculated(bool aFlag) { mStaleTimeCalculated = aFlag; }
|
||||
bool IsStaleTimeCalculated(void) const { return mStaleTimeCalculated; }
|
||||
|
||||
void SetDisregardFlag(bool aFlag) { mDisregard = aFlag; }
|
||||
bool ShouldDisregard(void) const { return mDisregard; }
|
||||
|
||||
protected:
|
||||
LifetimedPrefix(void) = default;
|
||||
|
||||
TimeMilli CalculateExpirationTime(uint32_t aLifetime) const;
|
||||
|
||||
Ip6::Prefix mPrefix;
|
||||
bool mDisregard : 1;
|
||||
bool mStaleTimeCalculated : 1;
|
||||
uint32_t mValidLifetime;
|
||||
TimeMilli mLastUpdateTime;
|
||||
};
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
class OnLinkPrefix : public LifetimedPrefix, public Clearable<OnLinkPrefix>
|
||||
{
|
||||
public:
|
||||
void SetFrom(const PrefixInfoOption &aPio);
|
||||
void SetFrom(const PrefixTableEntry &aPrefixTableEntry);
|
||||
uint32_t GetPreferredLifetime(void) const { return mPreferredLifetime; }
|
||||
void ClearPreferredLifetime(void) { mPreferredLifetime = 0; }
|
||||
bool IsDeprecated(void) const;
|
||||
TimeMilli GetDeprecationTime(void) const;
|
||||
TimeMilli GetStaleTime(void) const;
|
||||
void AdoptFlagsAndValidAndPreferredLifetimesFrom(const OnLinkPrefix &aPrefix);
|
||||
void CopyInfoTo(PrefixTableEntry &aEntry, TimeMilli aNow) const;
|
||||
bool IsFavoredOver(const Ip6::Prefix &aPrefix) const;
|
||||
|
||||
private:
|
||||
static constexpr uint32_t kFavoredMinPreferredLifetime = 1800; // In sec.
|
||||
|
||||
uint32_t mPreferredLifetime;
|
||||
bool mAutoAddrConfigFlag : 1;
|
||||
bool mDhcp6PdPreferredFlag : 1;
|
||||
};
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
class RoutePrefix : public LifetimedPrefix, public Clearable<RoutePrefix>
|
||||
{
|
||||
public:
|
||||
void SetFrom(const RouteInfoOption &aRio);
|
||||
void SetFrom(const RouterAdvert::Header &aRaHeader);
|
||||
void ClearValidLifetime(void) { mValidLifetime = 0; }
|
||||
TimeMilli GetStaleTime(void) const;
|
||||
RoutePreference GetRoutePreference(void) const { return mRoutePreference; }
|
||||
void CopyInfoTo(PrefixTableEntry &aEntry, TimeMilli aNow) const;
|
||||
|
||||
private:
|
||||
RoutePreference mRoutePreference;
|
||||
};
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
class RdnssAddress
|
||||
{
|
||||
public:
|
||||
void SetFrom(const RecursiveDnsServerOption &aRdnss, uint16_t aAddressIndex);
|
||||
const Ip6::Address &GetAddress(void) const { return mAddress; }
|
||||
const TimeMilli &GetLastUpdateTime(void) const { return mLastUpdateTime; }
|
||||
uint32_t GetLifetime(void) const { return mLifetime; }
|
||||
TimeMilli GetExpireTime(void) const;
|
||||
void ClearLifetime(void) { mLifetime = 0; }
|
||||
void CopyInfoTo(RdnssAddrEntry &aEntry, TimeMilli aNow) const;
|
||||
|
||||
bool Matches(const Ip6::Address &aAddress) const { return (mAddress == aAddress); }
|
||||
bool Matches(const ExpirationChecker &aChecker) const { return aChecker.IsExpired(GetExpireTime()); }
|
||||
|
||||
private:
|
||||
Ip6::Address mAddress;
|
||||
uint32_t mLifetime;
|
||||
TimeMilli mLastUpdateTime;
|
||||
};
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
class IfAddress // An if-address used by this BR itself (e.g., sending RA).
|
||||
{
|
||||
public:
|
||||
struct InvalidChecker : public InstanceLocator
|
||||
{
|
||||
// Used in `Matches()` to check if address is invalid `!Get<InfraIf>().HasAddress(mAddress)`.
|
||||
|
||||
explicit InvalidChecker(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
void SetFrom(const Ip6::Address &aAddress, uint32_t aUptimeNow);
|
||||
bool Matches(const Ip6::Address &aAddress) const { return (mAddress == aAddress); }
|
||||
bool Matches(const InvalidChecker &aChecker) const;
|
||||
void CopyInfoTo(IfAddrEntry &aEntry, uint32_t aUptimeNow) const;
|
||||
|
||||
private:
|
||||
Ip6::Address mAddress;
|
||||
uint32_t mLastUseUptime;
|
||||
};
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_MULTI_AIL_DETECTION_ENABLE
|
||||
|
||||
void HandleMultiAilDetectorTimer(void) { mMultiAilDetector.HandleTimer(); }
|
||||
@@ -1297,43 +1117,6 @@ private:
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
class OmrPrefixManager;
|
||||
|
||||
class OmrPrefix : public Clearable<OmrPrefix>, public Equatable<OmrPrefix>
|
||||
{
|
||||
friend class OmrPrefixManager;
|
||||
|
||||
public:
|
||||
OmrPrefix(void) { Clear(); }
|
||||
|
||||
bool IsEmpty(void) const { return (mPrefix.GetLength() == 0); }
|
||||
const Ip6::Prefix &GetPrefix(void) const { return mPrefix; }
|
||||
RoutePreference GetPreference(void) const { return mPreference; }
|
||||
bool IsDomainPrefix(void) const { return mIsDomainPrefix; }
|
||||
|
||||
protected:
|
||||
Ip6::Prefix mPrefix;
|
||||
RoutePreference mPreference;
|
||||
bool mIsDomainPrefix;
|
||||
};
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
class FavoredOmrPrefix : public OmrPrefix
|
||||
{
|
||||
friend class OmrPrefixManager;
|
||||
|
||||
public:
|
||||
bool IsInfrastructureDerived(void) const;
|
||||
|
||||
private:
|
||||
void SetFrom(const NetworkData::OnMeshPrefixConfig &aOnMeshPrefixConfig);
|
||||
void SetFrom(const OmrPrefix &aOmrPrefix);
|
||||
bool IsFavoredOver(const NetworkData::OnMeshPrefixConfig &aOmrPrefixConfig) const;
|
||||
};
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
class OmrPrefixManager : public InstanceLocator
|
||||
{
|
||||
public:
|
||||
@@ -1409,6 +1192,8 @@ private:
|
||||
#endif
|
||||
|
||||
private:
|
||||
static constexpr uint8_t kOnLinkPrefixLength = 64;
|
||||
|
||||
enum State : uint8_t // State of `mLocalPrefix`
|
||||
{
|
||||
kIdle,
|
||||
@@ -1789,8 +1574,6 @@ private:
|
||||
void HandleRaPrefixTableChanged(void);
|
||||
void HandleLocalOnLinkPrefixChanged(void);
|
||||
|
||||
static TimeMilli CalculateExpirationTime(TimeMilli aUpdateTime, uint32_t aLifetime);
|
||||
|
||||
static bool IsValidBrUlaPrefix(const Ip6::Prefix &aBrUlaPrefix);
|
||||
|
||||
static void LogRaHeader(const RouterAdvert::Header &aRaHeader);
|
||||
@@ -1858,29 +1641,25 @@ private:
|
||||
// Template specializations and declarations
|
||||
|
||||
template <>
|
||||
inline RoutingManager::RxRaTracker::Entry<RoutingManager::OnLinkPrefix> &RoutingManager::RxRaTracker::SharedEntry::
|
||||
GetEntry(void)
|
||||
inline RoutingManager::RxRaTracker::Entry<OnLinkPrefix> &RoutingManager::RxRaTracker::SharedEntry::GetEntry(void)
|
||||
{
|
||||
return mOnLinkEntry;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline RoutingManager::RxRaTracker::Entry<RoutingManager::RoutePrefix> &RoutingManager::RxRaTracker::SharedEntry::
|
||||
GetEntry(void)
|
||||
inline RoutingManager::RxRaTracker::Entry<RoutePrefix> &RoutingManager::RxRaTracker::SharedEntry::GetEntry(void)
|
||||
{
|
||||
return mRouteEntry;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline RoutingManager::RxRaTracker::Entry<RoutingManager::RdnssAddress> &RoutingManager::RxRaTracker::SharedEntry::
|
||||
GetEntry(void)
|
||||
inline RoutingManager::RxRaTracker::Entry<RdnssAddress> &RoutingManager::RxRaTracker::SharedEntry::GetEntry(void)
|
||||
{
|
||||
return mRdnssAddrEntry;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline RoutingManager::RxRaTracker::Entry<RoutingManager::IfAddress> &RoutingManager::RxRaTracker::SharedEntry::
|
||||
GetEntry(void)
|
||||
inline RoutingManager::RxRaTracker::Entry<IfAddress> &RoutingManager::RxRaTracker::SharedEntry::GetEntry(void)
|
||||
{
|
||||
return mIfAddrEntry;
|
||||
}
|
||||
|
||||
@@ -583,8 +583,8 @@ Error BorderAgent::PrepareServiceTxtData(uint8_t *aBuffer, uint16_t aBufferSize,
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
{
|
||||
Ip6::Prefix prefix;
|
||||
BorderRouter::RoutingManager::RoutePreference preference;
|
||||
Ip6::Prefix prefix;
|
||||
BorderRouter::RoutePreference preference;
|
||||
|
||||
if (Get<BorderRouter::RoutingManager>().GetFavoredOmrPrefix(prefix, preference) == kErrorNone &&
|
||||
prefix.GetLength() > 0)
|
||||
|
||||
@@ -682,7 +682,7 @@ bool Leader::ContainsOmrPrefix(const Ip6::Prefix &aPrefix) const
|
||||
const PrefixTlv *prefixTlv;
|
||||
const BorderRouterTlv *brSubTlv;
|
||||
|
||||
VerifyOrExit(BorderRouter::RoutingManager::IsValidOmrPrefix(aPrefix));
|
||||
VerifyOrExit(BorderRouter::IsValidOmrPrefix(aPrefix));
|
||||
|
||||
prefixTlv = FindPrefix(aPrefix);
|
||||
VerifyOrExit(prefixTlv != nullptr);
|
||||
@@ -697,7 +697,7 @@ bool Leader::ContainsOmrPrefix(const Ip6::Prefix &aPrefix) const
|
||||
|
||||
config.SetFrom(*prefixTlv, *brSubTlv, *entry);
|
||||
|
||||
if (BorderRouter::RoutingManager::IsValidOmrPrefix(config))
|
||||
if (BorderRouter::IsValidOmrPrefix(config))
|
||||
{
|
||||
ExitNow(contains = true);
|
||||
}
|
||||
|
||||
@@ -582,9 +582,7 @@ exit:
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
void Local::RecordFavoredOmrPrefix(const Ip6::Prefix &aPrefix,
|
||||
BorderRouter::RoutingManager::RoutePreference aPreference,
|
||||
bool aIsLocal)
|
||||
void Local::RecordFavoredOmrPrefix(const Ip6::Prefix &aPrefix, BorderRouter::RoutePreference aPreference, bool aIsLocal)
|
||||
{
|
||||
FavoredOmrPrefix *entry = mFavoredOmrPrefixHistory.AddNewEntry();
|
||||
|
||||
|
||||
@@ -532,10 +532,8 @@ private:
|
||||
void RecordEpskcEvent(EpskcEvent aEvent);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
void RecordFavoredOmrPrefix(const Ip6::Prefix &aPrefix,
|
||||
BorderRouter::RoutingManager::RoutePreference aPreference,
|
||||
bool aIsLocal);
|
||||
void RecordFavoredOnLinkPrefix(const Ip6::Prefix &aPrefix, bool aIsLocal);
|
||||
void RecordFavoredOmrPrefix(const Ip6::Prefix &aPrefix, BorderRouter::RoutePreference aPreference, bool aIsLocal);
|
||||
void RecordFavoredOnLinkPrefix(const Ip6::Prefix &aPrefix, bool aIsLocal);
|
||||
AilRouter *RecordAilRouterEvent(void);
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
|
||||
void RecordDhcp6Pd(BorderRouter::RoutingManager::Dhcp6PdState aState, const Ip6::Prefix &aPrefix);
|
||||
|
||||
@@ -1073,10 +1073,10 @@ void VerifyPrefixTable(const OnLinkPrefix *aOnLinkPrefixes,
|
||||
const RoutePrefix *aRoutePrefixes,
|
||||
uint16_t aNumRoutePrefixes)
|
||||
{
|
||||
BorderRouter::RoutingManager::PrefixTableIterator iter;
|
||||
BorderRouter::RoutingManager::PrefixTableEntry entry;
|
||||
uint16_t onLinkPrefixCount = 0;
|
||||
uint16_t routePrefixCount = 0;
|
||||
BorderRouter::PrefixTableIterator iter;
|
||||
BorderRouter::PrefixTableEntry entry;
|
||||
uint16_t onLinkPrefixCount = 0;
|
||||
uint16_t routePrefixCount = 0;
|
||||
|
||||
Log("VerifyPrefixTable()");
|
||||
|
||||
@@ -1162,9 +1162,9 @@ template <uint16_t kNumAddrs> void VerifyRdnssAddressTable(const RdnssAddress (&
|
||||
|
||||
void VerifyRdnssAddressTable(const RdnssAddress *aRdnssAddresses, uint16_t aNumAddrs)
|
||||
{
|
||||
BorderRouter::RoutingManager::PrefixTableIterator iter;
|
||||
BorderRouter::RoutingManager::RdnssAddrEntry entry;
|
||||
uint16_t count = 0;
|
||||
BorderRouter::PrefixTableIterator iter;
|
||||
BorderRouter::RdnssAddrEntry entry;
|
||||
uint16_t count = 0;
|
||||
|
||||
Log("VerifyRdnssAddressTable()");
|
||||
|
||||
@@ -1229,9 +1229,9 @@ template <uint16_t kNumRouters> void VerifyDiscoveredRouters(const InfraRouter (
|
||||
|
||||
void VerifyDiscoveredRouters(const InfraRouter *aRouters, uint16_t aNumRouters)
|
||||
{
|
||||
BorderRouter::RoutingManager::PrefixTableIterator iter;
|
||||
BorderRouter::RoutingManager::RouterEntry entry;
|
||||
uint16_t count = 0;
|
||||
BorderRouter::PrefixTableIterator iter;
|
||||
BorderRouter::RouterEntry entry;
|
||||
uint16_t count = 0;
|
||||
|
||||
Log("VerifyDiscoveredRouters()");
|
||||
|
||||
@@ -4595,7 +4595,7 @@ void TestNat64PrefixSelection(void)
|
||||
|
||||
void VerifyPdOmrPrefix(const Ip6::Prefix &aPrefix)
|
||||
{
|
||||
BorderRouter::RoutingManager::Dhcp6PdPrefix pdPrefix;
|
||||
BorderRouter::Dhcp6PdPrefix pdPrefix;
|
||||
|
||||
SuccessOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetDhcp6PdOmrPrefix(pdPrefix));
|
||||
VerifyOrQuit(AsCoreType(&pdPrefix.mPrefix) == aPrefix);
|
||||
@@ -4603,7 +4603,7 @@ void VerifyPdOmrPrefix(const Ip6::Prefix &aPrefix)
|
||||
|
||||
void VerifyNoPdOmrPrefix(void)
|
||||
{
|
||||
BorderRouter::RoutingManager::Dhcp6PdPrefix pdPrefix;
|
||||
BorderRouter::Dhcp6PdPrefix pdPrefix;
|
||||
|
||||
VerifyOrQuit(sInstance->Get<BorderRouter::RoutingManager>().GetDhcp6PdOmrPrefix(pdPrefix) == kErrorNotFound);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user