Skip to content

Commit

Permalink
[ip6] update tunnel message receive in HandleDatagram() (#9503)
Browse files Browse the repository at this point in the history
This commit updates how `Ip6::HandleDatagram()` processes a tunneled
IP-in-IP message. Previously, if a message was marked for both
`receive` and `forwardThread`, e.g., possible for a multicast message
from host with multicast-loop flag, it would be received but not
forwarded to the Thread mesh. This commit ensures that such messages
are handled properly.

Without this change, multicast transmission still works fine due to
the MPL layer retransmitting the message, which would then be
forwarded to the Thread mesh. However, this change improves the
multicast behavior by ensuring that the original/first message is
also forwarded to the Thread mesh.

This commit changes the code so that if we need to both `receive` and
`forwardThread`, we create a copy of the message by cloning it.
Otherwise, we take ownership of the original message and use it
directly. We then remove the encapsulating header before processing
the embedded message by calling the `HandleDatagram()` recursively.
  • Loading branch information
abtink authored Oct 11, 2023
1 parent be317ec commit 543b5da
Showing 1 changed file with 28 additions and 5 deletions.
33 changes: 28 additions & 5 deletions src/core/net/ip6.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1145,7 +1145,6 @@ Error Ip6::HandleDatagram(Message &aMessage, const void *aLinkMessageInfo, bool
bool shouldFreeMessage;
uint8_t nextHeader;

start:
receive = false;
forwardThread = false;
forwardHost = false;
Expand Down Expand Up @@ -1229,10 +1228,34 @@ Error Ip6::HandleDatagram(Message &aMessage, const void *aLinkMessageInfo, bool

if (receive && (nextHeader == kProtoIp6))
{
// Remove encapsulating header and start over.
aMessage.RemoveHeader(aMessage.GetOffset());
Get<MeshForwarder>().LogMessage(MeshForwarder::kMessageReceive, aMessage);
goto start;
// Process the embedded IPv6 message in an IPv6 tunnel message.
// If we need to `forwardThread` we create a copy by cloning
// the message, otherwise we take ownership of `aMessage`
// itself and use it directly. The encapsulating header is
// then removed before processing the embedded message.

Message *messageCopy;

if (forwardThread)
{
messageCopy = aMessage.Clone();
VerifyOrExit(messageCopy != nullptr, error = kErrorNoBufs);
messageCopy->SetMulticastLoop(aMessage.GetMulticastLoop());
}
else
{
messageCopy = &aMessage;
shouldFreeMessage = false;
}

messageCopy->RemoveHeader(messageCopy->GetOffset());

Get<MeshForwarder>().LogMessage(MeshForwarder::kMessageReceive, *messageCopy);

IgnoreError(HandleDatagram(*messageCopy, aLinkMessageInfo, aIsReassembled));

receive = false;
forwardHost = false;
}

if ((forwardHost || receive) && !aIsReassembled)
Expand Down

0 comments on commit 543b5da

Please sign in to comment.