From owner-freebsd-current@FreeBSD.ORG Mon Jun 18 18:39:46 2007 Return-Path: X-Original-To: current@freebsd.org Delivered-To: freebsd-current@FreeBSD.ORG Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id C4F9916A46C; Mon, 18 Jun 2007 18:39:46 +0000 (UTC) (envelope-from bms@incunabulum.net) Received: from out1.smtp.messagingengine.com (out1.smtp.messagingengine.com [66.111.4.25]) by mx1.freebsd.org (Postfix) with ESMTP id 8673013C458; Mon, 18 Jun 2007 18:39:46 +0000 (UTC) (envelope-from bms@incunabulum.net) Received: from compute2.internal (compute2.internal [10.202.2.42]) by out1.messagingengine.com (Postfix) with ESMTP id 2FEFA193B; Mon, 18 Jun 2007 14:39:46 -0400 (EDT) Received: from heartbeat2.messagingengine.com ([10.202.2.161]) by compute2.internal (MEProxy); Mon, 18 Jun 2007 14:39:46 -0400 X-Sasl-enc: u/7mRub3tOrLIPX942bUW4PB7pWjVCRBAr1YMw7IXNB1 1182191985 Received: from [192.168.123.18] (82-35-112-254.cable.ubr07.dals.blueyonder.co.uk [82.35.112.254]) by mail.messagingengine.com (Postfix) with ESMTP id 7548115370; Mon, 18 Jun 2007 14:39:45 -0400 (EDT) Message-ID: <4676D168.3050502@incunabulum.net> Date: Mon, 18 Jun 2007 19:39:36 +0100 From: "Bruce M. Simpson" User-Agent: Thunderbird 1.5.0.12 (Windows/20070509) MIME-Version: 1.0 To: "Bruce M. Simpson" References: <46765CB9.9020105@incunabulum.net> <4676C30E.7040300@incunabulum.net> <4676C952.5000607@incunabulum.net> In-Reply-To: <4676C952.5000607@incunabulum.net> Content-Type: multipart/mixed; boundary="------------020002060800060906070808" Cc: Daniel Eischen , Ian FREISLICH , current@freebsd.org Subject: Re: Multicast problems [PATCH] X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 18 Jun 2007 18:39:46 -0000 This is a multi-part message in MIME format. --------------020002060800060906070808 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Bruce M. Simpson wrote: > > The condition we've seen is a side-effect of ip_multicast_if() being > removed. Support for scoped addresses in the IPv4 stack will mean this > code has to change again. Here is a patch which explicitly looks for an interface supporting multicast, if no default route exists. The KASSERT should only be triggered if the routing trie code is broken; it is still possible for the last-resort interface lookup to fail if no loopback interface exists, if none of the interfaces have IPv4 addresses, or if no interfaces in the system support multicast. regards, BMS --------------020002060800060906070808 Content-Type: text/plain; name="xmcast.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="xmcast.diff" --- in_mcast.c.orig Mon Jun 18 20:08:48 2007 +++ in_mcast.c Mon Jun 18 20:36:33 2007 @@ -996,8 +996,16 @@ /* * Obtain ifp. If no interface address was provided, - * use the interface of the route to the given multicast - * address (usually this is the default route). + * use the interface of the route in the unicast FIB for + * the given multicast destination; usually, this is the + * default route. + * If this lookup fails, attempt to use the first non-loopback + * interface with multicast capability in the system as a + * last resort. The legacy IPv4 ASM API requires that we do + * this in order to allow groups to be joined when the routing + * table has not yet been populated during boot. + * If all of these conditions fail, return EADDRNOTAVAIL, and + * reject the IPv4 multicast join. */ if (mreqs.imr_interface.s_addr != INADDR_ANY) { INADDR_TO_IFP(mreqs.imr_interface, ifp); @@ -1007,16 +1015,23 @@ ro.ro_rt = NULL; *(struct sockaddr_in *)&ro.ro_dst = gsa->sin; rtalloc_ign(&ro, RTF_CLONING); - if (ro.ro_rt == NULL) { -#ifdef DIAGNOSTIC - printf("%s: no route to %s\n", __func__, - inet_ntoa(gsa->sin.sin_addr)); -#endif - return (EADDRNOTAVAIL); + if (ro.ro_rt != NULL) { + ifp = ro.ro_rt->rt_ifp; + KASSERT(ifp != NULL, ("%s: null ifp", + __func__)); + RTFREE(ro.ro_rt); + } else { + struct in_ifaddr *ia; + struct ifnet *mfp = NULL; + TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) { + mfp = ia->ia_ifp; + if (!(mfp->if_flags & IFF_LOOPBACK) && + (mfp->if_flags & IFF_MULTICAST)) { + ifp = mfp; + break; + } + } } - ifp = ro.ro_rt->rt_ifp; - KASSERT(ifp != NULL, ("%s: null ifp", __func__)); - RTFREE(ro.ro_rt); } #ifdef DIAGNOSTIC if (bootverbose) { --------------020002060800060906070808--