mirror of
https://github.com/espressif/openthread.git
synced 2026-09-14 13:10:08 +00:00
[ip6] skip MPL processing on SEDs and detect self-sent multicast (#12323)
This commit updates `Mpl::ProcessOption()` to skip MPL processing on Sleepy End Devices (SEDs) as an optimization. Along with this it introduces a check to prevent SEDs from processing their own multicast messages. Since MPL is now skipped on SEDs, they no longer have a mechanism for multicast duplicate detection. This can cause an issue when an SED sends a multicast message to a group it is subscribed to, as its parent can forward the message back to the SED. To handle this, `Ip6::DetermineAction()` is updated. For SEDs, it now checks if the source address of a subscribed multicast message belongs to the device itself. If it does, the message is not received, preventing the SED from processing its own looped-back messages. The behavior for non-sleepy devices remains unchanged. They continue to rely on MPL for duplicate suppression.
This commit is contained in:
+35
-5
@@ -1117,13 +1117,43 @@ void Ip6::DetermineAction(const Message &aMessage,
|
||||
// Always forward multicast packets to host network stack
|
||||
aForwardHost = true;
|
||||
|
||||
// If subscribed to the multicast address, receive if it is from the
|
||||
// Thread netif or if multicast loop is allowed.
|
||||
// Determine `aReceive` for a multicast message destined for
|
||||
// an address to which this device is subscribed.
|
||||
//
|
||||
// 1) Accept if `MulticastLoop` is enabled.
|
||||
// 2) Otherwise, if it originates from the Thread Netif:
|
||||
// - Always accept if the device is non-sleepy.
|
||||
// - If sleepy, only if the source is NOT the SED itself.
|
||||
//
|
||||
// For non-sleepy devices, duplicate multicast detection is
|
||||
// handled in `Mpl::ProcessOption()`, which will update
|
||||
// `aReceive` if the message was seen before (based on the
|
||||
// MPL Seed).
|
||||
//
|
||||
// To optimize SED behavior, MPL processing is fully skipped
|
||||
// on SEDs. Therefore, the check above is added to handle the
|
||||
// specific case where an SED sends a multicast message to a
|
||||
// group it is subscribed to. The parent can send it back to
|
||||
// the SED (since the child is subscribed), we check and skip
|
||||
// processing it.
|
||||
|
||||
if ((aMessage.IsOriginThreadNetif() || aMessage.GetMulticastLoop()) &&
|
||||
Get<ThreadNetif>().IsMulticastSubscribed(aHeader.GetDestination()))
|
||||
if (Get<ThreadNetif>().IsMulticastSubscribed(aHeader.GetDestination()))
|
||||
{
|
||||
aReceive = true;
|
||||
if (aMessage.GetMulticastLoop())
|
||||
{
|
||||
aReceive = true;
|
||||
}
|
||||
else if (aMessage.IsOriginThreadNetif())
|
||||
{
|
||||
if (Get<Mle::Mle>().IsRxOnWhenIdle())
|
||||
{
|
||||
aReceive = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
aReceive = !Get<ThreadNetif>().HasUnicastAddress(aHeader.GetSource());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExitNow();
|
||||
|
||||
@@ -117,7 +117,9 @@ exit:
|
||||
|
||||
Error Mpl::ProcessOption(Message &aMessage, const MplOption &aOption, bool &aReceive)
|
||||
{
|
||||
Error error;
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(Get<Mle::Mle>().IsRxOnWhenIdle());
|
||||
|
||||
// Check if the MPL Data Message is new.
|
||||
error = UpdateSeedSet(aOption.GetSeedId(), aOption.GetSequence());
|
||||
@@ -130,12 +132,19 @@ Error Mpl::ProcessOption(Message &aMessage, const MplOption &aOption, bool &aRec
|
||||
}
|
||||
else if (!aMessage.IsOriginThreadNetif())
|
||||
{
|
||||
// If the MPL message is not new (already present in the seed
|
||||
// set), avoid receiving it again. It should have been
|
||||
// received and processed the first time the seed set was
|
||||
// updated.
|
||||
aReceive = false;
|
||||
// In case MPL Data Message is generated locally, ignore potential error of the MPL Seed Set
|
||||
// to allow subsequent retransmissions with the same sequence number.
|
||||
|
||||
// In case MPL Data Message is generated locally, ignore
|
||||
// potential error of the MPL Seed Set to allow subsequent
|
||||
// retransmissions with the same sequence number.
|
||||
error = kErrorNone;
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user