Date: Sat, 30 Dec 1995 16:26:55 -0600 From: marquard@austin.ibm.com To: FreeBSD-gnats-submit@freebsd.org Subject: kern/923: Multicast problems on point-to-point interfaces Message-ID: <9512302226.AA04008@mojave.austin.ibm.com> Resent-Message-ID: <199512302230.OAA22065@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 923 >Category: kern >Synopsis: Multicast problems on point-to-point interfaces >Confidential: no >Severity: serious >Priority: high >Responsible: freebsd-bugs >State: open >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Dec 30 14:30:01 PST 1995 >Last-Modified: >Originator: Dave Marquardt >Organization: Individual >Release: FreeBSD 2.1-STABLE i386 >Environment: Packard Bell Force 442CDT (75 MHz Pentium, 8MB RAM) Using tun0 interface, which is multicast capable No other interfaces (except loopback) >Description: In attempting to run mrouted for multicast routing, I noted that tun0 has IFF_MULTICAST set, and tun0 along with a tunnel to a remote site should make mrouted work. Here's the mrouted configuration file I used: # mrouted configuration phyint 9.3.240.156 tunnel 9.3.240.156 129.35.128.45 Here's the state of tun0: tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500 inet 9.3.240.156 --> 9.3.240.14 netmask 0xff000000 When I run mrouted, I get this: lefse# mrouted -d -c ~drm/mrouted.conf debug level 2 19:38:42.082 mrouted version 3.6 19:38:42.480 Getting vifs from kernel interfaces 19:38:42.490 installing tun0 (9.3.240.156 on subnet 9/8) as vif #0 - rate=0 19:38:42.490 Getting vifs from /home/drm/mrouted.conf 19:38:42.552 installing tunnel from 9.3.240.156 to 129.35.128.45 as vif #1 - rate=500 19:38:42.554 Installing vifs in kernel... 19:38:42.560 vif #0, phyint 9.3.240.156 19:38:42.560 warning - can't join group 224.0.0.4 on interface 9.3.240.156: Can't assign requested address 19:38:42.567 warning - can't join group 224.0.0.2 on interface 9.3.240.156: Can't assign requested address 19:38:42.579 setsockopt IP_MULTICAST_IF 9.3.240.156: Can't assign requested address Upon code investigation, I discovered some problems in the code for both IP_ADD_MEMBERSHIP and IP_MULTICAST_IF. In the case of adding a membership with a specific source address, specifying the interface on which to add the multicast group, we end up in this code in ip_setmoptions(): INADDR_TO_IFP(mreq->imr_interface, ifp); The code for the INADDR_TO_IFP() macro is this: /* * Macro for finding the interface (ifnet structure) corresponding to one * of our IP addresses. */ #define INADDR_TO_IFP(addr, ifp) \ /* struct in_addr addr; */ \ /* struct ifnet *ifp; */ \ { \ register struct in_ifaddr *ia; \ \ for (ia = in_ifaddr; \ ia != NULL && ((ia->ia_ifp->if_flags & IFF_POINTOPOINT)? \ IA_DSTSIN(ia):IA_SIN(ia))->sin_addr.s_addr != (addr).s_addr; \ ia = ia->ia_next) \ continue; \ (ifp) = (ia == NULL) ? NULL : ia->ia_ifp; \ } In the case of a point to point link like tun0, we check the DESTINATION address rather than the source address of the interface. It seems to me we should either check the source, or both the source and destination, but not just the destination. A similar problem applies to the IP_MULTICAST_IF code. >How-To-Repeat: Try to join a multicast group on tun0 or some other point-to-point interface that claims to support multicast, i.e. use the IP_ADD_MEMBERSHIP socket option with setsockopt(). mrouted has code like this. Try to set the outgoing multicast interface using the setsockopt() with the IP_MULTICAST_IF socket option. Again, mrouted does this. >Fix: My own thought is that the INADDR_TO_IFP() macro is wrong in the case of IFF_POINTOPOINT. Here's a context diff: *** 1.1 1995/12/30 01:55:07 --- in_var.h 1995/12/30 02:26:41 *************** *** 102,111 **** register struct in_ifaddr *ia; \ \ for (ia = in_ifaddr; \ ! ia != NULL && ((ia->ia_ifp->if_flags & IFF_POINTOPOINT)? \ ! IA_DSTSIN(ia):IA_SIN(ia))->sin_addr.s_addr != (addr).s_addr; \ ia = ia->ia_next) \ ! continue; \ (ifp) = (ia == NULL) ? NULL : ia->ia_ifp; \ } --- 102,112 ---- register struct in_ifaddr *ia; \ \ for (ia = in_ifaddr; \ ! ia != NULL && IA_SIN(ia)->sin_addr.s_addr != (addr).s_addr; \ ia = ia->ia_next) \ ! if (ia->ia_ifp->if_flags & IFF_POINTOPOINT) \ ! if (IA_DSTSIN(ia)->sin_addr.s_addr == (addr).s_addr) \ ! break; \ (ifp) = (ia == NULL) ? NULL : ia->ia_ifp; \ } This should catch both the source and destination address of point to point links. Since INADDR_TO_IFP() seems to be used only with the multicast code, this change shouldn't mess anyone else up. >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9512302226.AA04008>