[nexus] optimize HandleIp6Receive and SendIp6 to use OwnedPtr (#12846)

This commit updates the IPv6 receive path in the Nexus platform to
utilize `OwnedPtr<Message>` for message lifecycle management. It
also removes the need for a large local buffer and redundant
message allocations.

Previously, `Node::HandleReceive()` copied the entire `otMessage`
payload into a local array, and `InfraIf::SendIp6()` allocated a new
`Message` to enqueue for transmission.

With this change:
- `Node::HandleIp6Receive()` wraps the received `otMessage` in an
  `OwnedPtr<Message>`, ensuring proper cleanup upon exit without
  explicitly calling `otMessageFree()`.
- The `Ip6::Header::ParseFrom` is used which reads and validates
  the IPv6 header and the message.
- The hop limit is updated in-place within the `Message` using
  `Write()` to overwrite previous header.
- `InfraIf::SendIp6()` accepts the `OwnedPtr<Message>` directly,
  taking ownership and enqueuing it without requiring reallocation
  or memory copying.
- Condition checks in `Node::HandleIp6Receive()` are reordered
  to match the comment.
This commit is contained in:
Abtin Keshavarzian
2026-04-07 13:22:55 -05:00
committed by GitHub
parent 641e84aed4
commit a24e841ad2
4 changed files with 25 additions and 38 deletions
+17 -21
View File
@@ -142,46 +142,42 @@ void Node::SetName(const char *aPrefix, uint16_t aIndex) { mName.Clear().Append(
void Node::HandleIp6Receive(otMessage *aMessage, void *aContext)
{
static_cast<Node *>(aContext)->HandleReceive(aMessage);
OwnedPtr<Message> messagePtr(AsCoreTypePtr(aMessage));
static_cast<Node *>(aContext)->HandleIp6Receive(messagePtr.PassOwnership());
}
void Node::HandleReceive(otMessage *aMessage)
void Node::HandleIp6Receive(OwnedPtr<Message> aMessagePtr)
{
uint16_t length = otMessageGetLength(aMessage);
uint8_t buffer[1500];
Ip6::Header *header;
Ip6::Header header;
VerifyOrExit(length <= sizeof(buffer));
VerifyOrQuit(otMessageRead(aMessage, 0, buffer, length) == length);
VerifyOrExit(length >= sizeof(Ip6::Header));
header = reinterpret_cast<Ip6::Header *>(buffer);
VerifyOrExit(aMessagePtr != nullptr);
SuccessOrExit(header.ParseFrom(*aMessagePtr));
// Forward packets to InfraIf if they are intended for the backbone.
// We avoid forwarding link-local and realm-local scope packets.
VerifyOrExit(mInfraIf.IsInitialized());
VerifyOrExit(header->GetHopLimit() > 1);
header->SetHopLimit(header->GetHopLimit() - 1);
VerifyOrExit(header.GetHopLimit() > 1);
header.SetHopLimit(header.GetHopLimit() - 1);
aMessagePtr->Write(0, header);
VerifyOrExit(header->GetDestination().GetScope() > Ip6::Address::kRealmLocalScope);
VerifyOrExit(header.GetDestination().GetScope() > Ip6::Address::kRealmLocalScope);
if (header->GetDestination().IsMulticast())
if (header.GetDestination().IsMulticast())
{
VerifyOrExit(Get<BackboneRouter::Local>().IsPrimary());
}
VerifyOrExit(Get<NetworkData::Leader>().IsOnMesh(header->GetSource()));
VerifyOrExit(!header.GetSource().IsLinkLocalUnicastOrMulticast());
VerifyOrExit(!Get<Mle::Mle>().IsMeshLocalAddress(header.GetSource()));
VerifyOrExit(Get<NetworkData::Leader>().IsOnMesh(header.GetSource()));
// Only forward if source is NOT Link-Local and NOT Mesh-Local.
VerifyOrExit(!header->GetSource().IsLinkLocalUnicastOrMulticast());
VerifyOrExit(!Get<Mle::Mle>().IsMeshLocalAddress(header->GetSource()));
mInfraIf.SendIp6(header->GetSource(), header->GetDestination(), buffer, length);
mInfraIf.SendIp6(header, aMessagePtr.PassOwnership());
exit:
otMessageFree(aMessage);
return;
}
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE