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