[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:
Abtin Keshavarzian
2024-03-13 11:15:49 -07:00
committed by GitHub
parent c4d7859d07
commit cf6dcc5bc7
5 changed files with 335 additions and 283 deletions
+39 -42
View File
@@ -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