Date: Mon, 6 Jun 2005 20:16:38 +1200 From: Matthew Luckie <mjl@luckie.org.nz> To: freebsd-net@freebsd.org Subject: Re: bpf writes on tun device Message-ID: <20050606081637.GA73886@lycra.luckie.org.nz> In-Reply-To: <4295A6CA.8080409@luckie.org.nz> References: <4295A6CA.8080409@luckie.org.nz>
next in thread | previous in thread | raw e-mail | index | archive | help
> 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) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050606081637.GA73886>