Subject: [Mcast-wifi] Issues with MLD and Android powersaving / sleep mode...

From: Linus Lüssing <[email-masked]>
Date: Tue, 24 Mar 2020 21:54:02 +0100

Hi,

With Freifunk [0] we lately came across an annoying issue with Android
devices... which I'm not really sure how to solve yet...

It seems that (some?) Android devices do not respond to MLD
queries when in sleep mode:

https://github.com/freifunk-gluon/gluon/issues/1832
https://issuetracker.google.com/issues/149630944

Which causes severe IPv6 connectivity/usability issues
when trying to use MLD snooping capabilities.

As soon as you turn on the screen of the Android device or
connect a charger MLD Reports arrive just fine. My test results
were, as noted in the Android ticket:

Results with phone on battery:
* 0/8 MLD Reports received
* 3/8 Neighbor Advertisements received
* 8/8 Echo Replies received

Results with phone on charger:
* 8/8 MLD Reports received
* 8/8 Neighbor Advertisements received
* 8/8 Echo Replies received

Fixing this on the Android devices would need several years to
propagate, as noted by an Android dev.

Has anyone on this list experienced similar issues, too? And is
there maybe even someone who came up with a workaround that they
implemented on the router/switch side?

If not and if we can't come up with a solution it looks pretty
gloomy for (non-flooding) multicast in wifi networks to me for
the next years...

Regards, Linus

[0]: https://freifunk.net/en/

---

From: Mark Smith <[email-masked]>
Date: Wed, 25 Mar 2020 08:40:09 +1100

> queries when in sleep mode:

If the device is asleep, effectively offline, why should it respond to
MLD queries?

When I'm asleep I have to wake up or be woken up before I respond to
queries too.

Times by a billion devices, responding to MLD queries while the device
is asleep and not in use is going to be wasting a lot of electricity.

> connect a charger MLD Reports arrive just fine.

>From the above github link, it sounds like the real fault is that when
Android wakes up it isn't immediately issuing MLD joins for its
existing IPv6 addresses. I'll have to think about which IPv6 RFC
advice to do that is probably in, however I think it should be - every
time an interface comes up with existing IPv6 addresses, it should be
sending MLD Reports to join the Solicited Node Multicast groups for
its addresses.

Regards,
Mark.

> My test results
> _______________________________________________
> Mcast-wifi mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/mcast-wifi

---

From: Dino Farinacci <[email-masked]>
Date: Tue, 24 Mar 2020 14:47:47 -0700

> sending MLD Reports to join the Solicited Node Multicast groups for

I have seen this problem too when running LISP on Android and iOS. And on an overlay, you don’t want a head-end to send MLD queries or IGMP queries to billions of nodes. This should be a periodic process from the phone for joined groups.

Dino

---

From: Linus Lüssing <[email-masked]>
Date: Wed, 25 Mar 2020 12:35:40 +0100

Hi Mark,

> sending MLD Reports to join the Solicited Node Multicast groups for

Yeah, that'd be one way of solving it. At least that specific issue.
Back then I couldn't find an RFC mandating that though (also
see my mail from last December, section "Roaming" [0]).

I'm not really familiar with either Android or it's powersaving, but
wouldn't that approach still have issues with communications
initiatiated not from but to the the Android device? For instance
someone sends a text message to an app like Signal. You'd want to
receive that timely and get a notification. And not just the next 
time you turn on the screen (and by that wake up the device).

So ICMPv6-NS to the Android device must work and as it uses a
multicast destination, MLD Queries/Reports would need have updated
any MLD snooping bridges/switches before that. Even when the
device is sleeping, right?

Also ICMPv6-NS with its multicast destination is received just
fine (with MLD snooping disabled), so it seems to me more like the
wifi drivers are not setting up their multicast wake up filters
properly.

The Android ticket references the "Android Compatibility Definition
Document" which allows some rate limiting or even filtering [1]. It
mentions ICMPv6-RA, but does not mention MLD. That might be the
reason why some vendors might have missed the necessity of MLD and
are therefore overblocking ICMPv6.

Anyways, as fixing every Android device out there would take
several years or is even impossible due to vendors not providing
updates (as noted by the Android dev in the ticket), pragmatically
speaking I currently don't see any way around implementing a
workaround on the router/switch side for the short term.
But I'd love to be proven wrong.

Regards, Linus

[0]: https://mailarchive.ietf.org/arch/msg/pim/DWWYpnsZsbqHtafwYZ_swhDpbcQ/
[1]: https://source.android.com/compatibility/7.1/android-7.1-cdd#7_4_5_minimum_network_capability

On Wed, Mar 25, 2020 at 08:40:09AM +1100, Mark Smith wrote:
> pim mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/pim

---

From: Dino Farinacci <[email-masked]>
Date: Wed, 25 Mar 2020 13:40:33 -0700

