Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 17 May 2004 00:36:29 +0800
From:      Eugene Grosbein <eugen@grosbein.pp.ru>
To:        bug-followup@freebsd.org
Cc:        net@freebsd.org
Subject:   Re: bin/51927: routed(8) fails to use multicast with IFF_POINTOPOINT interfaces
Message-ID:  <20040516163629.GA2271@grosbein.pp.ru>

next in thread | raw e-mail | index | archive | help
Reply-To: 

Hi!

ip(4) man page says that IP_MULTICAST_IF, IP_ADD_MEMBERSHIP etc.
must use local IP address of desired interface. There are (at least)
two undersirable consequents:

1) It is hard (if not impossible) to distinguish between "unnumbered"
IFF_POINTOPOINT interfaces, those share the same local IP address with
an ethernet interface (think of pppd and proxyarp).
2) routed, zebra and quagga cannot currently use outgoing RIPv2 multicasts
with IFF_POINTOPOINT interfaces (ppp, gif etc.) at least in 4-STABLE.

There was an attempt to fix this by modifying INADDR_TO_IFP:
http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/netinet/in_var.h#rev1.7

It was unsuccessful and Ruslan undid it:
http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/netinet/in_var.h#rev1.39

However, we still need working RIPv2:
http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/51927

Presently there are only two consumers of INADDR_TO_IFP in a 4.x kernel:
ipfw[2] and ip_multicast_if() in src/sys/netinet/ip_output.h,
the latter is exactly what prevents routed and ripd to enable
multicasts on IFF_POINTOPOINT.

Another attempt to fix that is presented. The next patch introduces another
macro INADDR_TO_IFP_P2P that is used by ip_multicast_if() when INADDR_TO_IFP
does not find ifp.

--- in_var.h.orig	Sat Dec 15 03:09:34 2001
+++ in_var.h	Sun May 16 23:51:14 2004
@@ -117,6 +117,20 @@
 	(ifp) = (ia == NULL) ? NULL : ia->ia_ifp; \
 }
 
+#define INADDR_TO_IFP_P2P(addr, ifp) \
+	/* struct in_addr addr; */ \
+	/* struct ifnet *ifp; */ \
+{ \
+	struct in_ifaddr *ia; \
+\
+	TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) \
+		if ((ia->ia_ifp->if_flags & IFF_POINTOPOINT) && \
+		    IA_DSTSIN(ia)->sin_addr.s_addr == (addr).s_addr) { \
+				break; \
+		} \
+	(ifp) = (ia == NULL) ? NULL : ia->ia_ifp; \
+}
+
 /*
  * Macro for finding the internet address structure (in_ifaddr) corresponding
  * to a given interface (ifnet structure).
--- sys/netinet/ip_output.c.orig	Fri May 14 18:51:35 2004
+++ sys/netinet/ip_output.c	Fri May 14 20:40:49 2004
@@ -1785,6 +1785,9 @@
 			*ifindexp = ifindex;
 	} else {
 		INADDR_TO_IFP(*a, ifp);
+		if (ifp == NULL) {
+			INADDR_TO_IFP_P2P(*a, ifp);
+		}
 	}
 	return ifp;
 }


I think this can be improved by introducing another hash for remote IPs
of IFF_POINTOPOINT intefaces (similar to in_ifaddrhashtbl) to avoid
linear search but leave that for later stage.

Eugene Grosbein



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