From fc307401a6aee332b36a94816033c8884ed283c5 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Wed, 11 Oct 2023 17:20:16 -0700 Subject: [PATCH] [ip6] add `PrepareMulticastToLargerThanRealmLocal()` (#9513) 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()`. --- src/core/net/ip6.cpp | 58 +++++++++++++++----------------------------- src/core/net/ip6.hpp | 2 +- 2 files changed, 21 insertions(+), 39 deletions(-) diff --git a/src/core/net/ip6.cpp b/src/core/net/ip6.cpp index 22b383450..61926c5d9 100644 --- a/src/core/net/ip6.cpp +++ b/src/core/net/ip6.cpp @@ -200,12 +200,29 @@ exit: 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().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(kDefaultHopLimit)); @@ -280,25 +297,7 @@ Error Ip6::InsertMplOption(Message &aMessage, Header &aHeader) } else { -#if OPENTHREAD_FTD - if (aHeader.GetDestination().IsMulticastLargerThanRealmLocal() && - Get().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: @@ -469,24 +468,7 @@ Error Ip6::SendDatagram(Message &aMessage, MessageInfo &aMessageInfo, uint8_t aI if (aMessageInfo.GetPeerAddr().IsMulticastLargerThanRealmLocal()) { -#if OPENTHREAD_FTD - if (Get().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()); diff --git a/src/core/net/ip6.hpp b/src/core/net/ip6.hpp index 46e0b05f7..c2a2e530e 100644 --- a/src/core/net/ip6.hpp +++ b/src/core/net/ip6.hpp @@ -387,7 +387,7 @@ private: 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);