Bug 12646

Summary: IGMP reports not sent if no multicast route
Product: Base System Reporter: kbracey <kbracey>
Component: kernAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Unspecified   
Hardware: Any   
OS: Any   

Description kbracey 1999-07-15 09:20:00 UTC
I've just stumbled across a bug in ip_output() while testing a multicast
TFTP client on a system with a FreeBSD-derived network stack.

The system has no default route or route for 224.0.0.0 set up. It is not
sending any multicasts, except for the IGMP reports generated by its group
joins, so it shouldn't need one.

The problem is that ip_output() will not output multicast packets if
it can't find a route for the destination IP address, even if the caller
has provided an interface in the multicast options, as igmp_sendpkt() does.

The same problem would arise a user process wanted to multicast on an
interface specified by IP_MULTICAST_IF.

And when you do have a route, various stats to do with that route
end up being incremented and examined, even though that route
ends up not being used!

I realise that in a normal FreeBSD system one would have a multicast
or default route set up, so the IGMP messages would get out, but it
strikes me that this is just covering up a kernel problem. You shouldn't
need a route to multicast on a manually named interface.

Fix: 

A quick fix would appear to be the following. Not terribly elegant, but
I think it works.

  line 214 or so of ip_output.c:
    
                ifp = ia->ia_ifp;
                ip->ip_ttl = 1;
                isbroadcast = in_broadcast(dst->sin_addr, ifp);
!       } else {
                /*
                 * If this is the case, we probably don't want to allocate
                 * a protocol-cloned route since we didn't get one from the

  change to:
  
                ifp = ia->ia_ifp;
                ip->ip_ttl = 1;
                isbroadcast = in_broadcast(dst->sin_addr, ifp);
!       } else if (!(imo && imo->imo_multicast_ifp &&
!                  IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
                /*
                 * If this is the case, we probably don't want to allocate
                 * a protocol-cloned route since we didn't get one from the
How-To-Repeat: Remove any default route and any route for 224.0.0.0/4. Check
that this has worked by pinging 224.0.0.1 - you should get a 
"No route to host" error. Run a program that joins a multicast group.
No IGMP report will be sent (check with tcpdump). netstat will say
that the report was sent, but in reality it will have fallen foul of
"output packets discarded due to no route".
Comment 1 Garrett A. Wollman 1999-07-15 18:54:49 UTC
<<On Thu, 15 Jul 1999 01:19:04 -0700 (PDT), kbracey@acorn.co.uk said:

> The problem is that ip_output() will not output multicast packets if
> it can't find a route for the destination IP address, even if the caller
> has provided an interface in the multicast options, as igmp_sendpkt() does.

This is a wart resuling from a path of development which was never
completed.  What was supposed to happen eventually was that the
underlying protocols would be modified to do the work of ip_output()
themselves, implementing only that part of the functionality which was
actually necessary.  Unfortunately, this work basically stopped when I
changed jobs (the previous employer was paying for it), so things were
left in this intermediate state.

-GAWollman
Comment 2 Bill Fenner 1999-07-22 16:31:26 UTC
This is a wart from the original kernel multicast patches from PARC.
I agree that it should be fixed, but be careful of creating side
effects.

  Bill
Comment 3 Mike Barcroft freebsd_committer freebsd_triage 2001-07-21 00:21:06 UTC
State Changed
From-To: open->feedback


Does this problem still occur in newer versions of FreeBSD, 
such as 4.3-RELEASE?
Comment 4 Mike Barcroft freebsd_committer freebsd_triage 2001-07-26 03:39:05 UTC
State Changed
From-To: feedback->closed


Multicast requires a route, see PR kern/19121 and pending/28902 
for details.  Also, mail sent to originator bounces.