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>