Skip site navigation (1)Skip section navigation (2)
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>