pali / igmpproxy

IGMP multicast routing daemon

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Filter all local multicast

Uglymotha opened this issue · comments

According to IANA (https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml):

The range of addresses between 224.0.0.0 and 224.0.0.255, inclusive,
is reserved for the use of routing protocols and other low-level
topology discovery or maintenance protocols, such as gateway discovery
and group membership reporting. Multicast routers should not forward
any multicast datagram with destination addresses in this range,
regardless of its TTL
.

igmpproxy is not adhering to this and forwarding queries for this address space. This results in igmpproxy joining/leaving groups like 224.0.0.1 (all hosts) 224.0.0.2 (all routers) 224.0.0.22 (IGMP) 224.0.0.251/252 (mDNS) upstream based on reports it receives downstream.
This is of course not correct and in my case breaks IPTV multicast streams, as my ISP stops forwarding the stream after 5 or 10 minutes (always exactly 5 or exactly 10 minutes), because igmpproxy keeps joining / leaving because of aging 224.0.0.22. My ISP does not seem to like this very much.

There's 2 ways to fix this:

  1. Make sure the switch architecture is taking care of igmpproxy never seeing reports for 224.0.0.0/8 .
  2. Patch igmp.c to actually filter out the local address range 224.0.0.0/8

In my case 1. is difficult, as my downstream switches are connected directly to the host running igmpporxy. I can put a switch in between and that works. So I decided to patch igmp.c. I's a simple enough patch.

--- igmpproxy.orig/src/igmp.c   2020-04-23 17:18:00.000000000 +0200
+++ igmpproxy/src/igmp.c        2020-04-26 11:23:40.950952000 +0200
@@ -121,8 +121,8 @@
     src       = ip->ip_src.s_addr;
     dst       = ip->ip_dst.s_addr;

-    /* filter local multicast 239.255.255.250 */
-    if (dst == htonl(0xEFFFFFFA))
+    /* filter local multicast 239.255.255.250 and 224.0.0.0/8 */
+    if (dst == htonl(0xEFFFFFFA) || (htonl(dst) & 0xFFFFFF00) == 0xE0000000)
     {
         my_log(LOG_NOTICE, 0, "The IGMP message was local multicast. Ignoring.");
         return;

I can create a pull request if you are willing to accept this patch.

commented

This is also related to issue #54 and also to commit b445adb . See also some proposed solution in discussion b445adb#commitcomment-36374166 .

I agree with you that current implementation is not correct and cause problems for some setups, but I think that by default 239.255.255.250 address should not be filtered. On the other hand it seems that range 224.0.0.0/8 should be filtered by default.

As stated in that discussion, this filtering should be configurable and ideally with more granularity. So if you want to work on this, feel free to provide patch. But your current non-configurable patch is not something suitable for merging.

And one important note: igmpproxy uses raw sockets for receiving igmp packets from local network, which means that it bypass linux netfilter/iptables rules. So you cannot do filtering via iptables/nftables and the only option for filtering is to implement it in igmpproxy itself. Therefore I think support for configuring whitelist/blacklist of local client addresses, mutlicast addresses and source of multicast packets in igmpproxy via config file is the "proper" and universal solution.

Agreed, attaching patch for reference and for people running into same issue as I.
local_multicast.zip

I've been thinking about this yesterday. I think this should be split 2ways.
1st have a command line option (-l) to enable forwarding of this local multicast range. By default block it globally. When -l is specified adhere to 2.
2nd. have a whitelist/blacklist for mcgroups on the upstream interface(s). Because of the dynamic nature of mc I think both need to be done. Parse wl first, then bl. This will then allow for allowing 224.0.0.0/4, but blokcing 224.0.0.0/8 (if -l option is specified).

I think both should not be extremely hard to implement, however I am only able to test on FreeBSD.

commented

Whole configuration of igmpproxy is done via config file, so please do not add a new command line option, but rather add option into config file.

About whitelisting/blacklisting, I was thinking about specifying series of commands: allow block1, deny block2, deny block3, allow block4.... for specific interface.

Also it should be per interface and perl all interfaces, not only upstream. So to have ability for some reasons to forward block1 to downstream network1 and disallow forwarding block1 do downstream network2.

For pfSense 2.4.5 users, I have implemented Uglymotha's patch for myself to fix an IPTV issue. The changes and a compiled binary is available here (use at your own risk, or compile it yourself): https://github.com/rhelgeby/igmpproxy/releases/tag/0.2.1.1

It's based on this commit: rhelgeby@f71ba40

When igmpproxy eventually get support for both whitelist and blacklist filters, this issue will be solved properly in the configuration.

commented

I hope that this issue is now fixed by introduction of whilelist and backlist filters done few months ago by pull request #83