Subject: Various strange things with ipv6 local multicast forwarding

From: Erik Slagter <[email-masked]>
Date: Fri, 30 Jan 2009 14:42:13 +0100

Hi All,

I am using a very simple setup: a linux server (linux 2.6.28.2, amd64) 
with 12 nics, almost each connected host has a nic uniquely to itself. 
On the server a program is running (poc-2250 to be precise) that streams 
data to multicast address ff05::4242. This data should be forwarded by 
the kernel to all interfaces that have hosts that are joined to 
ff05::4242. As it is such a simple setup, I do not want to use PIM nor a 
router application featuring PIM, I am using MLD messages only. I've 
written a very simple "MRT6_INIT" app that catches MLD messages and 
kernel upcalls, and joins interfaces on demand. This works :-)

I have had a very hard time with the kernel upcalls, but that problem 
has been solved with the recent "unnecessary skb_pull" patch I found 
here, THANKS! (Hi Todd ;-))

I now have still a few things that do not completely go like I want to 
or like I expect to. Can please someone clarify for me?

1: Next scenario:
    - Start streaming application (poc-2250)
         Now all packets go to a random interface, I cannot understand 
the logic, but most of the time it appears to be dummy0, which actually 
is a good thing. I guess it has something to do with the ff00:/8 routes 
in the "normal" routing table, from which the kernel selects one using 
some criterium. Tshark reveals the packets sent on dummy0 indeed.
    - Start "MRT6_INIT" app
    - This gets an upcall message from the kernel (which I can 
understand) for the above mc group.
    - App installs a "MFC_ADD" mcast route with the parameters from the 
upcall, with NO interfaces. My goal is to silence the streaming 
application until the stream is requested.
    - mc route gets installed OK
    - YET packets still appear on dummy0 (tshark and counters) and the 
"Wrong" (interface) counter in /proc/net/ipv6_mr_cache starts to increment.

This is not what I want and not what I expect. I expect the packets to 
be discarded if nobody is listening. I now have to run a "dummy" 
interface to drain unused packets.

    - Most of the time this more or less works, but when for a few hours 
only one interface has been joined to the mc route, a "ghost" route 
appears, which routes the packets for the multicast group directly to 
this interface, so the multicast routing system is not consulted anymore 
(counters remain steady). The route cannot be seen using "ip -6 route" 
BUT it can be deleted using "ip -6 route ff05::4242" but only when the 
multicast streaming app has been stopped. Also, the command must be 
given several times before the route is "not found".

I cannot see the logic behind this and also this is very annoying, as 
this way the mc packets always appear on this interface from this point, 
regardless whether the client on this interface has joined the group.

I already once removed all mc routes from the route table, but that 
makes the complete box fail miserably :-/

2: When a client wants to join, it sends a MLDv2 message (in my case, 
it's all linux). I catch the message and incoming interface info using 
IPV6_PKTINFO. This yields not enough information to add the client to 
the mr cache though, MFC_ADD needs a "source" interface index and 
address (and cannot use a wildcard, according to the kernel source :-(). 
At this stage I retrieve these by requesting the kernel for the route to 
multicast address (ff05::4242) which until now has been working well, 
but still I believe it's a dirty hack. There must be a more 
elegant/appropriate way to achieve this?

Somehow I get the impression the ip6 multicast routing code in the 
kernel is more targeted at multicast forwarding packets from outside the 
box than packets locally generated :-/

Thanks for your help in advance!