Date: Wed, 27 Oct 2004 00:38:58 -0700 From: Bruce M Simpson <bms@spc.org> To: freebsd-net@freebsd.org Subject: Implementing IP_SENDIF (like SO_BINDTODEVICE) Message-ID: <20041027073858.GC719@empiric.icir.org>
next in thread | raw e-mail | index | archive | help
--mojUlQ0s9EVzWg2t Content-Type: multipart/mixed; boundary="RnlQjJ0d97Da+TV1" Content-Disposition: inline --RnlQjJ0d97Da+TV1 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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. --RnlQjJ0d97Da+TV1 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="ip_sendif_rev1.patch" Content-Transfer-Encoding: quoted-printable 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 =20 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 =3D 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. + *=20 */ if (flags & IP_ROUTETOIF) { - if ((ia =3D ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) =3D=3D NULL && - (ia =3D ifatoia(ifa_ifwithnet(sintosa(dst)))) =3D=3D NULL) { + ia =3D ifatoia(ifa_ifwithdstaddr(sintosa(dst))); + if (ia =3D=3D NULL) + ia =3D ifatoia(ifa_ifwithnet(sintosa(dst))); + if (ia !=3D NULL) + ifp =3D ia->ia_ifp; + else + ifp =3D ina_to_rfc1724_if(&dst->sin_addr, NULL); + if (ifp =3D=3D NULL) { ipstat.ips_noroute++; error =3D ENETUNREACH; goto bad; } - ifp =3D ia->ia_ifp; ip->ip_ttl =3D 1; - isbroadcast =3D in_broadcast(dst->sin_addr, ifp); + isbroadcast =3D (flags & IP_SENDONES) | + in_broadcast(dst->sin_addr, ifp); } else if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) && imo !=3D NULL && imo->imo_multicast_ifp !=3D NULL) { /* @@ -1531,11 +1542,15 @@ bad: * standard option (IP_TTL). */ =20 +#define INADDR_IFINDEX_MASK 0x00FFFFFF /* 0.0.0.0/8 */ + /* - * following RFC1724 section 3.3, 0.0.0.0/8 is interpreted as interface in= dex. + * 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) =20 if (ifindexp) *ifindexp =3D 0; - if (ntohl(a->s_addr) >> 24 =3D=3D 0) { - ifindex =3D ntohl(a->s_addr) & 0xffffff; + if ((ntohl(a->s_addr) & ~INADDR_IFINDEX_MASK) =3D=3D 0) { + ifindex =3D ntohl(a->s_addr) & 0x00FFFFFF; if (ifindex < 0 || if_index < ifindex) return NULL; ifp =3D ifnet_byindex(ifindex); @@ -1554,7 +1569,7 @@ ip_multicast_if(a, ifindexp) } else { INADDR_TO_IFP(*a, ifp); } - return ifp; + return (ifp); } =20 /* @@ -1634,7 +1649,7 @@ ip_setmoptions(sopt, imop) * it supports multicasting. */ s =3D splimp(); - ifp =3D ip_multicast_if(&addr, &ifindex); + ifp =3D ina_to_rfc1724_if(&addr, &ifindex); if (ifp =3D=3D NULL || (ifp->if_flags & IFF_MULTICAST) =3D=3D 0) { splx(s); error =3D EADDRNOTAVAIL; @@ -1731,7 +1746,7 @@ ip_setmoptions(sopt, imop) RTFREE(ro.ro_rt); } else { - ifp =3D ip_multicast_if(&mreq.imr_interface, NULL); + ifp =3D ina_to_rfc1724_if(&mreq.imr_interface, NULL); } =20 /* @@ -1799,7 +1814,7 @@ ip_setmoptions(sopt, imop) if (mreq.imr_interface.s_addr =3D=3D INADDR_ANY) ifp =3D NULL; else { - ifp =3D ip_multicast_if(&mreq.imr_interface, NULL); + ifp =3D ina_to_rfc1724_if(&mreq.imr_interface, NULL); if (ifp =3D=3D NULL) { error =3D EADDRNOTAVAIL; splx(s); --RnlQjJ0d97Da+TV1-- --mojUlQ0s9EVzWg2t Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Comment: '' iD8DBQFBf1CRueUpAYYNtTsRAq2ZAJsEpxqxKF2l20jgnztRsZhElDNZHQCeLb7l bPPlc+nBc/B3muPtA0NpVdU= =V3uW -----END PGP SIGNATURE----- --mojUlQ0s9EVzWg2t--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20041027073858.GC719>