From owner-freebsd-net@FreeBSD.ORG Mon Jun 6 08:17:42 2005 Return-Path: X-Original-To: freebsd-net@freebsd.org 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 439D716A41C for ; Mon, 6 Jun 2005 08:17:42 +0000 (GMT) (envelope-from mjl@luckie.org.nz) Received: from grunt14.ihug.co.nz (grunt14.ihug.co.nz [203.109.254.61]) by mx1.FreeBSD.org (Postfix) with ESMTP id C7CE943D5D for ; Mon, 6 Jun 2005 08:17:41 +0000 (GMT) (envelope-from mjl@luckie.org.nz) Received: from 203-173-150-184.bliink.ihug.co.nz (lycra.luckie.org.nz) [203.173.150.184] by grunt14.ihug.co.nz with esmtp (Exim 3.35 #1 (Debian)) id 1DfCnj-00037e-00; Mon, 06 Jun 2005 20:17:39 +1200 Received: from mjl by lycra.luckie.org.nz with local (Exim 4.51 (FreeBSD)) id 1DfCml-000JFd-0c for freebsd-net@freebsd.org; Mon, 06 Jun 2005 20:16:39 +1200 Date: Mon, 6 Jun 2005 20:16:38 +1200 From: Matthew Luckie To: freebsd-net@freebsd.org Message-ID: <20050606081637.GA73886@lycra.luckie.org.nz> References: <4295A6CA.8080409@luckie.org.nz> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <4295A6CA.8080409@luckie.org.nz> User-Agent: Mutt/1.4.2.1i Subject: Re: bpf writes on tun device X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 Jun 2005 08:17:42 -0000 > I can successfully write BPF packets up to 1500 bytes in size (1496 IP > bytes without the address family integer). Writes larger than this > return EMSGSIZE. http://lists.freebsd.org/pipermail/freebsd-net/2005-May/007371.html Just for the record, the patch below fixes this on 4.11; the same problem exists in HEAD today. I'm pondering making an effort to add write support to all interface types. I would do this by adding an extra parameter to bpf_if that specifies the size of the 'link layer' it expects to encounter when bpfwrite is called. struct bpf_if { LIST_ENTRY(bpf_if) bif_next; /* list of all interfaces */ LIST_HEAD(, bpf_d) bif_dlist; /* descriptor list */ struct bpf_if **bif_driverp; /* pointer into softc */ u_int bif_dlt; /* link layer type */ - u_int bif_hdrlen; /* length of header (with padding) */ + u_int bif_hdrlen_rx; /* link header passed to bpf reader */ + u_int bif_hdrlen_tx; /* link header passed by bpf writer */ struct ifnet *bif_ifp; /* corresponding interface */ struct mtx bif_mtx; /* mutex for interface */ }; If I was to pursue this, would someone on this list consider committing the work to current? Index: bpf.c =================================================================== RCS file: /home/ncvs/src/sys/net/bpf.c,v retrieving revision 1.59.2.13 diff -u -p -r1.59.2.13 bpf.c --- bpf.c 21 Aug 2003 23:50:54 -0000 1.59.2.13 +++ bpf.c 6 Jun 2005 07:54:12 -0000 @@ -120,7 +120,7 @@ static void bpf_detachd __P((struct bpf_ static void bpf_freed __P((struct bpf_d *)); static void bpf_mcopy __P((const void *, void *, size_t)); static int bpf_movein __P((struct uio *, int, - struct mbuf **, struct sockaddr *, int *)); + struct mbuf **, struct sockaddr *, struct ifnet *)); static int bpf_setif __P((struct bpf_d *, struct ifreq *)); static void bpf_timed_out __P((void *)); static inline void @@ -164,9 +164,10 @@ static struct filterops bpfread_filtops { 1, NULL, filt_bpfdetach, filt_bpfread }; static int -bpf_movein(uio, linktype, mp, sockp, datlen) +bpf_movein(uio, linktype, mp, sockp, ifp) register struct uio *uio; - int linktype, *datlen; + int linktype; + struct ifnet *ifp; register struct mbuf **mp; register struct sockaddr *sockp; { @@ -209,11 +210,18 @@ bpf_movein(uio, linktype, mp, sockp, dat break; case DLT_RAW: - case DLT_NULL: sockp->sa_family = AF_UNSPEC; hlen = 0; break; + case DLT_NULL: + sockp->sa_family = AF_UNSPEC; + if(strcmp(ifp->if_name, "tun") == 0) + hlen = sizeof(int); + else + hlen = 0; + break; + #ifdef __FreeBSD__ case DLT_ATM_RFC1483: /* @@ -235,7 +243,10 @@ bpf_movein(uio, linktype, mp, sockp, dat } len = uio->uio_resid; - *datlen = len - hlen; + + if (len - hlen > ifp->if_mtu) + return (EMSGSIZE); + if ((unsigned)len > MCLBYTES) return (EIO); @@ -619,7 +630,6 @@ bpfwrite(dev, uio, ioflag) struct mbuf *m; int error, s; static struct sockaddr dst; - int datlen; if (d->bd_bif == 0) return (ENXIO); @@ -629,12 +639,9 @@ bpfwrite(dev, uio, ioflag) if (uio->uio_resid == 0) return (0); - error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, &m, &dst, &datlen); + error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, &m, &dst, ifp); if (error) return (error); - - if (datlen > ifp->if_mtu) - return (EMSGSIZE); if (d->bd_hdrcmplt) dst.sa_family = pseudo_AF_HDRCMPLT; Index: if_tun.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_tun.c,v retrieving revision 1.74.2.8 diff -u -p -r1.74.2.8 if_tun.c --- if_tun.c 13 Feb 2002 00:43:11 -0000 1.74.2.8 +++ if_tun.c 6 Jun 2005 07:54:13 -0000 @@ -328,10 +328,8 @@ tunoutput(ifp, m0, dst, rt) /* BPF write needs to be handled specially */ if (dst->sa_family == AF_UNSPEC) { - dst->sa_family = *(mtod(m0, int *)); - m0->m_len -= sizeof(int); - m0->m_pkthdr.len -= sizeof(int); - m0->m_data += sizeof(int); + bcopy(dst->sa_data, &s, 4); + dst->sa_family = s; } if (ifp->if_bpf) {