Multicast for IPTV

Hi!

There is a DIR-615 router that works with an IPTV set-top box out of the box.
With OpenWrt 23.05.4 r24012-d8dd03c46f, IPTV does not work.

There is a manual: https://openwrt.org/docs/guide-user/network/wan/udp_multicast

What I did:

cat /etc/config/igmpproxy
config igmpproxy
        option quickleave 1
        option verbose 3

config phyint
        option network wan
        option zone wan
        option direction upstream
        list altnet 0.0.0.0/0

config phyint
        option network lan
        option zone lan
        option direction downstream

cat /etc/config/network

config interface 'loopback'
        option device 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config globals 'globals'
        option ula_prefix 'fd17:ec76:f140::/48'

config device
        option name 'br-lan'
        option type 'bridge'
        option igmp_snooping 1
        list ports 'lan2'
        list ports 'lan3'
        list ports 'lan4'

config interface 'lan'
        option device 'br-lan'
        option proto 'static'
        option ipaddr '192.168.1.1'
        option netmask '255.255.255.0'
        option ip6assign '60'

config device
        option name 'wan'
        option macaddr '4c:c6:4c:a2:40:77'

config interface 'wan'
        option device 'wan'
        option proto 'dhcp'

config interface 'wan6'
        option device 'wan'
        option proto 'dhcpv6'
cat /sys/devices/virtual/net/br-lan/bridge/multicast_snooping
1
ps | grep igmp
 4377 root       972 S    /usr/sbin/igmpproxy -n -v -v /var/etc/igmpproxy.conf
 4678 root      1316 S    grep igmp
