From owner-freebsd-net@FreeBSD.ORG Wed Oct 27 07:39:11 2004 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 391F616A4CE for ; Wed, 27 Oct 2004 07:39:11 +0000 (GMT) Received: from arginine.spc.org (arginine.spc.org [195.206.69.236]) by mx1.FreeBSD.org (Postfix) with ESMTP id 3267943D49 for ; Wed, 27 Oct 2004 07:39:10 +0000 (GMT) (envelope-from bms@spc.org) Received: from localhost (localhost [127.0.0.1]) by arginine.spc.org (Postfix) with ESMTP id 969756538E for ; Wed, 27 Oct 2004 08:39:08 +0100 (BST) Received: from arginine.spc.org ([127.0.0.1]) by localhost (arginine.spc.org [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 68184-01-3 for ; Wed, 27 Oct 2004 08:39:08 +0100 (BST) Received: from empiric.dek.spc.org (adsl-67-121-95-134.dsl.snfc21.pacbell.net [67.121.95.134]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by arginine.spc.org (Postfix) with ESMTP id 7C99465375 for ; Wed, 27 Oct 2004 08:39:07 +0100 (BST) Received: by empiric.dek.spc.org (Postfix, from userid 1001) id 0AFC16246; Wed, 27 Oct 2004 00:38:58 -0700 (PDT) Date: Wed, 27 Oct 2004 00:38:58 -0700 From: Bruce M Simpson To: freebsd-net@freebsd.org Message-ID: <20041027073858.GC719@empiric.icir.org> Mail-Followup-To: freebsd-net@freebsd.org Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="mojUlQ0s9EVzWg2t" Content-Disposition: inline Subject: Implementing IP_SENDIF (like SO_BINDTODEVICE) X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 27 Oct 2004 07:39:11 -0000 --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--