[ip6] simplify multicast forwarding logic in DetermineAction() (#12653)

This commit simplifies and updates `Ip6::DetermineAction()` regarding
how the `aForwardThread` flag is determined for multicast messages
with a scope larger than realm-local.

Such messages are sent using IP-in-IP encapsulation destined to the
`RealmLocalAllMplForwarders` address. Both the encapsulated
(outer) and embedded (inner) messages are processed. When processing
the embedded IPv6 message, regardless of its origin, we only need to
forward it to the Thread mesh if the device has a sleepy child
subscribed to the multicast address. `MeshForwarder::SendMessage()`
on an FTD will then check for these subscriptions and schedule
indirect transmissions to those children.

The behavior for FTDs remains functionally the same as before, though
the code has been refactored to be clearer and easier to follow.

The primary change applies to MTDs: if the multicast destination scope
is larger than realm-local, the message is no longer forwarded to
Thread, as an MTD cannot have any children to support.
This commit is contained in:
Abtin Keshavarzian
2026-03-11 11:10:45 -07:00
committed by GitHub
parent b988a07525
commit 3e3690a068
+24 -9
View File
@@ -1099,18 +1099,33 @@ void Ip6::DetermineAction(const Message &aMessage,
{
// Destination is multicast
// Forward multicast message to thread unless we received it
// on Thread netif.
aForwardThread = !aMessage.IsOriginThreadNetif();
if (aHeader.GetDestination().IsMulticastLargerThanRealmLocal())
{
// Multicast messages with scope larger than realm-local
// use IP-in-IP encapsulation destined to the "All MPL
// Forwarders" multicast address. Both the encapsulated
// (outer) and embedded (inner) messages are processed.
//
// For the inner message, we set `aForwardThread` if the
// device has a sleepy child that is subscribed to the
// destination address. `MeshForwarder::SendMessage()` on
// an FTD will then check for this and schedules the
// indirect tx to such children. This is skipped on an MTD
// (`aForwardThread` remains `false`) since an MTD cannot
// have children.
#if OPENTHREAD_FTD
if (aMessage.IsOriginThreadNetif() && aHeader.GetDestination().IsMulticastLargerThanRealmLocal() &&
Get<ChildTable>().HasSleepyChildWithAddress(aHeader.GetDestination()))
{
aForwardThread = true;
}
aForwardThread = Get<ChildTable>().HasSleepyChildWithAddress(aHeader.GetDestination());
#endif
}
else
{
// For all other multicast messages, we forward to the
// Thread network unless the message was received on the
// Thread netif.
aForwardThread = !aMessage.IsOriginThreadNetif();
}
// Always forward multicast packets to host network stack
aForwardHost = true;