mirror of
https://github.com/espressif/openthread.git
synced 2026-08-10 04:37:47 +00:00
[routing-manager] construct RA dynamically using Heap::Array (#9924)
This commit enhances flexibility in Router Advertisement (RA) message construction by employing `Heap::Array`. This eliminates the need for a pre-allocated buffer and removes the constraint of predetermining the maximum RA message size. Additionally, introduces `TxMessage` and `RxMessage` nested classes within `Ip6::Nd::RouterAdvert` for efficient handling of outgoing and incoming RA messages: - `TxMessage`: Facilitates appending elements to an RA message with dynamic buffer allocation. - `RxMessage`: Enables parsing and iterating over options within a received RA message.
This commit is contained in:
@@ -571,35 +571,24 @@ exit:
|
||||
|
||||
void RoutingManager::SendRouterAdvertisement(RouterAdvTxMode aRaTxMode)
|
||||
{
|
||||
// RA message max length is derived to accommodate:
|
||||
//
|
||||
// - The RA header.
|
||||
// - One RA Flags Extensions Option (with stub router flag).
|
||||
// - One PIO for current local on-link prefix.
|
||||
// - At most `kMaxOldPrefixes` for old deprecating on-link prefixes.
|
||||
// - At most 3 times `kMaxOnMeshPrefixes` RIO for on-mesh prefixes.
|
||||
// Factor three is used for RIOs to account for any new prefix
|
||||
// with older prefixes entries being deprecated and prefixes
|
||||
// being invalidated.
|
||||
|
||||
static constexpr uint16_t kMaxRaLength =
|
||||
sizeof(Ip6::Nd::RouterAdvertMessage::Header) + sizeof(Ip6::Nd::RaFlagsExtOption) +
|
||||
sizeof(Ip6::Nd::PrefixInfoOption) + sizeof(Ip6::Nd::PrefixInfoOption) * OnLinkPrefixManager::kMaxOldPrefixes +
|
||||
3 * kMaxOnMeshPrefixes * (sizeof(Ip6::Nd::RouteInfoOption) + sizeof(Ip6::Prefix));
|
||||
|
||||
uint8_t buffer[kMaxRaLength];
|
||||
Ip6::Nd::RouterAdvertMessage raMsg(mRaInfo.mHeader, buffer);
|
||||
Error error = kErrorNone;
|
||||
Ip6::Nd::RouterAdvert::TxMessage raMsg;
|
||||
Ip6::Nd::RouterAdvert::Header header;
|
||||
Ip6::Address destAddress;
|
||||
InfraIf::Icmp6Packet packet;
|
||||
|
||||
LogInfo("Preparing RA");
|
||||
|
||||
mDiscoveredPrefixTable.DetermineAndSetFlags(raMsg);
|
||||
header = mRaInfo.mHeader;
|
||||
mDiscoveredPrefixTable.DetermineAndSetFlags(header);
|
||||
|
||||
LogInfo("- RA Header - flags - M:%u O:%u", raMsg.GetHeader().IsManagedAddressConfigFlagSet(),
|
||||
raMsg.GetHeader().IsOtherConfigFlagSet());
|
||||
LogInfo("- RA Header - default route - lifetime:%u", raMsg.GetHeader().GetRouterLifetime());
|
||||
SuccessOrExit(error = raMsg.AppendHeader(header));
|
||||
|
||||
LogInfo("- RA Header - flags - M:%u O:%u", header.IsManagedAddressConfigFlagSet(), header.IsOtherConfigFlagSet());
|
||||
LogInfo("- RA Header - default route - lifetime:%u", header.GetRouterLifetime());
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_STUB_ROUTER_FLAG_IN_EMITTED_RA_ENABLE
|
||||
SuccessOrAssert(raMsg.AppendFlagsExtensionOption(/* aStubRouterFlag */ true));
|
||||
SuccessOrExit(error = raMsg.AppendFlagsExtensionOption(/* aStubRouterFlag */ true));
|
||||
LogInfo("- FlagsExt - StubRouter:1");
|
||||
#endif
|
||||
|
||||
@@ -607,45 +596,40 @@ void RoutingManager::SendRouterAdvertisement(RouterAdvTxMode aRaTxMode)
|
||||
// advertised or deprecated and for old prefix if is being
|
||||
// deprecated.
|
||||
|
||||
mOnLinkPrefixManager.AppendAsPiosTo(raMsg);
|
||||
SuccessOrExit(error = mOnLinkPrefixManager.AppendAsPiosTo(raMsg));
|
||||
|
||||
if (aRaTxMode == kInvalidateAllPrevPrefixes)
|
||||
{
|
||||
mRioAdvertiser.InvalidatPrevRios(raMsg);
|
||||
SuccessOrExit(error = mRioAdvertiser.InvalidatPrevRios(raMsg));
|
||||
}
|
||||
else
|
||||
{
|
||||
mRioAdvertiser.AppendRios(raMsg);
|
||||
SuccessOrExit(error = mRioAdvertiser.AppendRios(raMsg));
|
||||
}
|
||||
|
||||
if (raMsg.ContainsAnyOptions())
|
||||
VerifyOrExit(raMsg.ContainsAnyOptions());
|
||||
|
||||
++mRaInfo.mTxCount;
|
||||
|
||||
destAddress.SetToLinkLocalAllNodesMulticast();
|
||||
raMsg.GetAsPacket(packet);
|
||||
|
||||
SuccessOrExit(error = mInfraIf.Send(packet, destAddress));
|
||||
|
||||
mRaInfo.mLastTxTime = TimerMilli::GetNow();
|
||||
Get<Ip6::Ip6>().GetBorderRoutingCounters().mRaTxSuccess++;
|
||||
LogInfo("Sent RA on %s", mInfraIf.ToString().AsCString());
|
||||
DumpDebg("[BR-CERT] direction=send | type=RA |", packet.GetBytes(), packet.GetLength());
|
||||
|
||||
exit:
|
||||
if (error != kErrorNone)
|
||||
{
|
||||
Error error;
|
||||
Ip6::Address destAddress;
|
||||
|
||||
++mRaInfo.mTxCount;
|
||||
|
||||
destAddress.SetToLinkLocalAllNodesMulticast();
|
||||
|
||||
error = mInfraIf.Send(raMsg.GetAsPacket(), destAddress);
|
||||
|
||||
if (error == kErrorNone)
|
||||
{
|
||||
mRaInfo.mLastTxTime = TimerMilli::GetNow();
|
||||
Get<Ip6::Ip6>().GetBorderRoutingCounters().mRaTxSuccess++;
|
||||
LogInfo("Sent RA on %s", mInfraIf.ToString().AsCString());
|
||||
DumpDebg("[BR-CERT] direction=send | type=RA |", raMsg.GetAsPacket().GetBytes(),
|
||||
raMsg.GetAsPacket().GetLength());
|
||||
}
|
||||
else
|
||||
{
|
||||
Get<Ip6::Ip6>().GetBorderRoutingCounters().mRaTxFailure++;
|
||||
LogWarn("Failed to send RA on %s: %s", mInfraIf.ToString().AsCString(), ErrorToString(error));
|
||||
}
|
||||
Get<Ip6::Ip6>().GetBorderRoutingCounters().mRaTxFailure++;
|
||||
LogWarn("Failed to send RA on %s: %s", mInfraIf.ToString().AsCString(), ErrorToString(error));
|
||||
}
|
||||
}
|
||||
|
||||
bool RoutingManager::IsReceivedRouterAdvertFromManager(const Ip6::Nd::RouterAdvertMessage &aRaMessage) const
|
||||
bool RoutingManager::IsReceivedRouterAdvertFromManager(const Ip6::Nd::RouterAdvert::RxMessage &aRaMessage) const
|
||||
{
|
||||
// Determines whether or not a received RA message was prepared by
|
||||
// by `RoutingManager` itself.
|
||||
@@ -797,7 +781,7 @@ exit:
|
||||
|
||||
void RoutingManager::HandleRouterAdvertisement(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress)
|
||||
{
|
||||
Ip6::Nd::RouterAdvertMessage routerAdvMessage(aPacket);
|
||||
Ip6::Nd::RouterAdvert::RxMessage routerAdvMessage(aPacket);
|
||||
|
||||
OT_ASSERT(mIsRunning);
|
||||
|
||||
@@ -946,11 +930,11 @@ bool RoutingManager::NetworkDataContainsUlaRoute(void) const
|
||||
return contains;
|
||||
}
|
||||
|
||||
void RoutingManager::UpdateRouterAdvertHeader(const Ip6::Nd::RouterAdvertMessage *aRouterAdvertMessage)
|
||||
void RoutingManager::UpdateRouterAdvertHeader(const Ip6::Nd::RouterAdvert::RxMessage *aRouterAdvertMessage)
|
||||
{
|
||||
// Updates the `mRaInfo` from the given RA message.
|
||||
|
||||
Ip6::Nd::RouterAdvertMessage::Header oldHeader;
|
||||
Ip6::Nd::RouterAdvert::Header oldHeader;
|
||||
|
||||
if (aRouterAdvertMessage != nullptr)
|
||||
{
|
||||
@@ -1060,8 +1044,9 @@ RoutingManager::DiscoveredPrefixTable::DiscoveredPrefixTable(Instance &aInstance
|
||||
{
|
||||
}
|
||||
|
||||
void RoutingManager::DiscoveredPrefixTable::ProcessRouterAdvertMessage(const Ip6::Nd::RouterAdvertMessage &aRaMessage,
|
||||
const Ip6::Address &aSrcAddress)
|
||||
void RoutingManager::DiscoveredPrefixTable::ProcessRouterAdvertMessage(
|
||||
const Ip6::Nd::RouterAdvert::RxMessage &aRaMessage,
|
||||
const Ip6::Address &aSrcAddress)
|
||||
{
|
||||
// Process a received RA message and update the prefix table.
|
||||
|
||||
@@ -1120,8 +1105,8 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void RoutingManager::DiscoveredPrefixTable::ProcessRaHeader(const Ip6::Nd::RouterAdvertMessage::Header &aRaHeader,
|
||||
Router &aRouter)
|
||||
void RoutingManager::DiscoveredPrefixTable::ProcessRaHeader(const Ip6::Nd::RouterAdvert::Header &aRaHeader,
|
||||
Router &aRouter)
|
||||
{
|
||||
Entry *entry;
|
||||
Ip6::Prefix prefix;
|
||||
@@ -1660,10 +1645,10 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void RoutingManager::DiscoveredPrefixTable::DetermineAndSetFlags(Ip6::Nd::RouterAdvertMessage &aRaMessage) const
|
||||
void RoutingManager::DiscoveredPrefixTable::DetermineAndSetFlags(Ip6::Nd::RouterAdvert::Header &aHeader) const
|
||||
{
|
||||
// Determine the `M` and `O` flags to include in the RA message
|
||||
// header `aRaMessage` to be emitted.
|
||||
// header to be emitted.
|
||||
//
|
||||
// If any discovered router on infrastructure which is not itself a
|
||||
// stub router (e.g., another Thread BR) includes the `M` or `O`
|
||||
@@ -1686,12 +1671,12 @@ void RoutingManager::DiscoveredPrefixTable::DetermineAndSetFlags(Ip6::Nd::Router
|
||||
|
||||
if (router.mManagedAddressConfigFlag)
|
||||
{
|
||||
aRaMessage.GetHeader().SetManagedAddressConfigFlag();
|
||||
aHeader.SetManagedAddressConfigFlag();
|
||||
}
|
||||
|
||||
if (router.mOtherConfigFlag)
|
||||
{
|
||||
aRaMessage.GetHeader().SetOtherConfigFlag();
|
||||
aHeader.SetOtherConfigFlag();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1778,7 +1763,7 @@ void RoutingManager::DiscoveredPrefixTable::Iterator::Advance(AdvanceMode aMode)
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// DiscoveredPrefixTable::Entry
|
||||
|
||||
void RoutingManager::DiscoveredPrefixTable::Entry::SetFrom(const Ip6::Nd::RouterAdvertMessage::Header &aRaHeader)
|
||||
void RoutingManager::DiscoveredPrefixTable::Entry::SetFrom(const Ip6::Nd::RouterAdvert::Header &aRaHeader)
|
||||
{
|
||||
mPrefix.Clear();
|
||||
mType = kTypeRoute;
|
||||
@@ -2528,13 +2513,18 @@ bool RoutingManager::OnLinkPrefixManager::IsPublishingOrAdvertising(void) const
|
||||
return (GetState() == kPublishing) || (GetState() == kAdvertising);
|
||||
}
|
||||
|
||||
void RoutingManager::OnLinkPrefixManager::AppendAsPiosTo(Ip6::Nd::RouterAdvertMessage &aRaMessage)
|
||||
Error RoutingManager::OnLinkPrefixManager::AppendAsPiosTo(Ip6::Nd::RouterAdvert::TxMessage &aRaMessage)
|
||||
{
|
||||
AppendCurPrefix(aRaMessage);
|
||||
AppendOldPrefixes(aRaMessage);
|
||||
Error error;
|
||||
|
||||
SuccessOrExit(error = AppendCurPrefix(aRaMessage));
|
||||
error = AppendOldPrefixes(aRaMessage);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void RoutingManager::OnLinkPrefixManager::AppendCurPrefix(Ip6::Nd::RouterAdvertMessage &aRaMessage)
|
||||
Error RoutingManager::OnLinkPrefixManager::AppendCurPrefix(Ip6::Nd::RouterAdvert::TxMessage &aRaMessage)
|
||||
{
|
||||
// Append the local on-link prefix to the `aRaMessage` as a PIO
|
||||
// only if it is being advertised or deprecated.
|
||||
@@ -2543,6 +2533,7 @@ void RoutingManager::OnLinkPrefixManager::AppendCurPrefix(Ip6::Nd::RouterAdvertM
|
||||
// If in `kDeprecating` state, we include it as PIO with zero
|
||||
// preferred lifetime and the remaining valid lifetime.
|
||||
|
||||
Error error = kErrorNone;
|
||||
uint32_t validLifetime = kDefaultOnLinkPrefixLifetime;
|
||||
uint32_t preferredLifetime = kDefaultOnLinkPrefixLifetime;
|
||||
TimeMilli now = TimerMilli::GetNow();
|
||||
@@ -2564,17 +2555,18 @@ void RoutingManager::OnLinkPrefixManager::AppendCurPrefix(Ip6::Nd::RouterAdvertM
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
SuccessOrAssert(aRaMessage.AppendPrefixInfoOption(mLocalPrefix, validLifetime, preferredLifetime));
|
||||
SuccessOrExit(error = aRaMessage.AppendPrefixInfoOption(mLocalPrefix, validLifetime, preferredLifetime));
|
||||
|
||||
LogPrefixInfoOption(mLocalPrefix, validLifetime, preferredLifetime);
|
||||
|
||||
exit:
|
||||
return;
|
||||
return error;
|
||||
}
|
||||
|
||||
void RoutingManager::OnLinkPrefixManager::AppendOldPrefixes(Ip6::Nd::RouterAdvertMessage &aRaMessage)
|
||||
Error RoutingManager::OnLinkPrefixManager::AppendOldPrefixes(Ip6::Nd::RouterAdvert::TxMessage &aRaMessage)
|
||||
{
|
||||
TimeMilli now = TimerMilli::GetNow();
|
||||
Error error = kErrorNone;
|
||||
TimeMilli now = TimerMilli::GetNow();
|
||||
uint32_t validLifetime;
|
||||
|
||||
for (const OldPrefix &oldPrefix : mOldLocalPrefixes)
|
||||
@@ -2585,10 +2577,13 @@ void RoutingManager::OnLinkPrefixManager::AppendOldPrefixes(Ip6::Nd::RouterAdver
|
||||
}
|
||||
|
||||
validLifetime = TimeMilli::MsecToSec(oldPrefix.mExpireTime - now);
|
||||
SuccessOrAssert(aRaMessage.AppendPrefixInfoOption(oldPrefix.mPrefix, validLifetime, 0));
|
||||
SuccessOrExit(error = aRaMessage.AppendPrefixInfoOption(oldPrefix.mPrefix, validLifetime, 0));
|
||||
|
||||
LogPrefixInfoOption(oldPrefix.mPrefix, validLifetime, 0);
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void RoutingManager::OnLinkPrefixManager::HandleNetDataChange(void)
|
||||
@@ -2824,11 +2819,13 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void RoutingManager::RioAdvertiser::InvalidatPrevRios(Ip6::Nd::RouterAdvertMessage &aRaMessage)
|
||||
Error RoutingManager::RioAdvertiser::InvalidatPrevRios(Ip6::Nd::RouterAdvert::TxMessage &aRaMessage)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
for (const RioPrefix &prefix : mPrefixes)
|
||||
{
|
||||
AppendRio(prefix.mPrefix, /* aRouteLifetime */ 0, aRaMessage);
|
||||
SuccessOrExit(error = AppendRio(prefix.mPrefix, /* aRouteLifetime */ 0, aRaMessage));
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_USE_HEAP_ENABLE
|
||||
@@ -2837,10 +2834,14 @@ void RoutingManager::RioAdvertiser::InvalidatPrevRios(Ip6::Nd::RouterAdvertMessa
|
||||
|
||||
mPrefixes.Clear();
|
||||
mTimer.Stop();
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void RoutingManager::RioAdvertiser::AppendRios(Ip6::Nd::RouterAdvertMessage &aRaMessage)
|
||||
Error RoutingManager::RioAdvertiser::AppendRios(Ip6::Nd::RouterAdvert::TxMessage &aRaMessage)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
TimeMilli now = TimerMilli::GetNow();
|
||||
TimeMilli nextTime = now.GetDistantFuture();
|
||||
RioPrefixArray oldPrefixes;
|
||||
@@ -2928,7 +2929,7 @@ void RoutingManager::RioAdvertiser::AppendRios(Ip6::Nd::RouterAdvertMessage &aRa
|
||||
{
|
||||
if (now >= prefix.mExpirationTime)
|
||||
{
|
||||
AppendRio(prefix.mPrefix, /* aRouteLifetime */ 0, aRaMessage);
|
||||
SuccessOrExit(error = AppendRio(prefix.mPrefix, /* aRouteLifetime */ 0, aRaMessage));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -2941,7 +2942,7 @@ void RoutingManager::RioAdvertiser::AppendRios(Ip6::Nd::RouterAdvertMessage &aRa
|
||||
if (mPrefixes.PushBack(prefix) != kErrorNone)
|
||||
{
|
||||
LogWarn("Too many deprecating on-mesh prefixes, removing %s", prefix.mPrefix.ToString().AsCString());
|
||||
AppendRio(prefix.mPrefix, /* aRouteLifetime */ 0, aRaMessage);
|
||||
SuccessOrExit(error = AppendRio(prefix.mPrefix, /* aRouteLifetime */ 0, aRaMessage));
|
||||
}
|
||||
|
||||
nextTime = Min(nextTime, prefix.mExpirationTime);
|
||||
@@ -2958,21 +2959,29 @@ void RoutingManager::RioAdvertiser::AppendRios(Ip6::Nd::RouterAdvertMessage &aRa
|
||||
lifetime = TimeMilli::MsecToSec(prefix.mExpirationTime - now);
|
||||
}
|
||||
|
||||
AppendRio(prefix.mPrefix, lifetime, aRaMessage);
|
||||
SuccessOrExit(error = AppendRio(prefix.mPrefix, lifetime, aRaMessage));
|
||||
}
|
||||
|
||||
if (nextTime != now.GetDistantFuture())
|
||||
{
|
||||
mTimer.FireAtIfEarlier(nextTime);
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void RoutingManager::RioAdvertiser::AppendRio(const Ip6::Prefix &aPrefix,
|
||||
uint32_t aRouteLifetime,
|
||||
Ip6::Nd::RouterAdvertMessage &aRaMessage)
|
||||
Error RoutingManager::RioAdvertiser::AppendRio(const Ip6::Prefix &aPrefix,
|
||||
uint32_t aRouteLifetime,
|
||||
Ip6::Nd::RouterAdvert::TxMessage &aRaMessage)
|
||||
{
|
||||
SuccessOrAssert(aRaMessage.AppendRouteInfoOption(aPrefix, aRouteLifetime, mPreference));
|
||||
Error error;
|
||||
|
||||
SuccessOrExit(error = aRaMessage.AppendRouteInfoOption(aPrefix, aRouteLifetime, mPreference));
|
||||
LogRouteInfoOption(aPrefix, aRouteLifetime, mPreference);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void RoutingManager::RioAdvertiser::HandleTimer(void)
|
||||
@@ -3655,12 +3664,12 @@ exit:
|
||||
|
||||
void RoutingManager::PdPrefixManager::ProcessPlatformGeneratedRa(const uint8_t *aRouterAdvert, const uint16_t aLength)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Ip6::Nd::RouterAdvertMessage::Icmp6Packet packet;
|
||||
Error error = kErrorNone;
|
||||
Ip6::Nd::RouterAdvert::Icmp6Packet packet;
|
||||
|
||||
VerifyOrExit(IsRunning(), LogWarn("Ignore platform generated RA since PD is disabled or not running."));
|
||||
packet.Init(aRouterAdvert, aLength);
|
||||
error = Process(Ip6::Nd::RouterAdvertMessage(packet));
|
||||
error = Process(Ip6::Nd::RouterAdvert::RxMessage(packet));
|
||||
mNumPlatformRaReceived++;
|
||||
mLastPlatformRaTime = TimerMilli::GetNow();
|
||||
|
||||
@@ -3671,7 +3680,7 @@ exit:
|
||||
}
|
||||
}
|
||||
|
||||
Error RoutingManager::PdPrefixManager::Process(const Ip6::Nd::RouterAdvertMessage &aMessage)
|
||||
Error RoutingManager::PdPrefixManager::Process(const Ip6::Nd::RouterAdvert::RxMessage &aMessage)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
DiscoveredPrefixTable::Entry favoredEntry;
|
||||
|
||||
@@ -630,8 +630,8 @@ private:
|
||||
public:
|
||||
explicit DiscoveredPrefixTable(Instance &aInstance);
|
||||
|
||||
void ProcessRouterAdvertMessage(const Ip6::Nd::RouterAdvertMessage &aRaMessage,
|
||||
const Ip6::Address &aSrcAddress);
|
||||
void ProcessRouterAdvertMessage(const Ip6::Nd::RouterAdvert::RxMessage &aRaMessage,
|
||||
const Ip6::Address &aSrcAddress);
|
||||
void ProcessNeighborAdvertMessage(const Ip6::Nd::NeighborAdvertMessage &aNaMessage);
|
||||
|
||||
bool ContainsDefaultOrNonUlaRoutePrefix(void) const;
|
||||
@@ -648,7 +648,7 @@ private:
|
||||
|
||||
TimeMilli CalculateNextStaleTime(TimeMilli aNow) const;
|
||||
|
||||
void DetermineAndSetFlags(Ip6::Nd::RouterAdvertMessage &aRaMessage) const;
|
||||
void DetermineAndSetFlags(Ip6::Nd::RouterAdvert::Header &aHeader) const;
|
||||
|
||||
void InitIterator(PrefixTableIterator &aIterator) const;
|
||||
Error GetNextEntry(PrefixTableIterator &aIterator, PrefixTableEntry &aEntry) const;
|
||||
@@ -724,7 +724,7 @@ private:
|
||||
TimeMilli mNow;
|
||||
};
|
||||
|
||||
void SetFrom(const Ip6::Nd::RouterAdvertMessage::Header &aRaHeader);
|
||||
void SetFrom(const Ip6::Nd::RouterAdvert::Header &aRaHeader);
|
||||
void SetFrom(const Ip6::Nd::PrefixInfoOption &aPio);
|
||||
void SetFrom(const Ip6::Nd::RouteInfoOption &aRio);
|
||||
Type GetType(void) const { return mType; }
|
||||
@@ -824,7 +824,7 @@ private:
|
||||
void SetInitTime(void) { mData32 = TimerMilli::GetNow().GetValue(); }
|
||||
};
|
||||
|
||||
void ProcessRaHeader(const Ip6::Nd::RouterAdvertMessage::Header &aRaHeader, Router &aRouter);
|
||||
void ProcessRaHeader(const Ip6::Nd::RouterAdvert::Header &aRaHeader, Router &aRouter);
|
||||
void ProcessPrefixInfoOption(const Ip6::Nd::PrefixInfoOption &aPio, Router &aRouter);
|
||||
void ProcessRouteInfoOption(const Ip6::Nd::RouteInfoOption &aRio, Router &aRouter);
|
||||
void ProcessRaFlagsExtOption(const Ip6::Nd::RaFlagsExtOption &aFlagsOption, Router &aRouter);
|
||||
@@ -951,7 +951,7 @@ private:
|
||||
bool IsInitalEvaluationDone(void) const;
|
||||
void HandleDiscoveredPrefixTableChanged(void);
|
||||
bool ShouldPublishUlaRoute(void) const;
|
||||
void AppendAsPiosTo(Ip6::Nd::RouterAdvertMessage &aRaMessage);
|
||||
Error AppendAsPiosTo(Ip6::Nd::RouterAdvert::TxMessage &aRaMessage);
|
||||
bool IsPublishingOrAdvertising(void) const;
|
||||
void HandleNetDataChange(void);
|
||||
void HandleExtPanIdChange(void);
|
||||
@@ -980,8 +980,8 @@ private:
|
||||
void PublishAndAdvertise(void);
|
||||
void Deprecate(void);
|
||||
void ResetExpireTime(TimeMilli aNow);
|
||||
void AppendCurPrefix(Ip6::Nd::RouterAdvertMessage &aRaMessage);
|
||||
void AppendOldPrefixes(Ip6::Nd::RouterAdvertMessage &aRaMessage);
|
||||
Error AppendCurPrefix(Ip6::Nd::RouterAdvert::TxMessage &aRaMessage);
|
||||
Error AppendOldPrefixes(Ip6::Nd::RouterAdvert::TxMessage &aRaMessage);
|
||||
void DeprecateOldPrefix(const Ip6::Prefix &aPrefix, TimeMilli aExpireTime);
|
||||
void SavePrefix(const Ip6::Prefix &aPrefix, TimeMilli aExpireTime);
|
||||
|
||||
@@ -1013,8 +1013,8 @@ private:
|
||||
void SetPreference(RoutePreference aPreference);
|
||||
void ClearPreference(void);
|
||||
void HandleRoleChanged(void);
|
||||
void AppendRios(Ip6::Nd::RouterAdvertMessage &aRaMessage);
|
||||
void InvalidatPrevRios(Ip6::Nd::RouterAdvertMessage &aRaMessage);
|
||||
Error AppendRios(Ip6::Nd::RouterAdvert::TxMessage &aRaMessage);
|
||||
Error InvalidatPrevRios(Ip6::Nd::RouterAdvert::TxMessage &aRaMessage);
|
||||
bool HasAdvertised(const Ip6::Prefix &aPrefix) const { return mPrefixes.ContainsMatching(aPrefix); }
|
||||
uint16_t GetAdvertisedRioCount(void) const { return mPrefixes.GetLength(); }
|
||||
void HandleTimer(void);
|
||||
@@ -1041,9 +1041,11 @@ private:
|
||||
void Add(const Ip6::Prefix &aPrefix);
|
||||
};
|
||||
|
||||
void SetPreferenceBasedOnRole(void);
|
||||
void UpdatePreference(RoutePreference aPreference);
|
||||
void AppendRio(const Ip6::Prefix &aPrefix, uint32_t aRouteLifetime, Ip6::Nd::RouterAdvertMessage &aRaMessage);
|
||||
void SetPreferenceBasedOnRole(void);
|
||||
void UpdatePreference(RoutePreference aPreference);
|
||||
Error AppendRio(const Ip6::Prefix &aPrefix,
|
||||
uint32_t aRouteLifetime,
|
||||
Ip6::Nd::RouterAdvert::TxMessage &aRaMessage);
|
||||
|
||||
using RioTimer = TimerMilliIn<RoutingManager, &RoutingManager::HandleRioAdvertiserimer>;
|
||||
|
||||
@@ -1167,11 +1169,11 @@ private:
|
||||
{
|
||||
}
|
||||
|
||||
Ip6::Nd::RouterAdvertMessage::Header mHeader;
|
||||
TimeMilli mHeaderUpdateTime;
|
||||
bool mIsHeaderFromHost;
|
||||
uint32_t mTxCount;
|
||||
TimeMilli mLastTxTime;
|
||||
Ip6::Nd::RouterAdvert::Header mHeader;
|
||||
TimeMilli mHeaderUpdateTime;
|
||||
bool mIsHeaderFromHost;
|
||||
uint32_t mTxCount;
|
||||
TimeMilli mLastTxTime;
|
||||
};
|
||||
|
||||
void HandleRsSenderTimer(void) { mRsSender.HandleTimer(); }
|
||||
@@ -1246,7 +1248,7 @@ private:
|
||||
}
|
||||
|
||||
private:
|
||||
Error Process(const Ip6::Nd::RouterAdvertMessage &aMessage);
|
||||
Error Process(const Ip6::Nd::RouterAdvert::RxMessage &aMessage);
|
||||
void EvaluateStateChange(Dhcp6PdState aOldState);
|
||||
void WithdrawPrefix(void);
|
||||
void StartStop(bool aStart);
|
||||
@@ -1287,8 +1289,8 @@ private:
|
||||
void UpdateDiscoveredPrefixTableOnNetDataChange(void);
|
||||
bool NetworkDataContainsOmrPrefix(const Ip6::Prefix &aPrefix) const;
|
||||
bool NetworkDataContainsUlaRoute(void) const;
|
||||
void UpdateRouterAdvertHeader(const Ip6::Nd::RouterAdvertMessage *aRouterAdvertMessage);
|
||||
bool IsReceivedRouterAdvertFromManager(const Ip6::Nd::RouterAdvertMessage &aRaMessage) const;
|
||||
void UpdateRouterAdvertHeader(const Ip6::Nd::RouterAdvert::RxMessage *aRouterAdvertMessage);
|
||||
bool IsReceivedRouterAdvertFromManager(const Ip6::Nd::RouterAdvert::RxMessage &aRaMessage) const;
|
||||
void ResetDiscoveredPrefixStaleTimer(void);
|
||||
|
||||
static bool IsValidBrUlaPrefix(const Ip6::Prefix &aBrUlaPrefix);
|
||||
|
||||
+38
-19
@@ -36,6 +36,7 @@
|
||||
|
||||
#include "common/as_core_type.hpp"
|
||||
#include "common/code_utils.hpp"
|
||||
#include "instance/instance.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Ip6 {
|
||||
@@ -181,9 +182,9 @@ void RaFlagsExtOption::Init(void)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// RouterAdverMessage::Header
|
||||
// RouterAdver::Header
|
||||
|
||||
void RouterAdvertMessage::Header::SetToDefault(void)
|
||||
void RouterAdvert::Header::SetToDefault(void)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(mCode);
|
||||
OT_UNUSED_VARIABLE(mCurHopLimit);
|
||||
@@ -194,21 +195,21 @@ void RouterAdvertMessage::Header::SetToDefault(void)
|
||||
mType = Icmp::Header::kTypeRouterAdvert;
|
||||
}
|
||||
|
||||
RoutePreference RouterAdvertMessage::Header::GetDefaultRouterPreference(void) const
|
||||
RoutePreference RouterAdvert::Header::GetDefaultRouterPreference(void) const
|
||||
{
|
||||
return NetworkData::RoutePreferenceFromValue((mFlags & kPreferenceMask) >> kPreferenceOffset);
|
||||
}
|
||||
|
||||
void RouterAdvertMessage::Header::SetDefaultRouterPreference(RoutePreference aPreference)
|
||||
void RouterAdvert::Header::SetDefaultRouterPreference(RoutePreference aPreference)
|
||||
{
|
||||
mFlags &= ~kPreferenceMask;
|
||||
mFlags |= (NetworkData::RoutePreferenceToValue(aPreference) << kPreferenceOffset) & kPreferenceMask;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// RouterAdverMessage
|
||||
// RouterAdver::TxMessage
|
||||
|
||||
Option *RouterAdvertMessage::AppendOption(uint16_t aOptionSize)
|
||||
Option *RouterAdvert::TxMessage::AppendOption(uint16_t aOptionSize)
|
||||
{
|
||||
// This method appends an option with a given size to the RA
|
||||
// message by reserving space in the data buffer if there is
|
||||
@@ -217,21 +218,39 @@ Option *RouterAdvertMessage::AppendOption(uint16_t aOptionSize)
|
||||
// initialized and populated by the caller.
|
||||
|
||||
Option *option = nullptr;
|
||||
uint32_t newLength = mData.GetLength();
|
||||
uint16_t oldLength = mArray.GetLength();
|
||||
|
||||
newLength += aOptionSize;
|
||||
VerifyOrExit(newLength <= mMaxLength);
|
||||
|
||||
option = reinterpret_cast<Option *>(AsNonConst(GetDataEnd()));
|
||||
mData.SetLength(static_cast<uint16_t>(newLength));
|
||||
SuccessOrExit(AppendBytes(nullptr, aOptionSize));
|
||||
option = reinterpret_cast<Option *>(&mArray[oldLength]);
|
||||
|
||||
exit:
|
||||
return option;
|
||||
}
|
||||
|
||||
Error RouterAdvertMessage::AppendPrefixInfoOption(const Prefix &aPrefix,
|
||||
uint32_t aValidLifetime,
|
||||
uint32_t aPreferredLifetime)
|
||||
Error RouterAdvert::TxMessage::AppendBytes(const uint8_t *aBytes, uint16_t aLength)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
for (; aLength > 0; aLength--)
|
||||
{
|
||||
uint8_t byte;
|
||||
|
||||
byte = (aBytes == nullptr) ? 0 : *aBytes++;
|
||||
SuccessOrExit(error = mArray.PushBack(byte));
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error RouterAdvert::TxMessage::AppendHeader(const Header &aHeader)
|
||||
{
|
||||
return AppendBytes(reinterpret_cast<const uint8_t *>(&aHeader), sizeof(Header));
|
||||
}
|
||||
|
||||
Error RouterAdvert::TxMessage::AppendPrefixInfoOption(const Prefix &aPrefix,
|
||||
uint32_t aValidLifetime,
|
||||
uint32_t aPreferredLifetime)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
PrefixInfoOption *pio;
|
||||
@@ -250,9 +269,9 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error RouterAdvertMessage::AppendRouteInfoOption(const Prefix &aPrefix,
|
||||
uint32_t aRouteLifetime,
|
||||
RoutePreference aPreference)
|
||||
Error RouterAdvert::TxMessage::AppendRouteInfoOption(const Prefix &aPrefix,
|
||||
uint32_t aRouteLifetime,
|
||||
RoutePreference aPreference)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
RouteInfoOption *rio;
|
||||
@@ -269,7 +288,7 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error RouterAdvertMessage::AppendFlagsExtensionOption(bool aStubRouterFlag)
|
||||
Error RouterAdvert::TxMessage::AppendFlagsExtensionOption(bool aStubRouterFlag)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
RaFlagsExtOption *flagsOption;
|
||||
|
||||
+141
-116
@@ -47,6 +47,7 @@
|
||||
#include "common/const_cast.hpp"
|
||||
#include "common/encoding.hpp"
|
||||
#include "common/equatable.hpp"
|
||||
#include "common/heap_array.hpp"
|
||||
#include "net/icmp6.hpp"
|
||||
#include "net/ip6.hpp"
|
||||
#include "thread/network_data_types.hpp"
|
||||
@@ -67,7 +68,7 @@ typedef NetworkData::RoutePreference RoutePreference; ///< Route Preference
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class Option
|
||||
{
|
||||
friend class RouterAdvertMessage;
|
||||
friend class RouterAdvert;
|
||||
|
||||
public:
|
||||
enum Type : uint8_t
|
||||
@@ -525,14 +526,14 @@ private:
|
||||
static_assert(sizeof(RaFlagsExtOption) == 8, "invalid RaFlagsExtOption structure");
|
||||
|
||||
/**
|
||||
* Represents a Router Advertisement message.
|
||||
* Defines Router Advertisement components.
|
||||
*
|
||||
*/
|
||||
class RouterAdvertMessage
|
||||
class RouterAdvert
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Implements the RA message header.
|
||||
* Represent an RA message header.
|
||||
*
|
||||
* See section 2.2 of RFC 4191 [https://datatracker.ietf.org/doc/html/rfc4191]
|
||||
*
|
||||
@@ -673,135 +674,159 @@ public:
|
||||
typedef Data<kWithUint16Length> Icmp6Packet; ///< A data buffer containing an ICMPv6 packet.
|
||||
|
||||
/**
|
||||
* Initializes the RA message from a received packet data buffer.
|
||||
*
|
||||
* @param[in] aPacket A received packet data.
|
||||
* Represents a received RA message.
|
||||
*
|
||||
*/
|
||||
explicit RouterAdvertMessage(const Icmp6Packet &aPacket)
|
||||
: mData(aPacket)
|
||||
, mMaxLength(0)
|
||||
class RxMessage
|
||||
{
|
||||
}
|
||||
public:
|
||||
/**
|
||||
* Initializes the RA message from a received packet data buffer.
|
||||
*
|
||||
* @param[in] aPacket A received packet data.
|
||||
*
|
||||
*/
|
||||
explicit RxMessage(const Icmp6Packet &aPacket)
|
||||
: mData(aPacket)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the RA message as an `Icmp6Packet`.
|
||||
*
|
||||
* @returns The RA message as an `Icmp6Packet`.
|
||||
*
|
||||
*/
|
||||
const Icmp6Packet &GetAsPacket(void) const { return mData; }
|
||||
|
||||
/**
|
||||
* Indicates whether or not the received RA message is valid.
|
||||
*
|
||||
* @retval TRUE If the RA message is valid.
|
||||
* @retval FALSE If the RA message is not valid.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const
|
||||
{
|
||||
return (mData.GetBytes() != nullptr) && (mData.GetLength() >= sizeof(Header)) &&
|
||||
(GetHeader().GetType() == Icmp::Header::kTypeRouterAdvert);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the RA message's header.
|
||||
*
|
||||
* @returns The RA message's header.
|
||||
*
|
||||
*/
|
||||
const Header &GetHeader(void) const { return *reinterpret_cast<const Header *>(mData.GetBytes()); }
|
||||
|
||||
/**
|
||||
* Indicates whether or not the received RA message contains any options.
|
||||
*
|
||||
* @retval TRUE If the RA message contains at least one option.
|
||||
* @retval FALSE If the RA message contains no options.
|
||||
*
|
||||
*/
|
||||
bool ContainsAnyOptions(void) const { return (mData.GetLength() > sizeof(Header)); }
|
||||
|
||||
// The following methods are intended to support range-based `for`
|
||||
// loop iteration over `Option`s in the RA message.
|
||||
|
||||
Option::Iterator begin(void) const { return Option::Iterator(GetOptionStart(), GetDataEnd()); }
|
||||
Option::Iterator end(void) const { return Option::Iterator(); }
|
||||
|
||||
private:
|
||||
const uint8_t *GetOptionStart(void) const { return (mData.GetBytes() + sizeof(Header)); }
|
||||
const uint8_t *GetDataEnd(void) const { return mData.GetBytes() + mData.GetLength(); }
|
||||
|
||||
Data<kWithUint16Length> mData;
|
||||
};
|
||||
|
||||
/**
|
||||
* This template constructor initializes the RA message with a given header using a given buffer to store the RA
|
||||
* message.
|
||||
*
|
||||
* @tparam kBufferSize The size of the buffer used to store the RA message.
|
||||
*
|
||||
* @param[in] aHeader The RA message header.
|
||||
* @param[in] aBuffer The data buffer to store the RA message in.
|
||||
* Represents an RA message to be sent.
|
||||
*
|
||||
*/
|
||||
template <uint16_t kBufferSize>
|
||||
RouterAdvertMessage(const Header &aHeader, uint8_t (&aBuffer)[kBufferSize])
|
||||
: mMaxLength(kBufferSize)
|
||||
class TxMessage
|
||||
{
|
||||
static_assert(kBufferSize >= sizeof(Header), "Buffer for RA msg is too small");
|
||||
public:
|
||||
/**
|
||||
* Gets the prepared RA message as an `Icmp6Packet`.
|
||||
*
|
||||
* @param[out] aPacket A reference to an `Icmp6Packet`.
|
||||
*
|
||||
*/
|
||||
void GetAsPacket(Icmp6Packet &aPacket) const { aPacket.Init(mArray.AsCArray(), mArray.GetLength()); }
|
||||
|
||||
memcpy(aBuffer, &aHeader, sizeof(Header));
|
||||
mData.Init(aBuffer, sizeof(Header));
|
||||
}
|
||||
/**
|
||||
* Appends the RA header.
|
||||
*
|
||||
* @param[in] aHeader The RA header.
|
||||
*
|
||||
* @retval kErrorNone Header is written successfully.
|
||||
* @retval kErrorNoBufs Insufficient available buffers to grow the message.
|
||||
*
|
||||
*/
|
||||
Error AppendHeader(const Header &aHeader);
|
||||
|
||||
/**
|
||||
* Gets the RA message as an `Icmp6Packet`.
|
||||
*
|
||||
* @returns The RA message as an `Icmp6Packet`.
|
||||
*
|
||||
*/
|
||||
const Icmp6Packet &GetAsPacket(void) const { return mData; }
|
||||
/**
|
||||
* Appends a Prefix Info Option to the RA message.
|
||||
*
|
||||
* The appended Prefix Info Option will have both on-link (L) and autonomous address-configuration (A) flags
|
||||
* set.
|
||||
*
|
||||
* @param[in] aPrefix The prefix.
|
||||
* @param[in] aValidLifetime The valid lifetime in seconds.
|
||||
* @param[in] aPreferredLifetime The preferred lifetime in seconds.
|
||||
*
|
||||
* @retval kErrorNone Option is appended successfully.
|
||||
* @retval kErrorNoBufs Insufficient available buffers to grow the message.
|
||||
*
|
||||
*/
|
||||
Error AppendPrefixInfoOption(const Prefix &aPrefix, uint32_t aValidLifetime, uint32_t aPreferredLifetime);
|
||||
|
||||
/**
|
||||
* Indicates whether or not the RA message is valid.
|
||||
*
|
||||
* @retval TRUE If the RA message is valid.
|
||||
* @retval FALSE If the RA message is not valid.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const
|
||||
{
|
||||
return (mData.GetBytes() != nullptr) && (mData.GetLength() >= sizeof(Header)) &&
|
||||
(GetHeader().GetType() == Icmp::Header::kTypeRouterAdvert);
|
||||
}
|
||||
/**
|
||||
* Appends a Route Info Option to the RA message.
|
||||
*
|
||||
* @param[in] aPrefix The prefix.
|
||||
* @param[in] aRouteLifetime The route lifetime in seconds.
|
||||
* @param[in] aPreference The route preference.
|
||||
*
|
||||
* @retval kErrorNone Option is appended successfully.
|
||||
* @retval kErrorNoBufs Insufficient available buffers to grow the message.
|
||||
*
|
||||
*/
|
||||
Error AppendRouteInfoOption(const Prefix &aPrefix, uint32_t aRouteLifetime, RoutePreference aPreference);
|
||||
|
||||
/**
|
||||
* Gets the RA message's header.
|
||||
*
|
||||
* @returns The RA message's header.
|
||||
*
|
||||
*/
|
||||
const Header &GetHeader(void) const { return *reinterpret_cast<const Header *>(mData.GetBytes()); }
|
||||
/**
|
||||
* Appends a Flags Extension Option to the RA message.
|
||||
*
|
||||
* @param[in] aStubRouterFlag The stub router flag.
|
||||
*
|
||||
* @retval kErrorNone Option is appended successfully.
|
||||
* @retval kErrorNoBufs Insufficient available buffers to grow the message.
|
||||
*
|
||||
*/
|
||||
Error AppendFlagsExtensionOption(bool aStubRouterFlag);
|
||||
|
||||
/**
|
||||
* Gets the RA message's header.
|
||||
*
|
||||
* @returns The RA message's header.
|
||||
*
|
||||
*/
|
||||
Header &GetHeader(void) { return *reinterpret_cast<Header *>(AsNonConst(mData.GetBytes())); }
|
||||
/**
|
||||
* Indicates whether or not the received RA message contains any options.
|
||||
*
|
||||
* @retval TRUE If the RA message contains at least one option.
|
||||
* @retval FALSE If the RA message contains no options.
|
||||
*
|
||||
*/
|
||||
bool ContainsAnyOptions(void) const { return (mArray.GetLength() > sizeof(Header)); }
|
||||
|
||||
/**
|
||||
* Appends a Prefix Info Option to the RA message.
|
||||
*
|
||||
* The appended Prefix Info Option will have both on-link (L) and autonomous address-configuration (A) flags set.
|
||||
*
|
||||
* @param[in] aPrefix The prefix.
|
||||
* @param[in] aValidLifetime The valid lifetime in seconds.
|
||||
* @param[in] aPreferredLifetime The preferred lifetime in seconds.
|
||||
*
|
||||
* @retval kErrorNone Option is appended successfully.
|
||||
* @retval kErrorNoBufs No more space in the buffer to append the option.
|
||||
*
|
||||
*/
|
||||
Error AppendPrefixInfoOption(const Prefix &aPrefix, uint32_t aValidLifetime, uint32_t aPreferredLifetime);
|
||||
private:
|
||||
static constexpr uint16_t kCapacityIncrement = 256;
|
||||
|
||||
/**
|
||||
* Appends a Route Info Option to the RA message.
|
||||
*
|
||||
* @param[in] aPrefix The prefix.
|
||||
* @param[in] aRouteLifetime The route lifetime in seconds.
|
||||
* @param[in] aPreference The route preference.
|
||||
*
|
||||
* @retval kErrorNone Option is appended successfully.
|
||||
* @retval kErrorNoBufs No more space in the buffer to append the option.
|
||||
*
|
||||
*/
|
||||
Error AppendRouteInfoOption(const Prefix &aPrefix, uint32_t aRouteLifetime, RoutePreference aPreference);
|
||||
Error AppendBytes(const uint8_t *aBytes, uint16_t aLength);
|
||||
Option *AppendOption(uint16_t aOptionSize);
|
||||
|
||||
/**
|
||||
* Appends a Flags Extension Option to the RA message.
|
||||
*
|
||||
* @param[in] aStubRouterFlag The stub router flag.
|
||||
*
|
||||
* @retval kErrorNone Option is appended successfully.
|
||||
* @retval kErrorNoBufs No more space in the buffer to append the option.
|
||||
*
|
||||
*/
|
||||
Error AppendFlagsExtensionOption(bool aStubRouterFlag);
|
||||
Heap::Array<uint8_t, kCapacityIncrement> mArray;
|
||||
};
|
||||
|
||||
/**
|
||||
* Indicates whether or not the RA message contains any options.
|
||||
*
|
||||
* @retval TRUE If the RA message contains at least one option.
|
||||
* @retval FALSE If the RA message contains no options.
|
||||
*
|
||||
*/
|
||||
bool ContainsAnyOptions(void) const { return (mData.GetLength() > sizeof(Header)); }
|
||||
|
||||
// The following methods are intended to support range-based `for`
|
||||
// loop iteration over `Option`s in the RA message.
|
||||
|
||||
Option::Iterator begin(void) const { return Option::Iterator(GetOptionStart(), GetDataEnd()); }
|
||||
Option::Iterator end(void) const { return Option::Iterator(); }
|
||||
|
||||
private:
|
||||
const uint8_t *GetOptionStart(void) const { return (mData.GetBytes() + sizeof(Header)); }
|
||||
const uint8_t *GetDataEnd(void) const { return mData.GetBytes() + mData.GetLength(); }
|
||||
Option *AppendOption(uint16_t aOptionSize);
|
||||
|
||||
Data<kWithUint16Length> mData;
|
||||
uint16_t mMaxLength;
|
||||
RouterAdvert(void) = delete;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -126,7 +126,7 @@ static otRadioFrame sRadioTxFrame;
|
||||
static uint8_t sRadioTxFramePsdu[OT_RADIO_FRAME_MAX_SIZE];
|
||||
static bool sRadioTxOngoing = false;
|
||||
|
||||
using Icmp6Packet = Ip6::Nd::RouterAdvertMessage::Icmp6Packet;
|
||||
using Icmp6Packet = Ip6::Nd::RouterAdvert::Icmp6Packet;
|
||||
|
||||
enum ExpectedPio
|
||||
{
|
||||
@@ -414,7 +414,7 @@ void ValidateRouterAdvert(const Icmp6Packet &aPacket)
|
||||
{
|
||||
constexpr uint8_t kMaxPrefixes = 16;
|
||||
|
||||
Ip6::Nd::RouterAdvertMessage raMsg(aPacket);
|
||||
Ip6::Nd::RouterAdvert::RxMessage raMsg(aPacket);
|
||||
bool sawExpectedPio = false;
|
||||
Array<Ip6::Prefix, kMaxPrefixes> pioPrefixes;
|
||||
Array<Ip6::Prefix, kMaxPrefixes> rioPrefixes;
|
||||
@@ -570,7 +570,7 @@ exit:
|
||||
|
||||
void LogRouterAdvert(const Icmp6Packet &aPacket)
|
||||
{
|
||||
Ip6::Nd::RouterAdvertMessage raMsg(aPacket);
|
||||
Ip6::Nd::RouterAdvert::RxMessage raMsg(aPacket);
|
||||
|
||||
VerifyOrQuit(raMsg.IsValid());
|
||||
|
||||
@@ -854,17 +854,15 @@ struct RaFlags : public Clearable<RaFlags>
|
||||
bool mStubRouterFlag;
|
||||
};
|
||||
|
||||
template <size_t N>
|
||||
uint16_t BuildRouterAdvert(uint8_t (&aBuffer)[N],
|
||||
const Pio *aPios,
|
||||
uint16_t aNumPios,
|
||||
const Rio *aRios,
|
||||
uint16_t aNumRios,
|
||||
const DefaultRoute &aDefaultRoute,
|
||||
const RaFlags &aRaFlags)
|
||||
void BuildRouterAdvert(Ip6::Nd::RouterAdvert::TxMessage &aRaMsg,
|
||||
const Pio *aPios,
|
||||
uint16_t aNumPios,
|
||||
const Rio *aRios,
|
||||
uint16_t aNumRios,
|
||||
const DefaultRoute &aDefaultRoute,
|
||||
const RaFlags &aRaFlags)
|
||||
{
|
||||
Ip6::Nd::RouterAdvertMessage::Header header;
|
||||
uint16_t length;
|
||||
Ip6::Nd::RouterAdvert::Header header;
|
||||
|
||||
header.SetRouterLifetime(aDefaultRoute.mLifetime);
|
||||
header.SetDefaultRouterPreference(aDefaultRoute.mPreference);
|
||||
@@ -879,29 +877,22 @@ uint16_t BuildRouterAdvert(uint8_t (&aBuffer)[N],
|
||||
header.SetOtherConfigFlag();
|
||||
}
|
||||
|
||||
SuccessOrQuit(aRaMsg.AppendHeader(header));
|
||||
|
||||
if (aRaFlags.mStubRouterFlag)
|
||||
{
|
||||
Ip6::Nd::RouterAdvertMessage raMsg(header, aBuffer);
|
||||
|
||||
if (aRaFlags.mStubRouterFlag)
|
||||
{
|
||||
SuccessOrQuit(raMsg.AppendFlagsExtensionOption(/* aStubRouterFlag */ true));
|
||||
}
|
||||
|
||||
for (; aNumPios > 0; aPios++, aNumPios--)
|
||||
{
|
||||
SuccessOrQuit(
|
||||
raMsg.AppendPrefixInfoOption(aPios->mPrefix, aPios->mValidLifetime, aPios->mPreferredLifetime));
|
||||
}
|
||||
|
||||
for (; aNumRios > 0; aRios++, aNumRios--)
|
||||
{
|
||||
SuccessOrQuit(raMsg.AppendRouteInfoOption(aRios->mPrefix, aRios->mValidLifetime, aRios->mPreference));
|
||||
}
|
||||
|
||||
length = raMsg.GetAsPacket().GetLength();
|
||||
SuccessOrQuit(aRaMsg.AppendFlagsExtensionOption(/* aStubRouterFlag */ true));
|
||||
}
|
||||
|
||||
return length;
|
||||
for (; aNumPios > 0; aPios++, aNumPios--)
|
||||
{
|
||||
SuccessOrQuit(aRaMsg.AppendPrefixInfoOption(aPios->mPrefix, aPios->mValidLifetime, aPios->mPreferredLifetime));
|
||||
}
|
||||
|
||||
for (; aNumRios > 0; aRios++, aNumRios--)
|
||||
{
|
||||
SuccessOrQuit(aRaMsg.AppendRouteInfoOption(aRios->mPrefix, aRios->mValidLifetime, aRios->mPreference));
|
||||
}
|
||||
}
|
||||
|
||||
void SendRouterAdvert(const Ip6::Address &aRouterAddress,
|
||||
@@ -912,12 +903,15 @@ void SendRouterAdvert(const Ip6::Address &aRouterAddress,
|
||||
const DefaultRoute &aDefaultRoute,
|
||||
const RaFlags &aRaFlags)
|
||||
{
|
||||
uint8_t buffer[kMaxRaSize];
|
||||
uint16_t length = BuildRouterAdvert(buffer, aPios, aNumPios, aRios, aNumRios, aDefaultRoute, aRaFlags);
|
||||
Ip6::Nd::RouterAdvert::TxMessage raMsg;
|
||||
Icmp6Packet packet;
|
||||
|
||||
SendRouterAdvert(aRouterAddress, buffer, length);
|
||||
BuildRouterAdvert(raMsg, aPios, aNumPios, aRios, aNumRios, aDefaultRoute, aRaFlags);
|
||||
raMsg.GetAsPacket(packet);
|
||||
|
||||
SendRouterAdvert(aRouterAddress, packet);
|
||||
Log("Sending RA from router %s", aRouterAddress.ToString().AsCString());
|
||||
LogRouterAdvert(buffer, length);
|
||||
LogRouterAdvert(packet);
|
||||
}
|
||||
|
||||
template <uint16_t kNumPios, uint16_t kNumRios>
|
||||
@@ -963,13 +957,16 @@ void SendRouterAdvert(const Ip6::Address &aRouterAddress, const RaFlags &aRaFlag
|
||||
|
||||
template <uint16_t kNumPios> void SendRouterAdvertToBorderRoutingProcessIcmp6Ra(const Pio (&aPios)[kNumPios])
|
||||
{
|
||||
uint8_t buffer[kMaxRaSize];
|
||||
uint16_t length = BuildRouterAdvert(buffer, aPios, kNumPios, nullptr, 0,
|
||||
DefaultRoute(0, NetworkData::kRoutePreferenceMedium), RaFlags());
|
||||
Ip6::Nd::RouterAdvert::TxMessage raMsg;
|
||||
Icmp6Packet packet;
|
||||
|
||||
otPlatBorderRoutingProcessIcmp6Ra(sInstance, buffer, length);
|
||||
BuildRouterAdvert(raMsg, aPios, kNumPios, nullptr, 0, DefaultRoute(0, NetworkData::kRoutePreferenceMedium),
|
||||
RaFlags());
|
||||
raMsg.GetAsPacket(packet);
|
||||
|
||||
otPlatBorderRoutingProcessIcmp6Ra(sInstance, packet.GetBytes(), packet.GetLength());
|
||||
Log("Passing RA to otPlatBorderRoutingProcessIcmp6Ra");
|
||||
LogRouterAdvert(buffer, length);
|
||||
LogRouterAdvert(packet);
|
||||
}
|
||||
|
||||
struct OnLinkPrefix : public Pio
|
||||
|
||||
Reference in New Issue
Block a user