unsealed counsel
08 Jan 2022

VyOS pimd setup for SSDP and DLNA

Setting up SSDP propagation between two VLANs on the same physical interface turned out to be more challenging than expected.

Consider the following network topology:

music-dlna-layout.svg

Both the music players are SSDP publishers and SSDP receivers. The minidlna instance is an SSDP source and the controllers are just receivers. SSDP traffic is published on 239.255.255.250 on all of the sources and must be received by all the sinks.

1. IGMP proxy

Since these are on different VLANs, the most straightforward idea would be to use igmp proxy, per VyOS documentation. However, no amount of configuration could get SSDP (also known as UPnP) traffic to be proxied between VLANs. The most common cause of failed multicast routing is low TTL values on those IP packets, but even with a TTL of 64, there was no forwarding.

After a day of trying to figure it out, I started looking at the code for igmp proxy directly. Looking at the code did not yield any solutions. The code was pretty straightforward with very low potential for bugs. At this point, I was out of ideas. More out of desperation than anything else, I started looking through the git repository's history for any references to SSDP. Eventually, I found some code that specifically blacklisted UPnP traffic. This code was present in v0.3 in debian repos, and was hence part of the rolling Sagitta VyOS release that I used to test. It was removed in a later commit but is, as of now, not part of any debian build, and hence not of any VyOS build either.

Having given up on igmp proxy, the only other alternative within the VyOS universe was to use pimd. Igmp proxy may become viable once that project makes a new release.

2. pimd setup

Looking at the VyOS documentation for pim, it seemed very straightforward to use a dummy interface to set up pimd:

set interfaces dummy dum0 address '10.100.91.1/24'
set interfaces ethernet eth1 vif 64 address '10.100.64.1/24'
set interfaces ethernet eth1 vif 66 address '10.100.66.1/24'
set interfaces ethernet eth1 vif 68 address '10.100.68.1/24'
set protocols ospf area 0 network '10.100.64.0/24'
set protocols ospf area 0 network '10.100.66.0/24'
set protocols ospf area 0 network '10.100.68.0/24'
set protocols ospf area 0 network '10.100.91.0/24'
set protocols pim interface dum0
set protocols pim interface eth1.64
set protocols pim interface eth1.66
set protocols pim interface eth1.68
set protocols pim rp address 10.100.91.1 group '224.0.0.0/4'

Everything seemed to be set up correctly:

vyos@vyos:~$ show ip pim interfaces
Interface         State          Address  PIM Nbrs           PIM DR  FHR IfChannels
dum0                 up      10.100.91.1         0            local    0          0
eth1.64              up      10.100.64.1         0            local    0          0
eth1.66              up      10.100.66.1         0            local    0          0
eth1.68              up      10.100.68.1         0            local    0          0
pimreg               up          0.0.0.0         0            local    0          0
vyos@vyos:~$ show ip pim rp
RP address       group/prefix-list   OIF               I am RP    Source
10.100.91.1      224.0.0.0/4         dum0              yes        Static

Sources of IGMP traffic were also identified correctly:

vyos@vyos:~$ show ip pim state
Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN, M -> Muted
Active Source           Group            RPT  IIF               OIL
1      10.100.64.11     239.255.255.250  n    eth1.64           pimreg( J   )
1      10.100.68.11     239.255.255.250  n    eth1.68           pimreg( J   )
1      10.100.68.12     239.255.255.250  n    eth1.68           pimreg( J   )

Multicast traffic was also received on the physical ethernet interface. IGMP joins could also be seen:

vyos@vyos:~$ sudo tcpdump -i eth1 igmp -vvv
tcpdump: listening on eth1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
21:40:25.552863 IP (tos 0xc0, ttl 4, id 0, offset 0, flags [DF], proto IGMP (2), length 40, options (RA))
    10.100.68.12 > igmp.mcast.net: igmp v3 report, 1 group record(s) [gaddr 239.255.255.250 to_in { }]
21:40:25.849373 IP (tos 0xc0, ttl 4, id 0, offset 0, flags [DF], proto IGMP (2), length 40, options (RA))
    10.100.68.12 > igmp.mcast.net: igmp v3 report, 1 group record(s) [gaddr 239.255.255.250 to_in { }]
21:40:41.889771 IP (tos 0xc0, ttl 4, id 0, offset 0, flags [DF], proto IGMP (2), length 40, options (RA))
    10.100.68.12 > igmp.mcast.net: igmp v3 report, 1 group record(s) [gaddr 239.255.255.250 to_ex { }]
21:40:42.230071 IP (tos 0xc0, ttl 4, id 0, offset 0, flags [DF], proto IGMP (2), length 40, options (RA))
    10.100.68.12 > igmp.mcast.net: igmp v3 report, 1 group record(s) [gaddr 239.255.255.250 to_ex { }]

In spite of all of this, no multicast traffic was seen on any of the receiver VLAN interfaces. It appeared that pimd did not see those IGMP requests:

vyos@vyos:~$ show ip pim join
Interface        Address         Source          Group           State      Uptime   Expire Prune

At this point, I spent quite a bit of time trying to figure out FRR debug logging to try to understand what was going on. I had reached another impasse, just as I had with igmp proxy. Once again, out of desperation, I asked for help on the VyOS forum. Dimitry Eshenko from the VyOS team spotted the problem:

IGMP was not enabled for interfaces that receive IGMP joins.

With the following configuration, PIM finally started working:

set protocols igmp interface eth1.64 version 3
set protocols igmp interface eth1.66 version 3
set protocols igmp interface eth1.68 version 3

This requirement was stated in the documentation for set protocols igmp interface but was not part of the example which used a dummy interface, since none of the interfaces in the example router with the PIM interface actually received IGMP joins. A simpler example, like the preceding, for the very common case of a single router would have been more helpful.

Tags: vyos pimd multicast dlna
Creative Commons License
runes.lexarcana.com by Ravi R Kiran is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License .