Issue with igmpproxy in separated guest network

Hello everyone,
I set up an openwrt device to share an internet connection and IPTV between two apartments. The device is a FritzBox 7362 SL running OpenWrt 19.07.7. The "main" interface (main apartment) is using switch ports LAN 2..4 with untagged VLAN 2. On this interface the openwrt device gets an IP from the main router via dhcp in the 192.168.2.x range. A WiFi AP is bridged to the same interface. LAN port 1 is assigned to untagged VLAN 1. On this "guest" (guest apartment) interface the openwrt device has a static IP 192.168.1.1 and serves DHCP and DNS. There are firewall configs for NAT and for preventing access to the main network from the guest network. I roughly followed this guide. This all works flawlessly and I learned a lot setting it up.

The remaining issue is with IPTV (Deutsche Telekom Magenta), which does not work in the guest network. You can browse channels and start watching but after five seconds of watching the stream switches from unicast to multicast, the picture stutters and comes to a halt. I have installed and configured igmpproxy and I can see the IPTV receiver talking to the openwrt device as well as the openwrt device relaying the igmp into the main network. But the logs and packets are confusing too me. It looks like the receiver tries again and again to join the multicast group?!

The issue is visible in the following logs. In the guest network the IPTV receiver is 192.168.1.191 and the openwrt device is 192.168.1.1. In the main network the openwrt device is 192.168.2.180 and the main router (connected to the internet) is 192.168.2.1.

I would greatly appreciate your help in figuring this out!
Stefan

network config

root@OpenWrt:~# cat /etc/config/network

[...]

config switch
        option name 'switch0'
        option reset '1'
        option enable_vlan '1'

config switch_vlan
        option device 'switch0'
        option vlan '1'
        option vid '1'
        option ports '4 6t'

config switch_vlan
        option device 'switch0'
        option vlan '2'
        option vid '2'
        option ports '0 1 2 6t'

config interface 'if_main'
        option proto 'dhcp'
        option type 'bridge'
        option ipv6 '0'
        option igmp_snooping '1'
        option ifname 'eth0.2'

config interface 'if_guest'
        option ifname 'eth0.1'
        option proto 'static'
        option ipaddr '192.168.1.1'
        option netmask '255.255.255.0'
        option ipv6 '0'

firewall config

root@OpenWrt:~# cat /etc/config/firewall

config defaults
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'REJECT'
        option synflood_protect '1'

config include
        option path '/etc/firewall.user'

config zone
        option network 'if_main'
        option input 'ACCEPT'
        option name 'fw_main'
        option output 'ACCEPT'
        option forward 'ACCEPT'

config zone
        option network 'if_guest'
        option input 'ACCEPT'
        option name 'fw_guest'
        option output 'ACCEPT'
        option forward 'REJECT'

config forwarding
        option dest 'fw_main'
        option src 'fw_guest'

config nat
        option src 'fw_main'
        option name 'guest_internet'
        option target 'MASQUERADE'
        list proto 'all'

config rule
        option src 'fw_guest'
        option name 'guest_no_main'
        option dest 'fw_main'
        option target 'DROP'
        list dest_ip '192.168.2.1/24'
        list proto 'all'

wireless config

config wifi-device 'radio0'
	option type 'mac80211'
	option hwmode '11g'
	option path 'pci0000:00/0000:00:00.0/0000:01:00.0'
	option htmode 'HT40'
	option channel 'auto'

config wifi-iface 'default_radio0'
	option device 'radio0'
	option mode 'ap'
	option network 'if_main'
	option key [...]
	option ssid [...]
	option encryption 'psk2'

igmpproxy config

config igmpproxy
        option quickleave 1
#       option verbose 3
#       option verbose [0-3](none, minimal[default], more, maximum)

config phyint
        option network 'if_main'
        option zone 'fw_main'
        option direction upstream
        list altnet 0.0.0.0/0

config phyint
        option network 'if_guest'
        option zone 'fw_guest'
        option direction downstream

Even if you do not know the solution, any tips on what else to check or other places to ask for help are appreciated, thank you!

