Skip to content

Commit

Permalink
[ip6] add PrepareMulticastToLargerThanRealmLocal() (openthread#9513)
Browse files Browse the repository at this point in the history
This commit adds `Ip6::PrepareMulticastToLargerThanRealmLocal()`,
which prepares to transmit a multicast message with destination
larger than realm-local address. It checks if any sleepy child of
device is subscribed to the multicast address and clones the message
for indirect tx if needed, before adding the IP-in-IP tunnel header.
The new method helps remove repeated code in `SendRaw()` and
`SenDatagram()`.
  • Loading branch information
abtink authored Oct 12, 2023
1 parent 543b5da commit fc30740
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 39 deletions.
58 changes: 20 additions & 38 deletions src/core/net/ip6.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,12 +200,29 @@ Error Ip6::AddMplOption(Message &aMessage, Header &aHeader)
return error;
}

Error Ip6::AddTunneledMplOption(Message &aMessage, Header &aHeader)
Error Ip6::PrepareMulticastToLargerThanRealmLocal(Message &aMessage, const Header &aHeader)
{
Error error = kErrorNone;
Header tunnelHeader;
const Address *source;

#if OPENTHREAD_FTD
if (aHeader.GetDestination().IsMulticastLargerThanRealmLocal() &&
Get<ChildTable>().HasSleepyChildWithAddress(aHeader.GetDestination()))
{
Message *messageCopy = aMessage.Clone();

if (messageCopy != nullptr)
{
EnqueueDatagram(*messageCopy);
}
else
{
LogWarn("Failed to clone mcast message for indirect tx to sleepy children");
}
}
#endif

// Use IP-in-IP encapsulation (RFC2473) and ALL_MPL_FORWARDERS address.
tunnelHeader.InitVersionTrafficClassFlow();
tunnelHeader.SetHopLimit(static_cast<uint8_t>(kDefaultHopLimit));
Expand Down Expand Up @@ -280,25 +297,7 @@ Error Ip6::InsertMplOption(Message &aMessage, Header &aHeader)
}
else
{
#if OPENTHREAD_FTD
if (aHeader.GetDestination().IsMulticastLargerThanRealmLocal() &&
Get<ChildTable>().HasSleepyChildWithAddress(aHeader.GetDestination()))
{
Message *messageCopy = nullptr;

if ((messageCopy = aMessage.Clone()) != nullptr)
{
IgnoreError(HandleDatagram(*messageCopy));
LogInfo("Message copy for indirect transmission to sleepy children");
}
else
{
LogWarn("No enough buffer for message copy for indirect transmission to sleepy children");
}
}
#endif

SuccessOrExit(error = AddTunneledMplOption(aMessage, aHeader));
SuccessOrExit(error = PrepareMulticastToLargerThanRealmLocal(aMessage, aHeader));
}

exit:
Expand Down Expand Up @@ -469,24 +468,7 @@ Error Ip6::SendDatagram(Message &aMessage, MessageInfo &aMessageInfo, uint8_t aI

if (aMessageInfo.GetPeerAddr().IsMulticastLargerThanRealmLocal())
{
#if OPENTHREAD_FTD
if (Get<ChildTable>().HasSleepyChildWithAddress(header.GetDestination()))
{
Message *messageCopy = aMessage.Clone();

if (messageCopy != nullptr)
{
LogInfo("Message copy for indirect transmission to sleepy children");
EnqueueDatagram(*messageCopy);
}
else
{
LogWarn("No enough buffer for message copy for indirect transmission to sleepy children");
}
}
#endif

SuccessOrExit(error = AddTunneledMplOption(aMessage, header));
SuccessOrExit(error = PrepareMulticastToLargerThanRealmLocal(aMessage, header));
}

aMessage.SetMulticastLoop(aMessageInfo.GetMulticastLoop());
Expand Down
2 changes: 1 addition & 1 deletion src/core/net/ip6.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ class Ip6 : public InstanceLocator, private NonCopyable
void SendIcmpError(Message &aMessage, Icmp::Header::Type aIcmpType, Icmp::Header::Code aIcmpCode);
#endif
Error AddMplOption(Message &aMessage, Header &aHeader);
Error AddTunneledMplOption(Message &aMessage, Header &aHeader);
Error PrepareMulticastToLargerThanRealmLocal(Message &aMessage, const Header &aHeader);
Error InsertMplOption(Message &aMessage, Header &aHeader);
Error RemoveMplOption(Message &aMessage);
Error HandleOptions(Message &aMessage, Header &aHeader, bool &aReceive);
Expand Down

0 comments on commit fc30740

Please sign in to comment.