Bug 19121

Summary: IPv4 multicast does not work without route
Product: Base System Reporter: root <sam>
Component: kernAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 5.0-CURRENT   
Hardware: Any   
OS: Any   

Description root 2000-06-08 13:10:03 UTC
	When trying to join a multicast group with a
	IPPROTO_IP/ADD_MEMBERSHIP ioctl call on a IPv4 socket, FreeBSD
	tries to find a suitable network interface using the regular
	routing table:

From netinet/ip_output.c:

                s = splimp();
                /*
                 * If no interface address was provided, use the interface of
                 * the route to the given multicast address.
                 */
                if (mreq.imr_interface.s_addr == INADDR_ANY) {
                        bzero((caddr_t)&ro, sizeof(ro));
                        dst = (struct sockaddr_in *)&ro.ro_dst;
                        dst->sin_len = sizeof(*dst);
                        dst->sin_family = AF_INET;
                        dst->sin_addr = mreq.imr_multiaddr;
                        rtalloc(&ro);
                        if (ro.ro_rt == NULL) {
                                error = EADDRNOTAVAIL;
                                splx(s);
                                break;
                        }
                        ifp = ro.ro_rt->rt_ifp;
                        rtfree(ro.ro_rt);
                }

	On a FreeBSD box with one ethernet card connected to a local network
	and with no default route, this means that EADDRNOTAVAIL will be
	returned when trying to join an IPv4 multicast group.

	This is not a theoritical-only case: this happens on a home
	network (which sometimes connects to the internet using PPP)
	when NTP is launched on the ntp.mcast.net address to reach the
	various subnets.

	Also, if several interfaces are multicast-capable, at most one of
	them will be selected. Packets emitted from the host will be sent
	to at most one local network (I believe, I haven't tested this
	configuration).

Fix: 

(I haven't had a chance to test this, it is pure guess)

	When no interface is explicitely given, netinet/ip_output.c should
	do two things instead of looking for a suitable interface in the
	routing table:

		(1) Fill a slot in the imo structure with imo_multicast_ifp
		field being NULL.

		(2) Add a slot for every multicast-capable interface and
		subscribe this interface to the multicast group.

	Also, when an interface M_MCAST flag is set (or when the interface is
	brought up), a new slot should be added. Deletion of a multicast
	membership should follow the same logic.

	This way, every new interface added to the system (as I do with
	my laptop) will automatically start sending multicast packets if
	it is multicast capable.
How-To-Repeat: 
	Remove your default route, make sure that you have no explicit route
	for 224.0.0.0/8 addresses and start sdr. You will get an error
	from setsockopt (can't assign requested address).
Comment 1 Garrett A. Wollman 2000-06-08 16:09:49 UTC
<<On Thu,  8 Jun 2000 14:06:27 +0200 (CEST), sam@inf.enst.fr said:

> 	A FreeBSD box on a private network with IPv4 routes to local
> 	network only. No default route has been set, nor any route for
> 	the 224.0.0.0/8 addresses.

Then your configuration is broken.  If you want to send multicasts,
you MUST configure a route for them, end of story.

This requirement has existed throughout the entire history of IP
multicast under UNIX.

Note that it would be an error for packets to be multicast out
multiple interfaces simultaneously.  The definition of the multicast
service model says that hosts MUST NOT do this; only a multicast
router is permitted to send the same packet in multiple directions at
once.

-GAWollman

--
Garrett A. Wollman   | O Siem / We are all family / O Siem / We're all the same
wollman@lcs.mit.edu  | O Siem / The fires of freedom 
Opinions not those of| Dance in the burning flame
MIT, LCS, CRS, or NSA|                     - Susan Aglukark and Chad Irschick
Comment 2 Mike Barcroft freebsd_committer freebsd_triage 2001-07-22 04:08:53 UTC
State Changed
From-To: open->closed


Multicast requires a route.  See wollman's comments in the 
Audit-Trail for details.