Start with a tcpdump on the upstream interface, see if you are getting the multicast packets delivered to the upstream side. If so you may need to adjust the TTL field of these packets so they can be routed down to the guest side

Thank you! I made some progress. By accident I realized an IPTV channel in the guest network is working fine if someone watches the same channel in the main network. I verified this for multiple channels and also by watching a channel (in the main network) with VLC (e.g. "rtp://87.141.215.251@232.0.20.234:10000"). I can see the packets coming in on the main network and the stream works without any issue in the guest network. But without watching the channel via VLC or the main network receiver the problem persists. The forwarding of the multicast packets apparently works.

The IPTV receiver in the guest network does report its wish to join the multicast group (igmp v2):

17:42:25.003343 IP (tos 0x60, ttl 1, id 0, offset 0, flags [DF], proto IGMP (2), length 32, options (RA))
    192.168.1.191 > 232.0.20.234: igmp v2 report 232.0.20.234

And the OpenWRT device does forward the group join (igmp v3):

19:14:12.091131 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP (2), length 40, options (RA))
    192.168.2.180 > 224.0.0.22: igmp v3 report, 1 group record(s) [gaddr 232.0.20.234 to_ex { }]

The group join does not work, though, and it looks different to the reports by VLC (which do work):

21:02:45.223977 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP (2), length 52, options (RA))
    192.168.2.118 > 224.0.0.22: igmp v3 report, 2 group record(s) [gaddr 232.0.20.234 is_in { 87.141.215.251 }] [gaddr 224.0.0.251 is_ex { }]

23:01:37.721601 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP (2), length 44, options (RA))
    192.168.2.118 > 224.0.0.22: igmp v3 report, 1 group record(s) [gaddr 232.0.20.234 block { 87.141.215.251 }]

23:01:42.361612 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP (2), length 44, options (RA))
    192.168.2.118 > 224.0.0.22: igmp v3 report, 1 group record(s) [gaddr 232.0.20.234 allow { 87.141.215.251 }]

It seems the source address (87.141.215.251) is missing from the reports by igmpproxy.

What I do not understand is: why does the IPTV receiver in the guest network use igmp v2, it is the only device attached (direct cable to OpenWRT device, no other LAN ports or WLAN connections). And why does igmpproxy translate the igmp v2 request to igmp v3 but with missing source address?

Any help would be greatly appreciated!

I'm not quite following. Can you show the Internal and external packets for join from regular LAN and then from GUEST

Hi,
here are packets from regular (main via vlc on notebook computer ...2.118):

23:01:37.721601 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP (2), length 44, options (RA))
    192.168.2.118 > 224.0.0.22: igmp v3 report, 1 group record(s) [gaddr 232.0.20.234 block { 87.141.215.251 }]
23:01:38.428293 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP (2), length 44, options (RA))
    192.168.2.118 > 224.0.0.22: igmp v3 report, 1 group record(s) [gaddr 232.0.20.234 block { 87.141.215.251 }]
23:01:42.361612 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP (2), length 44, options (RA))
    192.168.2.118 > 224.0.0.22: igmp v3 report, 1 group record(s) [gaddr 232.0.20.234 allow { 87.141.215.251 }]
23:01:43.171650 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP (2), length 44, options (RA))
    192.168.2.118 > 224.0.0.22: igmp v3 report, 1 group record(s) [gaddr 232.0.20.234 allow { 87.141.215.251 }]
23:01:47.198314 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP (2), length 52, options (RA))
    192.168.2.118 > 224.0.0.22: igmp v3 report, 2 group record(s) [gaddr 232.0.20.234 is_in { 87.141.215.251 }] [gaddr 224.0.0.251 is_ex { }]

From the internal (IPTV receiver ...1.191 in guest) packet to join is:

17:42:25.003343 IP (tos 0x60, ttl 1, id 0, offset 0, flags [DF], proto IGMP (2), length 32, options (RA))
    192.168.1.191 > 232.0.20.234: igmp v2 report 232.0.20.234

which triggers the external (main via igmpproxy on openwrt ...2.180):

