DLNA, UPnP and multicast routing

I have a problem which is probably unusual in most home networks, which is that I have multiple subnets coming off one of my LAN interfaces on my router.  For most IP-routed things, this is obviously not a problem, but there is seemingly one exception to this rule, and that is multicast packets.

Multicast (which is a way of sending a packet once and many machines receiving the same packet simultaneously, so you don’t have to send the packets to every machine individually) isn’t very well understood by many people in the IPv4 world, because firstly it’s optional, and secondly hardly anyone seems to use  it.  In contrast, IPv6 effectively makes the use of multicast compulsory because it is used extensively by IPv6 itself, as well as protocols which run on top of it, even if only at the link-local level to other machines that can be reached without a router.

A few weeks ago, I decided to try and make my home router (which is built on Debian) into a multicast-capable router, both IPv4 and IPv6.  Not knowing an awful lot about this subject, other than it doesn’t “just work” despite the Linux kernel having multicast support built in, I started to Google.  It would appear that I need to run programs on top of the kernel that supports IGMP for IPv4, and MLD for IPv6, and both need to support PIM as well, which appears to be the multicast equivalent of things like OSPF and RIP, which do the dynamic routing.  (Although this seems bit like overkill since my LAN only has one router, but there you are.)

Debian doesn’t seem to have a lot of choice on which programs to use, but I narrowed it down to pimd (which works with IPv4 only) and mrd6 (which works with IPv6 only).  So far so good.  I configured the programs with a configuration that I thought worked, and started up the daemons, which appeared to work, and thought no more about it.

Until…

I wanted to play a few tracks from my DLNA server.  For those not familiar, DLNA (or UPnP AV Specification) servers use Universal Plug and Play to advertise themselves.  In IPv4, this is done by sending packets to the multicast address 239.255.255.250 and in IPv6 this is done by sending packets to ff0x::c (where x is the scope ID).  So, had my configuration of pimd actually worked (we’ll have to ignore mrd6 for the minute because my mediatomb DLNA server does not support IPv6, and I can’t find an open-source DLNA server that does yet) this should have “just worked”,  because the router would have routed the packets between the network my server was on, and the network my client was on.  But it wasn’t working.  But the $64 million question was why  on earth not?

The answer turned out to be a little obscure, but worth noting nonetheless (and almost certainly had the DLNA server and client been listening on IPv6 this would never have broken).  After doing a bit of investigating and searching the Web (and also trying and failing to get upnpproxy and igmpproxy to work), it would appear the problem was that my ‘servers’ network interface had not one subnet on it, but three subnets.  This appeared to confuse pimd into not knowing what to route where.

The solution was to tell pimd specifically which other subnets were on the same interface.  You can do this by specifiying the altnet keyword in the phyint interface definitions in the /etc/pimd.conf file, as in this example:

phyint eth0 enable altnet 10.10.10.0/24 altnet 10.11.12.0/24

To make this work, I had to put in an altnet parameter for every extra IPv4 address range I had on the same interface, otherwise nothing else will see it.  Normally, you wouldn’t need this parameter if you have exactly one IPv4 subnet parameter per interface, but it’s necessary if you have more than one so that pimd knows which subnets should be accepted from which interface.

Problem solved!

Well, nearly.  This works on most clients, but it would appear even Microsoft’s own UPnP AV/DLNA client in Windows Media Player doesn’t even bother to use multicast, and the UPnPlay app on Android 6.0.1 also does not work (although this may be because multicast sockets in Android are probably still broken, so this would affect all apps).  However, my Panasonic TV works fine with it, so does Kodi for Windows, so I’m happy enough for now.  I have my tunes back.