Skip site navigation (1)Skip section navigation (2)
Date:      Thu,  8 Jun 2000 14:06:27 +0200 (CEST)
From:      sam@inf.enst.fr
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/19121: IPv4 multicast does not work without route
Message-ID:  <20000608120627.D9AEE1FC@trillian.enst.fr>

next in thread | raw e-mail | index | archive | help

>Number:         19121
>Category:       kern
>Synopsis:       IPv4 multicast does not work without route
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jun 08 05:10:03 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator:     Samuel Tardieu
>Release:        FreeBSD 5.0-CURRENT i386
>Organization:
TELECOM Paris
>Environment:

	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.

>Description:

	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).

>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).

>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.


>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000608120627.D9AEE1FC>