Another way to solve the problem on the head-end side could use this algorithm:

(1) Queries (using this term “query" to apply to both IGMP and MLD) are sent periodically to the well-known group. That means queries get to phones that are not sleeping. This is what is done today.

(2) If the querier sees reports (using this term “report" to apply to both IGMP and MLD) it obviously knows the phone is up and what groups it is interested in. That sets a keep-alive timer for the phone.

(3) When keep-alive timer expires, the querier doesn’t know if the phone is down, asleep, or not joined to any groups. But (this is a new addition) it sends a unicast query to the phone.

(4) If a report is received from the phone, you know the phone is not down and is interested in at least one group. Do normal report processing.

(5) Note the query wakes up the phone when asleep.

This is a simple solution which can be made more robust with complexity, but does get the job done.

Comments?

Dino

> On Mar 25, 2020, at 4:35 AM, Linus Lüssing <[email-masked]> wrote:
> 
> Hi Mark,
>

---

From: Hitoshi Asaeda <[email-masked]>
Date: Fri, 27 Mar 2020 19:19:34 +0900

RFC6636 (Tuning the Behavior of the Internet Group Management Protocol (IGMP) and Multicast Listener Discovery (MLD) for Routers in Mobile and Wireless Networks) gives some guideline to tune IGMP/MLD.
Android and iOS implement some specific mechanisms to save battery power, hence I don't know if they work what we expect, though.

Regards,

Hitoshi

> On Mar 26, 2020, at 5:40, Dino Farinacci <[email-masked]> wrote:
>

---

From: Dino Farinacci <[email-masked]>
Date: Fri, 27 Mar 2020 15:09:17 -0700

> Android and iOS implement some specific mechanisms to save battery power, hence I don't know if they work what we expect, though.

The techniques in this RFC are good but to get bang for the buck, the quering router needs to support Explicit Tracking, as you stated in the document.

But the RFC does not say what to do when a mobile node goes to sleep and how it should, or if it should, be woken up to refresh group membership status.

One important technical questiont that should be asked and answered is: 

Should a mobile host send a Leave message when the app is still joined to the group but the phone wants to go to sleep.

Dino

---

From: [email-masked]
Date: Sat, 28 Mar 2020 16:50:08 +0100

Hi Linus,

The purpose of using MLD as a part of the IPv6 address resolution protocol (ND) was to help MLD snooping switches for the solicited node multicast addresses.
My understanding is that most switches don't do that for the solicited node multicast address anyway, because of scale.
This to the extent that I was unsure if we should bother having MLD on by default for solicited node multicast at all.

Interesting to hear there are platforms that find MLD snooping useful.
Do you have a pointer or would you mind explaining how it is used in Freifunk?

Best regards,
Ole

> On 24 Mar 2020, at 21:54, Linus Lüssing <[email-masked]> wrote:
> 
> Hi,
>

---

From: Linus Lüssing <[email-masked]>
Date: Sat, 28 Mar 2020 19:54:54 +0100

Hi Ole,

> This to the extent that I was unsure if we should bother having MLD on by default for solicited node multicast at all.

The IGMP/MLD snooping in the Linux bridge treats ICMPv6-NS with
its solicited node multicast address no different than any other
multicast traffic. And ICMPv6-NS is actually the main reason I'd
like to enable MLD snooping in our mesh networks.

Currently about 50% of the management overhead is caused by the
layer 2 mesh routing protcol itself (batman-adv). The other
50% is currently ICMPv6-NS between all these phones, laptops and
gateways which so far are flooded through the mesh. (after
filtering mDNS, LLMNR, etc., these protocols just don't scale right
now)

Since ICMPv6-NS commonly has zero recipients for
duplicate-address-detection and just one recipient for address
resolution, we would greatly benefit from full MLD snooping support
as we could just drop them on the first node or forward them via
unicast to its specific destination. Which would significantly
reduce our overhead and improve our scalability.

The second, but lower priority for MLD support is of course
allowing new applications like multicast streaming between
any hosts. Serverless multicasting would fit nicely with
a decentral mesh network.

> Do you have a pointer or would you mind explaining how it is used in Freifunk?

Sure. I can't speak for all Freifunk communities. But about 40k of
the 50k nodes in Germany are using the OpenWrt based mesh
framework "Gluon" with the layer 2 mesh routing protocol
"B.A.T.M.A.N. Advanced" right now:

https://github.com/freifunk-gluon/gluon/
https://www.open-mesh.org/projects/batman-adv/wiki
https://freifunk.net/en/how-to-join/find-your-nearest-community/

So far MLD snooping is only used on the "last mile". So the Wifi AP knows
about the multicast listeners of its local Wifi clients. And this
allows us to safe quite some Wifi airtime already. Unfortunately
MLD is still too noisy in a layer 2 mesh network with a some hundred nodes
and a thousand or more client devices and not reliable enough in a frequently,
dynamically changing mesh topology. So we are mirroring the MLD state into the
mesh network, into batman-adv. batman-adv has a more robust
and less bandwidth hungry method optimized for mesh networks
(it sums the state with hashes and counters and then once a node notices
that it is not up to date anymore requests and usually receives just a
small diff from its neighbor node).

Anyway, before I get into too many details, here is the
documentation of what we have implemented and are currently using:

https://gluon.readthedocs.io/en/v2020.1.1/package/gluon-mesh-batman-adv.html#multicast-architecture
https://www.open-mesh.org/projects/batman-adv/wiki/Multicast-optimizations

And now we are about to enable the multicast optimizations in
batman-adv to have multicast listener awareness through the
whole mesh. After we hopefully solve the current issue with the
sleeping Android devices, that is...

There were also some initial patches and tests with IPv6
link-local multicast streaming, using the simple
multicast-to-multi-unicast frames conversion in batman-adv:

https://github.com/freifunk-gluon/gluon/pull/1357

Regards, Linus

---

From: Linus Lüssing <[email-masked]>
Date: Sat, 28 Mar 2020 20:33:11 +0100

> Android and iOS implement some specific mechanisms to save battery power, hence I don't know if they work what we expect, though.

Oh, thanks! I didn't know about this RFC before. It's an interesting
read.

It's maybe not 100% what you were thinking of with "Explicit
Tracking of Membership Status", but it makes me wonder if the
following approach could help:

(1) We already track host and not just port based listener state
    for the Linux bridge "multicast-to-unicast" conversion feature
(2) We could avoid timing out host based multicast listener
    entries. And only remove such an entry in the following two
    cases:
    (i): The host vanishes in the Linux bridge FDB or
         even only if it vanishes on the 802.11 layer
    (ii): If an MLDv2 Report was received, but did
          not contain the specific multicast group anymore
    (iii): An MLDv1 Done was received for the specific group

Regards, Linus

---

From: Linus Lüssing <[email-masked]>
Date: Sat, 28 Mar 2020 20:48:09 +0100

> (5) Note the query wakes up the phone when asleep.

Thanks Dino! Seems to go in the right direction. Using MLD queries with a
unicast destination was also one of my first thoughts and tries.
But unfortunately even when using both a unicast MAC destination
and unicast IPv6 destination in the MLD Query I only get MLD Reports in
3 of 8 cases... Better than nothing, but still seems even unicast is
rate-limited. And I don't know yet what else besides MLD is accounted
in the same bucket for this rate-limiting, so in a realistic setup could
be even worse than 3/8 with other traffic flying around.

What I still wanted to try (but didn't do yet) was playing with
the suggestion in the Android ticket. That is sending specific
packets prior MLD which are know to not be filtered which might
hopefully wake up the device for a while. ICMPv6 Echo Requests
might be one candidate as in my tests they were never filtered.
But also not sure if that'd be the case for all Android devices.

---

From: Hitoshi Asaeda <[email-masked]>
Date: Sun, 29 Mar 2020 12:08:33 +0900

Hi,

> On Mar 29, 2020, at 4:33, Linus Lüssing <[email-masked]> wrote:
> 

Interesting discussions.

It might be a different topic, but in fact, there is an explicit tracking draft (*) expired about a few years ago. It failed IESG review because they said the specific experiments were not explicitly described in the draft even though its intended status was experimental.
(*) https://tools.ietf.org/html/draft-ietf-pim-explicit-tracking-13
It'd be great to resume the activity if someone who has the experiments of the explicit tracking function could give some inputs for this function from implementors'/operators' points of views (or even better work together for this document).

Regards,

Hitoshi

---

From: Mark Smith <[email-masked]>
Date: Sun, 29 Mar 2020 15:35:46 +1100

Hi Linus,

> Yeah, that'd be one way of solving it. At least that specific issue.

So that's the specific issue you're asking about isn't it?

I think it is the correct solution. The MLD snooping state follows the
presence and existence of the device.

> time you turn on the screen (and by that wake up the device).

That's a different problem.

The device needs to be in charge of its own battery and how its
battery's capacity is spent. The battery is the device's resource, not
the network's.

If a sleeping device wakes up every time the network sends it an
unsolicited message to it, such as your MLD queries, then the device
becomes vulnerable to a battery resource denial of service attack. An
attacker can send a lot of unsolicited traffic, keeping the device
permanently woken until the battery runs out, defeating the purpose of
the sleeping mechanism.

If a device wants to receive messages the instant they are sent, then
it can't go to sleep, because "sleeping" means ignoring events that
occur while asleep.

What sleeping devices commonly do is they periodically wake up to
collect buffered messages, with either with the messages buffered in
the network, or probably  more compliant with the Internet
architecture, buffered in the sending host.

Regards,
Mark.