Subject: Re: Various strange things with ipv6 local multicast forwarding

From: Erik Slagter <[email-masked]>
Date: Sun, 01 Feb 2009 11:57:43 +0100

Todd Hayton wrote:

>> 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 :-/
> 
> This was my impression as well. From your setup your machine is not
> really acting as a multicast router per-se where you forward traffic
> received on interface A onto interfaces B, C, D...

Indeed. But how, am I asking myself, is one supposed to supply all real 
multicast routers with a stream... I guess somewhere a streaming server 
is required. This will only work (with linux) if the server only has one 
interface in use OR the serving application does the "multicasting" at 
application level (i.e. open multiple sockets and send the packets on 
them one by one) :-(

> My impression is
> that when you are sourcing the traffic you can only send it out of one
> interface (assuming you're doing only one call to sendto()). In fact,
> options like IP_MULTICAST_IF and IPV6_MULTICAST_IF let you specify an
> outgoing interface, but they only let you specify one outgoing
> interface.

This is actually not a problem in my opinion. These setsockopts are 
meant to be used by the multicast source application. Actually I want to 
have the multicast forwarding working without involvement of the source 
application, and imho it should work exactly like that. Kernel receives 
a packet from either an interface or internally generated (= lo?) and 
THEN applies the multicast routing for multicast destinations, simple as 
that!? My problem is that the kernel also uses and applies the normal 
routing table (with these strange ff00::/8 entries for each interface).

> My understanding was that when you are sending traffic the
> normal IP routing table is used to determine the outgoing interface.

Yes indeed. And I don't like that (for multicast traffic).

> In fact, on FreeBSD systems I've worked on you have to explicitly add
> a route to be able to send multicast traffic out of an interface (eg
> "route add -inet6 -net ff15:: -prefixlen 16 -interface le0") otherwise
> sendto() fails with "network is unreachable".

On linux it's exactly the same, the difference is that the multicast 
entries "pop up" automatically for each interface. But if you remove 
them, all kinds of apps that rely on multicasting (not per se multicast 
ROUTING) start to fail.

> As you've seen, the multicast route downloaded (via MFC_ADD) needs the
> incoming interface that the traffic is received on. Generally a
> multicast route doesn't get downloaded to the kernel *until* traffic
> starts showing up on some interface. The traffic then generates an
> upcall which is sent to the user space process which can then look at
> the traffic being sent and decide whether or not to download a route
> into the kernel (using MRT6_ADD_MFC). The decision on whether or not
> to download would be based on whether there were any interested
> receivers - which your application would know because it's monitoring
> the MLD reports.

Yes, I have that in consideration indeed. The absence of a multicast 
"cache" route or having a multicast "cache" route with no destination 
interfaces does not yield what's expected. In this case the normal 
routing table is consulted instead of the packet being dropped.

> Since you're not receiving the traffic from some other host, maybe you
> could make it look like you are to the kernel by connecting two of
> your interfaces back to back (say eth1 connects to eth2) using a
> crossover cable and then enabling multicasting on one of them (using
> MRT6_ADD_MIF) and then actually sending traffic out of the other one.
> This traffic then gets looped back onto the MIF, generates an upcall
> which your userland application gets and can then decide whether or
> not it wants to add a route for the traffic...Dunno if this setup
> would work but it's one idea...

Nah, that's too much a hack on a hack for me. I will try to work around 
the problems in userspace, I will even try to do some kernel hacking and 
I expect to have an acceptable setup in the end, although maybe with 
some workarounds (like the "dummy" interface).

Thanks for your efford.

I'd still like to have some comment from some of the netdev developers 
though... I think the whole thing is so overcomplicated. I would be very 
pleased with a simple mechanism, a "multicast" route in the normal 
routing table, that has multiple (interface) destinations. If you'd have 
a static setup, you wouldn't even need to have a multicast routing 
application to have it working, "ip route add" would suffice...