19:14:12.091131 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP (2), length 40, options (RA))
    192.168.2.180 > 224.0.0.22: igmp v3 report, 1 group record(s) [gaddr 232.0.20.234 to_ex { }]

I hope that is the correct info, I want to have another look tomorrow and could get more data.

Good night form Germany!

Ok, I think I have found the issue. I performed the following tests in the main network, neither the openwrt device nor igmpproxy were involved.

When I try to watch the stream on VLC without giving the source (rtp://@232.0.20.234:10000), the IGMP messages sent by VLC have the same format as the ones by igmpproxy:

13:00:02.851814 IP (tos 0x0, ttl 1, id 30038, offset 0, flags [none], proto IGMP (2), length 40, options (RA))
    192.168.2.4 > 224.0.0.22: igmp v3 report, 1 group record(s) [gaddr 232.0.20.234 to_ex { }]

Which, as I understand, means: "I want to join the group 232.0.20.234 and I do not exclude any source addresses".

This does not work, no picture is shown and no packets are visible with tcpdump -n "multicast and dst 232.0.20.234".

When I try to watch the stream on VLC with giving the source (rtp://87.141.215.251@232.0.20.234:10000), the IGMP messages include it as well:

13:04:29.923734 IP (tos 0x0, ttl 1, id 14649, offset 0, flags [none], proto IGMP (2), length 44, options (RA))
    192.168.2.4 > 224.0.0.22: igmp v3 report, 1 group record(s) [gaddr 232.0.20.234 allow { 87.141.215.251 }]

This does work, picture is shown and many packets are visible with tcpdump -n "multicast and dst 232.0.20.234".

So I guess the question is, how do I get igmpproxy to include the source address? As I understand, right now it can only send igmp v2 queries, so the IPTV receiver in the guest network answers with an igmp v2 report, which does not include the source address. Is there maybe a way to set a default source address to be included in the upstream reports?

So I hard coded the source address into the specific function "k_join" in igmpproxy and recompiled:

    // imgp v2 join without source
    // struct ip_mreq mreq;

    // multicast request with source
    struct ip_mreq_source mreq;

    mreq.imr_multiaddr.s_addr = grp;
    mreq.imr_interface.s_addr = ifd->InAdr.s_addr;

    // add source Telekom Magenta / Entertain
    mreq.imr_sourceaddr.s_addr = inet_addr("87.141.215.251");

    my_log(LOG_NOTICE, 0, "Joining group %s on interface %s", inetFmt(grp, s1), ifd->Name);

    // old igmp v2 join
    // if (setsockopt(MRouterFD, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0)

    // new igmp v3 join
    if (setsockopt(MRouterFD, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0)

Which worked, igmpproxy now sends the reports with the hard coded source IP:

17:18:04.485425 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP (2), length 44, options (RA))
    192.168.2.180 > 224.0.0.22: igmp v3 report, 1 group record(s) [gaddr 232.0.20.135 to_in { 87.141.215.251 }]

Somehow streaming still does not work, but that is at least some progress for today.

Is VLC setup to multicast to another network?

I am not using VLC to cast anything anywhere, you probably misunderstood.

Yesterdays solution was correct, I merely forgot that the init script in the igmpproxy opkg would add the firewall rules to forward the multicast traffic, so they were missing.

I reinstalled the opkg and replace the igmpproxy binary with a modified one, that adds the source IP (igmp v3) when joining in upstream direction. IPTV now works perfectly in the guest network, finally.

I hope if anyone stumbles upon this trying to solve the same problem, igmpproxy supporting igmp v3 will be not too far into the future. If it would, this whole problem would never have appeared. IGMP v3 is almost 20 years old, so cross your fingers. My solution is ugly and only works because the source IP for all streams is fix and the same.

One more remark: Both here in the forum and in the wiki it is recommended to set the TTL for multicast packets, so they can be routed. This might not be necessary, in my case the packets came to the router with ttl between 20 and 22. Also, if you want to use the rule given in the wiki you will have to opkg install iptables-mod-ipopt first - otherwise the rule fails more or less silently.

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.