nft list ruleset | grep 224
meta l4proto udp ip daddr 224.0.0.0/4 counter packets 0 bytes 0 jump accept_to_lan comment "!fw4: ubus:igmpproxy[instance1] rule 2"
nft list ruleset | grep 239
meta l4proto udp ip daddr 239.255.255.250 counter packets 0 bytes 0 jump drop_to_lan comment "!fw4: ubus:igmpproxy[instance1] rule 1"
logread | grep igmpproxy
Fri Jan  3 14:50:46 2025 user.debug igmpproxy[4377]: No routes in table...
Fri Jan  3 14:50:46 2025 user.debug igmpproxy[4377]: -----------------------------------------------------
Fri Jan  3 14:50:47 2025 user.notice igmpproxy[4377]: RECV V2 member report   from 192.168.1.1     to 224.0.0.22
Fri Jan  3 14:50:47 2025 user.notice igmpproxy[4377]: The IGMP message was from myself. Ignoring.
Fri Jan  3 14:50:50 2025 user.notice igmpproxy[4377]: RECV V2 member report   from 192.168.1.1     to 224.0.0.2
Fri Jan  3 14:50:50 2025 user.notice igmpproxy[4377]: The IGMP message was from myself. Ignoring.
Fri Jan  3 14:50:51 2025 user.notice igmpproxy[4377]: RECV V2 member report   from 192.168.1.1     to 224.0.0.106
Fri Jan  3 14:50:51 2025 user.notice igmpproxy[4377]: The IGMP message was from myself. Ignoring.
Fri Jan  3 14:50:54 2025 user.debug igmpproxy[4377]: About to call timeout 42 (#0)
Fri Jan  3 14:50:54 2025 user.debug igmpproxy[4377]: SENT Membership query   from 192.168.1.1     to 224.0.0.1
Fri Jan  3 14:50:54 2025 user.debug igmpproxy[4377]: Sent membership query from 192.168.1.1 to 224.0.0.1. Delay: 10
Fri Jan  3 14:50:54 2025 user.debug igmpproxy[4377]: Created timeout 43 (#0) - delay 10 secs
Fri Jan  3 14:50:54 2025 user.debug igmpproxy[4377]: (Id:43, Time:10)
Fri Jan  3 14:50:54 2025 user.debug igmpproxy[4377]: Created timeout 44 (#1) - delay 115 secs
Fri Jan  3 14:50:54 2025 user.debug igmpproxy[4377]: (Id:43, Time:10)
Fri Jan  3 14:50:54 2025 user.debug igmpproxy[4377]: (Id:44, Time:115)
Fri Jan  3 14:50:54 2025 user.notice igmpproxy[4377]: RECV Membership query   from 192.168.1.1     to 224.0.0.1
Fri Jan  3 14:50:56 2025 user.notice igmpproxy[4377]: RECV V2 member report   from 192.168.1.1     to 224.0.0.106
Fri Jan  3 14:50:56 2025 user.notice igmpproxy[4377]: The IGMP message was from myself. Ignoring.
Fri Jan  3 14:50:59 2025 user.debug igmpproxy[4377]: About to call timeout 43 (#0)
Fri Jan  3 14:50:59 2025 user.debug igmpproxy[4377]: Aging routes in table.
Fri Jan  3 14:50:59 2025 user.debug igmpproxy[4377]:
Fri Jan  3 14:50:59 2025 user.debug igmpproxy[4377]: Current routing table (Age active routes):
Fri Jan  3 14:50:59 2025 user.debug igmpproxy[4377]: -----------------------------------------------------
Fri Jan  3 14:50:59 2025 user.debug igmpproxy[4377]: No routes in table...
Fri Jan  3 14:50:59 2025 user.debug igmpproxy[4377]: -----------------------------------------------------
Fri Jan  3 14:51:02 2025 user.debug igmpproxy[4377]: About to call timeout 44 (#0)
Fri Jan  3 14:51:02 2025 user.debug igmpproxy[4377]: SENT Membership query   from 192.168.1.1     to 224.0.0.1
Fri Jan  3 14:51:02 2025 user.debug igmpproxy[4377]: Sent membership query from 192.168.1.1 to 224.0.0.1. Delay: 10
Fri Jan  3 14:51:02 2025 user.debug igmpproxy[4377]: Created timeout 45 (#0) - delay 10 secs
Fri Jan  3 14:51:02 2025 user.debug igmpproxy[4377]: (Id:45, Time:10)
Fri Jan  3 14:51:02 2025 user.debug igmpproxy[4377]: Created timeout 46 (#1) - delay 115 secs
Fri Jan  3 14:51:02 2025 user.debug igmpproxy[4377]: (Id:45, Time:10)
Fri Jan  3 14:51:02 2025 user.debug igmpproxy[4377]: (Id:46, Time:115)
Fri Jan  3 14:51:02 2025 user.notice igmpproxy[4377]: RECV Membership query   from 192.168.1.1     to 224.0.0.1
Fri Jan  3 14:51:03 2025 user.notice igmpproxy[4377]: RECV V2 member report   from 192.168.1.1     to 224.0.0.22
Fri Jan  3 14:51:03 2025 user.notice igmpproxy[4377]: The IGMP message was from myself. Ignoring.
Fri Jan  3 14:51:03 2025 user.notice igmpproxy[4377]: RECV V2 member report   from 192.168.1.1     to 224.0.0.106
Fri Jan  3 14:51:03 2025 user.notice igmpproxy[4377]: The IGMP message was from myself. Ignoring.
Fri Jan  3 14:51:03 2025 user.notice igmpproxy[4377]: RECV V2 member report   from 192.168.1.1     to 224.0.0.2
Fri Jan  3 14:51:03 2025 user.notice igmpproxy[4377]: The IGMP message was from myself. Ignoring.
cat /proc/net/ip_mr_cache
Group    Origin   Iif     Pkts    Bytes    Wrong Oifs

TCP dump (192.168.1.57 - IP of the set-top box)

tcpdump -i br-lan igmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on br-lan, link-type EN10MB (Ethernet), snapshot length 262144 bytes
14:51:57.403111 IP 192.168.1.1 > igmp.mcast.net: igmp v2 report igmp.mcast.net
14:51:59.323140 IP 192.168.1.1 > all-routers.mcast.net: igmp v2 report all-routers.mcast.net
14:52:02.326495 IP 192.168.1.1 > all-systems.mcast.net: igmp query v2
14:52:05.346346 IP 192.168.1.57 > mdns.mcast.net: igmp v2 report mdns.mcast.net
14:52:05.643106 IP 192.168.1.1 > all-routers.mcast.net: igmp v2 report all-routers.mcast.net
14:52:06.203129 IP 192.168.1.1 > igmp.mcast.net: igmp v2 report igmp.mcast.net
14:52:07.243121 IP 192.168.1.1 > 224.0.0.106: igmp v2 report 224.0.0.106
14:52:12.232443 IP 192.168.1.1 > all-systems.mcast.net: igmp query v2
14:52:12.246675 IP 192.168.1.57 > mdns.mcast.net: igmp v2 report mdns.mcast.net
14:52:13.403079 IP 192.168.1.1 > 224.0.0.106: igmp v2 report 224.0.0.106
14:52:19.409756 IP 192.168.1.1 > all-systems.mcast.net: igmp query v2
14:52:19.603094 IP 192.168.1.1 > igmp.mcast.net: igmp v2 report igmp.mcast.net
14:52:22.123117 IP 192.168.1.1 > all-routers.mcast.net: igmp v2 report all-routers.mcast.net
14:52:23.483278 IP 192.168.1.1 > 224.0.0.106: igmp v2 report 224.0.0.106
14:52:26.356390 IP 192.168.1.57 > mdns.mcast.net: igmp v2 report mdns.mcast.net
14:52:29.489725 IP 192.168.1.1 > all-systems.mcast.net: igmp query v2
tcpdump -i wan net 224.0.0.0/4
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wan, link-type EN10MB (Ethernet), snapshot length 262144 bytes
15:14:09.797449 IP 172.16.33.1 > all-systems.mcast.net: igmp query v2
15:15:09.802222 IP 172.16.33.1 > all-systems.mcast.net: igmp query v2

This as well:

sysctl net.ipv4.conf.all.force_igmp_version
net.ipv4.conf.all.force_igmp_version = 2

These steps didn't yield results. Any ideas where to dig further?

IPTV is needed only over a wired connection, not via Wi-Fi.

Is your IPTV box provided by your ISP? Does it work if connected directly to the ISP router/modem/ONT device?

Yes, the IPTV box is provided by the ISP, and it works both directly and through the DIR-615 router.

You may want to basically just make 'pass-through' port for the wan to go to the STB.

You probably don't need anything else in your config to make this work beyond that pass-through.

Let's take a look at the current config:

Please connect to your OpenWrt device using ssh and copy the output of the following commands and post it here using the "Preformatted text </> " button:
grafik
Remember to redact passwords, MAC addresses and any public IP addresses you may have:

ubus call system board
cat /etc/config/network
cat /etc/config/wireless
cat /etc/config/dhcp
cat /etc/config/firewall
ubus call system board
{
        "kernel": "5.15.162",
        "hostname": "OpenWrt",
        "system": "ARMv8 Processor rev 4",
        "model": "Xiaomi Redmi Router AX6000 (stock layout)",
        "board_name": "xiaomi,redmi-router-ax6000-stock",
        "rootfs_type": "squashfs",
        "release": {
                "distribution": "OpenWrt",
                "version": "23.05.4",
                "revision": "r24012-d8dd03c46f",
                "target": "mediatek/filogic",
                "description": "OpenWrt 23.05.4 r24012-d8dd03c46f"
        }
}
cat /etc/config/network

config interface 'loopback'
        option device 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config globals 'globals'
        option ula_prefix 'fd17:ec76:f140::/48'

config device
        option name 'br-lan'
        option type 'bridge'
        option igmp_snooping 1
        list ports 'lan2'
        list ports 'lan3'
        list ports 'lan4'

config interface 'lan'
        option device 'br-lan'
        option proto 'static'
        option ipaddr '192.168.1.1'
        option netmask '255.255.255.0'
        option ip6assign '60'

config device
        option name 'wan'
        option macaddr '4c:c6:4c:a2:40:77'

config interface 'wan'
        option device 'wan'
        option proto 'dhcp'

config interface 'wan6'
        option device 'wan'
        option proto 'dhcpv6'
cat /etc/config/wireless

config wifi-device 'radio0'
        option type 'mac80211'
        option path 'platform/soc/18000000.wifi'
        option channel '1'
        option band '2g'
        option htmode 'HE20'
        option disabled '1'

config wifi-iface 'default_radio0'
        option device 'radio0'
        option network 'lan'
        option mode 'ap'
        option ssid 'OpenWrt'
        option encryption 'none'

config wifi-device 'radio1'
        option type 'mac80211'
        option path 'platform/soc/18000000.wifi+1'
        option channel '36'
        option band '5g'
        option htmode 'HE80'
        option cell_density '0'

config wifi-iface 'default_radio1'
        option device 'radio1'
        option network 'lan'
        option mode 'ap'
        option ssid 'OpenWrt'
        option encryption 'sae'
        option key '********'
cat /etc/config/dhcp                                                                                                                                                                                                  [12/1856]

config dnsmasq
        option domainneeded '1'
        option localise_queries '1'
        option rebind_protection '1'
        option rebind_localhost '1'
        option local '/lan/'
        option domain 'lan'
        option expandhosts '1'
        option cachesize '1000'  
        option authoritative '1'    
        option readethers '1'
        option leasefile '/tmp/dhcp.leases'
        option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
        option localservice '1'
        option ednspacket_max '1232'

config dhcp 'lan'
        option interface 'lan'
        option start '100'
        option limit '150'
        option leasetime '12h'
        option dhcpv4 'server'
        option dhcpv6 'server'
        option ra 'server'
        option ra_slaac '1'
        list ra_flags 'managed-config'
        list ra_flags 'other-config'

config dhcp 'wan'
        option interface 'wan'
        option ignore '1'

config odhcpd 'odhcpd'
        option maindhcp '0'
        option leasefile '/tmp/hosts/odhcpd'
        option leasetrigger '/usr/sbin/odhcpd-update'
        option loglevel '4'
cat /etc/config/firewall                                                                                                                                                                                                       
config defaults                                                                                                                                                                                                                                
        option syn_flood        1     
        option input            REJECT                     
        option output           ACCEPT
        option forward          REJECT
# Uncomment this line to disable ipv6 rules
#       option disable_ipv6     1

config zone
        option name             lan
        list   network          'lan'
        option input            ACCEPT
        option output           ACCEPT
        option forward          ACCEPT

config zone
        option name             wan
        list   network          'wan'
        list   network          'wan6'
        option input            REJECT
        option output           ACCEPT
        option forward          REJECT
        option masq             1
        option mtu_fix          1

config forwarding
        option src              lan
        option dest             wan

# We need to accept udp packets on port 68,
# see https://dev.openwrt.org/ticket/4108
config rule
        option name             Allow-DHCP-Renew
        option src              wan
        option proto            udp
        option dest_port        68
        option target           ACCEPT
        option family           ipv4

# Allow IPv4 ping
config rule
        option name             Allow-Ping
        option src              wan
        option proto            icmp
        option icmp_type        echo-request
        option family           ipv4
        option target           ACCEPT

config rule
        option name             Allow-IGMP
        option src              wan
        option proto            igmp
        option family           ipv4
        option target           ACCEPT

# Allow DHCPv6 replies
# see https://github.com/openwrt/openwrt/issues/5066
config rule
        option name             Allow-DHCPv6
        option src              wan
        option proto            udp
        option dest_port        546
        option family           ipv6
        option target           ACCEPT

config rule
        option name             Allow-MLD
        option src              wan
        option proto            icmp
        option src_ip           fe80::/10
        list icmp_type          '130/0'
        list icmp_type          '131/0'
        list icmp_type          '132/0'
        list icmp_type          '143/0'
        option family           ipv6
        option target           ACCEPT

# Allow essential incoming IPv6 ICMP traffic
config rule
        option name             Allow-ICMPv6-Input
        option src              wan
        option proto    icmp
        list icmp_type          echo-request
        list icmp_type          echo-reply
        list icmp_type          destination-unreachable
        list icmp_type          packet-too-big
        list icmp_type          time-exceeded
        list icmp_type          bad-header
        list icmp_type          unknown-header-type
        list icmp_type          router-solicitation
        list icmp_type          neighbour-solicitation
        list icmp_type          router-advertisement
        list icmp_type          neighbour-advertisement
        option limit            1000/sec
        option family           ipv6
        option target           ACCEPT

# Allow essential forwarded IPv6 ICMP traffic
config rule
        option name             Allow-ICMPv6-Forward
        option src              wan
        option dest             *
        option proto            icmp
        list icmp_type          echo-request
        list icmp_type          echo-reply
        list icmp_type          destination-unreachable
        list icmp_type          packet-too-big
        list icmp_type          time-exceeded
        list icmp_type          bad-header
        list icmp_type          unknown-header-type
        option limit            1000/sec
        option family           ipv6
        option target           ACCEPT

config rule
        option name             Allow-IPSec-ESP
        option src              wan
        option dest             lan
        option proto            esp
        option target           ACCEPT

config rule
        option name             Allow-ISAKMP
        option src              wan
        option dest             lan
        option dest_port        500
        option proto            udp
        option target           ACCEPT

Ok... here's what I'd recommend... assuming that the IPTV box doesn't expect any tagged VLANs:

Edit br-lan to look like this (we'll remove IGMP snooping, and add the wan port):

config device
        option name 'br-lan'
        option type 'bridge'
        list ports 'lan2'
        list ports 'lan3'
        list ports 'lan4'
        list ports 'wan'

Create two bridge-VLANs:

config bridge-vlan
        option device 'br-lan'
        option vlan '1'
        list ports 'lan2:u*'
        list ports 'lan3:u*'

config bridge-vlan
        option device 'br-lan'
        option vlan '2'
        list ports 'lan4:u*'
        list ports 'wan:u*'

Now, edit the lan interface to use br-lan.1:

config interface 'lan'
        option device 'br-lan.1'
        option proto 'static'
        option ipaddr '192.168.1.1'
        option netmask '255.255.255.0'
        option ip6assign '60'

And edit the wan and wan6 to use br-lan.2:

config interface 'wan'
        option device 'br-lan.2'
        option proto 'dhcp'

config interface 'wan6'
        option device 'br-lan.2'
        option proto 'dhcpv6'

Restart the router after these changes. Connect the IPTV box to port lan4 and test.