Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Oct 2004 12:28:22 -0700
From:      Julian Elischer <julian@elischer.org>
To:        Bruce M Simpson <bms@spc.org>
Cc:        freebsd-net@freebsd.org
Subject:   Re: Implementing IP_SENDIF (like SO_BINDTODEVICE)
Message-ID:  <417FF6D6.4010201@elischer.org>
In-Reply-To: <20041027073858.GC719@empiric.icir.org>
References:  <20041027073858.GC719@empiric.icir.org>

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


Bruce M Simpson wrote:

>It annoys me that we have to resort to BPF to send IP datagrams on
>unnumbered interfaces. Here is a half baked idea. Please look and
>tell me what you think.
>

I've sent lots of datagrams on un-numberred interfaces using netgraph..

>  
>
>------------------------------------------------------------------------
>
>Adding IP_SENDIF (like Linux's SO_BINDTODEVICE) support to FreeBSD.
>Clean up the RFC 1724 hack in ip_output.c
>
>TODO:
>
>Add IP_SENDIF processing to ip_ctloutput.
>Move inp_depend6.inp6_ifindex into general inpcb structure.
>Update #define.
>Pass IP_ROUTETOIF flag to ip_output() from udp and rawip.
>Pass inp_ifindex to ip_output() as destination from udp and rawip.
>
>Index: src/sys/netinet/ip_output.c
>===================================================================
>RCS file: /home/ncvs/src/sys/netinet/ip_output.c,v
>retrieving revision 1.225.2.4
>diff -u -p -r1.225.2.4 ip_output.c
>--- src/sys/netinet/ip_output.c	22 Sep 2004 19:23:38 -0000	1.225.2.4
>+++ src/sys/netinet/ip_output.c	27 Oct 2004 07:27:24 -0000
>@@ -93,7 +93,7 @@ SYSCTL_INT(_net_inet_ip, OID_AUTO, mbuf_
> #endif
> 
> static struct mbuf *ip_insertoptions(struct mbuf *, struct mbuf *, int *);
>-static struct ifnet *ip_multicast_if(struct in_addr *, int *);
>+static struct ifnet *ina_to_rfc1724_if(struct in_addr *, int *);
> static void	ip_mloopback
> 	(struct ifnet *, struct mbuf *, struct sockaddr_in *, int);
> static int	ip_getmoptions
>@@ -206,19 +206,30 @@ again:
> 		dst->sin_addr = ip->ip_dst;
> 	}
> 	/*
>-	 * If routing to interface only,
>-	 * short circuit routing lookup.
>+	 * If routing to interface only, short circuit routing lookup.
>+	 *
>+	 * Assume the destination is either the destination end of a
>+	 * point-to-point interface, the network address of an interface,
>+	 * or the address of an interface itself. In the last case, an
>+	 * interface may be specified by index as per RFC 1724.
>+	 * 
> 	 */
> 	if (flags & IP_ROUTETOIF) {
>-		if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) == NULL &&
>-		    (ia = ifatoia(ifa_ifwithnet(sintosa(dst)))) == NULL) {
>+		ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)));
>+		if (ia == NULL)
>+			ia = ifatoia(ifa_ifwithnet(sintosa(dst)));
>+		if (ia != NULL)
>+			ifp = ia->ia_ifp;
>+		else
>+			ifp = ina_to_rfc1724_if(&dst->sin_addr, NULL);
>+		if (ifp == NULL) {
> 			ipstat.ips_noroute++;
> 			error = ENETUNREACH;
> 			goto bad;
> 		}
>-		ifp = ia->ia_ifp;
> 		ip->ip_ttl = 1;
>-		isbroadcast = in_broadcast(dst->sin_addr, ifp);
>+		isbroadcast = (flags & IP_SENDONES) |
>+			      in_broadcast(dst->sin_addr, ifp);
> 	} else if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) &&
> 	    imo != NULL && imo->imo_multicast_ifp != NULL) {
> 		/*
>@@ -1531,11 +1542,15 @@ bad:
>  * standard option (IP_TTL).
>  */
> 
>+#define	INADDR_IFINDEX_MASK	0x00FFFFFF		/* 0.0.0.0/8 */
>+
> /*
>- * following RFC1724 section 3.3, 0.0.0.0/8 is interpreted as interface index.
>+ * Look up the ifnet corresponding to a given IPv4 host address, taking the
>+ * RFC1724 hack into account. If the address given has the network prefix
>+ * 0.0.0.0/8, interpret the host portion as an interface index.
>  */
> static struct ifnet *
>-ip_multicast_if(a, ifindexp)
>+ina_to_rfc1724_if(a, ifindexp)
> 	struct in_addr *a;
> 	int *ifindexp;
> {
>@@ -1544,8 +1559,8 @@ ip_multicast_if(a, ifindexp)
> 
> 	if (ifindexp)
> 		*ifindexp = 0;
>-	if (ntohl(a->s_addr) >> 24 == 0) {
>-		ifindex = ntohl(a->s_addr) & 0xffffff;
>+	if ((ntohl(a->s_addr) & ~INADDR_IFINDEX_MASK) == 0) {
>+		ifindex = ntohl(a->s_addr) & 0x00FFFFFF;
> 		if (ifindex < 0 || if_index < ifindex)
> 			return NULL;
> 		ifp = ifnet_byindex(ifindex);
>@@ -1554,7 +1569,7 @@ ip_multicast_if(a, ifindexp)
> 	} else {
> 		INADDR_TO_IFP(*a, ifp);
> 	}
>-	return ifp;
>+	return (ifp);
> }
> 
> /*
>@@ -1634,7 +1649,7 @@ ip_setmoptions(sopt, imop)
> 		 * it supports multicasting.
> 		 */
> 		s = splimp();
>-		ifp = ip_multicast_if(&addr, &ifindex);
>+		ifp = ina_to_rfc1724_if(&addr, &ifindex);
> 		if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
> 			splx(s);
> 			error = EADDRNOTAVAIL;
>@@ -1731,7 +1746,7 @@ ip_setmoptions(sopt, imop)
> 			RTFREE(ro.ro_rt);
> 		}
> 		else {
>-			ifp = ip_multicast_if(&mreq.imr_interface, NULL);
>+			ifp = ina_to_rfc1724_if(&mreq.imr_interface, NULL);
> 		}
> 
> 		/*
>@@ -1799,7 +1814,7 @@ ip_setmoptions(sopt, imop)
> 		if (mreq.imr_interface.s_addr == INADDR_ANY)
> 			ifp = NULL;
> 		else {
>-			ifp = ip_multicast_if(&mreq.imr_interface, NULL);
>+			ifp = ina_to_rfc1724_if(&mreq.imr_interface, NULL);
> 			if (ifp == NULL) {
> 				error = EADDRNOTAVAIL;
> 				splx(s);
>  
>



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