From owner-svn-src-all@FreeBSD.ORG Sun May 9 12:36:51 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id B6C65106564A; Sun, 9 May 2010 12:36:51 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [69.147.83.44]) by mx1.freebsd.org (Postfix) with ESMTP id A4EF38FC1B; Sun, 9 May 2010 12:36:51 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o49CapJk034381; Sun, 9 May 2010 12:36:51 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o49Captw034378; Sun, 9 May 2010 12:36:51 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201005091236.o49Captw034378@svn.freebsd.org> From: Konstantin Belousov Date: Sun, 9 May 2010 12:36:51 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r207815 - stable/8/sys/net X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 09 May 2010 12:36:51 -0000 Author: kib Date: Sun May 9 12:36:51 2010 New Revision: 207815 URL: http://svn.freebsd.org/changeset/base/207815 Log: MFC r207195: Provide compat32 shims for bpf(4), except zero-copy facilities. Modified: stable/8/sys/net/bpf.c stable/8/sys/net/bpfdesc.h Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/dev/xen/xenpci/ (props changed) stable/8/sys/geom/sched/ (props changed) Modified: stable/8/sys/net/bpf.c ============================================================================== --- stable/8/sys/net/bpf.c Sun May 9 12:34:20 2010 (r207814) +++ stable/8/sys/net/bpf.c Sun May 9 12:36:51 2010 (r207815) @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include "opt_bpf.h" +#include "opt_compat.h" #include "opt_netgraph.h" #include @@ -89,6 +90,43 @@ MALLOC_DEFINE(M_BPF, "BPF", "BPF data"); #define PRINET 26 /* interruptible */ +#ifdef COMPAT_FREEBSD32 +#include +#include +#define BPF_ALIGNMENT32 sizeof(int32_t) +#define BPF_WORDALIGN32(x) (((x)+(BPF_ALIGNMENT32-1))&~(BPF_ALIGNMENT32-1)) + +/* + * 32-bit version of structure prepended to each packet. We use this header + * instead of the standard one for 32-bit streams. We mark the a stream as + * 32-bit the first time we see a 32-bit compat ioctl request. + */ +struct bpf_hdr32 { + struct timeval32 bh_tstamp; /* time stamp */ + uint32_t bh_caplen; /* length of captured portion */ + uint32_t bh_datalen; /* original length of packet */ + uint16_t bh_hdrlen; /* length of bpf header (this struct + plus alignment padding) */ +}; + +struct bpf_program32 { + u_int bf_len; + uint32_t bf_insns; +}; + +struct bpf_dltlist32 { + u_int bfl_len; + u_int bfl_list; +}; + +#define BIOCSETF32 _IOW('B', 103, struct bpf_program32) +#define BIOCSRTIMEOUT32 _IOW('B',109, struct timeval32) +#define BIOCGRTIMEOUT32 _IOR('B',110, struct timeval32) +#define BIOCGDLTLIST32 _IOWR('B',121, struct bpf_dltlist32) +#define BIOCSETWF32 _IOW('B',123, struct bpf_program32) +#define BIOCSETFNR32 _IOW('B',130, struct bpf_program32) +#endif + /* * bpf_iflist is a list of BPF interface structures, each corresponding to a * specific DLT. The same network interface might have several BPF interface @@ -1002,8 +1040,14 @@ bpfioctl(struct cdev *dev, u_long cmd, c case BIOCFLUSH: case BIOCGDLT: case BIOCGDLTLIST: +#ifdef COMPAT_FREEBSD32 + case BIOCGDLTLIST32: +#endif case BIOCGETIF: case BIOCGRTIMEOUT: +#ifdef COMPAT_FREEBSD32 + case BIOCGRTIMEOUT32: +#endif case BIOCGSTATS: case BIOCVERSION: case BIOCGRSIG: @@ -1012,6 +1056,9 @@ bpfioctl(struct cdev *dev, u_long cmd, c case FIONREAD: case BIOCLOCK: case BIOCSRTIMEOUT: +#ifdef COMPAT_FREEBSD32 + case BIOCSRTIMEOUT32: +#endif case BIOCIMMEDIATE: case TIOCGPGRP: case BIOCROTZBUF: @@ -1020,6 +1067,22 @@ bpfioctl(struct cdev *dev, u_long cmd, c return (EPERM); } } +#ifdef COMPAT_FREEBSD32 + /* + * If we see a 32-bit compat ioctl, mark the stream as 32-bit so + * that it will get 32-bit packet headers. + */ + switch (cmd) { + case BIOCSETF32: + case BIOCSETFNR32: + case BIOCSETWF32: + case BIOCGDLTLIST32: + case BIOCGRTIMEOUT32: + case BIOCSRTIMEOUT32: + d->bd_compat32 = 1; + } +#endif + CURVNET_SET(TD_TO_VNET(td)); switch (cmd) { @@ -1077,6 +1140,11 @@ bpfioctl(struct cdev *dev, u_long cmd, c case BIOCSETF: case BIOCSETFNR: case BIOCSETWF: +#ifdef COMPAT_FREEBSD32 + case BIOCSETF32: + case BIOCSETFNR32: + case BIOCSETWF32: +#endif error = bpf_setf(d, (struct bpf_program *)addr, cmd); break; @@ -1120,6 +1188,26 @@ bpfioctl(struct cdev *dev, u_long cmd, c /* * Get a list of supported data link types. */ +#ifdef COMPAT_FREEBSD32 + case BIOCGDLTLIST32: + { + struct bpf_dltlist32 *list32; + struct bpf_dltlist dltlist; + + list32 = (struct bpf_dltlist32 *)addr; + dltlist.bfl_len = list32->bfl_len; + dltlist.bfl_list = PTRIN(list32->bfl_list); + if (d->bd_bif == NULL) + error = EINVAL; + else { + error = bpf_getdltlist(d, &dltlist); + if (error == 0) + list32->bfl_len = dltlist.bfl_len; + } + break; + } +#endif + case BIOCGDLTLIST: if (d->bd_bif == NULL) error = EINVAL; @@ -1163,8 +1251,23 @@ bpfioctl(struct cdev *dev, u_long cmd, c * Set read timeout. */ case BIOCSRTIMEOUT: +#ifdef COMPAT_FREEBSD32 + case BIOCSRTIMEOUT32: +#endif { struct timeval *tv = (struct timeval *)addr; +#ifdef COMPAT_FREEBSD32 + struct timeval32 *tv32; + struct timeval tv64; + + if (cmd == BIOCSRTIMEOUT32) { + tv32 = (struct timeval32 *)addr; + tv = &tv64; + tv->tv_sec = tv32->tv_sec; + tv->tv_usec = tv32->tv_usec; + } else +#endif + tv = (struct timeval *)addr; /* * Subtract 1 tick from tvtohz() since this isn't @@ -1179,11 +1282,31 @@ bpfioctl(struct cdev *dev, u_long cmd, c * Get read timeout. */ case BIOCGRTIMEOUT: +#ifdef COMPAT_FREEBSD32 + case BIOCGRTIMEOUT32: +#endif { - struct timeval *tv = (struct timeval *)addr; + struct timeval *tv; +#ifdef COMPAT_FREEBSD32 + struct timeval32 *tv32; + struct timeval tv64; + + if (cmd == BIOCGRTIMEOUT32) + tv = &tv64; + else +#endif + tv = (struct timeval *)addr; tv->tv_sec = d->bd_rtout / hz; tv->tv_usec = (d->bd_rtout % hz) * tick; +#ifdef COMPAT_FREEBSD32 + if (cmd == BIOCGRTIMEOUT32) { + tv32 = (struct timeval32 *)addr; + tv32->tv_sec = tv->tv_sec; + tv32->tv_usec = tv->tv_usec; + } +#endif + break; } @@ -1371,7 +1494,19 @@ bpf_setf(struct bpf_d *d, struct bpf_pro #ifdef BPF_JITTER bpf_jit_filter *ofunc; #endif - +#ifdef COMPAT_FREEBSD32 + struct bpf_program32 *fp32; + struct bpf_program fp_swab; + + if (cmd == BIOCSETWF32 || cmd == BIOCSETF32 || cmd == BIOCSETFNR32) { + fp32 = (struct bpf_program32 *)fp; + fp_swab.bf_len = fp32->bf_len; + fp_swab.bf_insns = (struct bpf_insn *)(uintptr_t)fp32->bf_insns; + fp = &fp_swab; + if (cmd == BIOCSETWF32) + cmd = BIOCSETWF; + } +#endif if (cmd == BIOCSETWF) { old = d->bd_wfilter; wfilter = 1; @@ -1773,6 +1908,9 @@ catchpacket(struct bpf_d *d, u_char *pkt struct timeval *tv) { struct bpf_hdr hdr; +#ifdef COMPAT_FREEBSD32 + struct bpf_hdr32 hdr32; +#endif int totlen, curlen; int hdrlen = d->bd_bif->bif_hdrlen; int do_wakeup = 0; @@ -1811,7 +1949,12 @@ catchpacket(struct bpf_d *d, u_char *pkt * buffer is considered immutable by the buffer model, try to rotate * the buffer and wakeup pending processes. */ - curlen = BPF_WORDALIGN(d->bd_slen); +#ifdef COMPAT_FREEBSD32 + if (d->bd_compat32) + curlen = BPF_WORDALIGN32(d->bd_slen); + else +#endif + curlen = BPF_WORDALIGN(d->bd_slen); if (curlen + totlen > d->bd_bufsize || !bpf_canwritebuf(d)) { if (d->bd_fbuf == NULL) { /* @@ -1833,6 +1976,22 @@ catchpacket(struct bpf_d *d, u_char *pkt * reader should be woken up. */ do_wakeup = 1; +#ifdef COMPAT_FREEBSD32 + /* + * If this is a 32-bit stream, then stick a 32-bit header at the + * front and copy the data into the buffer. + */ + if (d->bd_compat32) { + bzero(&hdr32, sizeof(hdr32)); + hdr32.bh_tstamp.tv_sec = tv->tv_sec; + hdr32.bh_tstamp.tv_usec = tv->tv_usec; + hdr32.bh_datalen = pktlen; + hdr32.bh_hdrlen = hdrlen; + hdr.bh_caplen = hdr32.bh_caplen = totlen - hdrlen; + bpf_append_bytes(d, d->bd_sbuf, curlen, &hdr32, sizeof(hdr32)); + goto copy; + } +#endif /* * Append the bpf header. Note we append the actual header size, but @@ -1848,6 +2007,9 @@ catchpacket(struct bpf_d *d, u_char *pkt /* * Copy the packet data into the store buffer and update its length. */ +#ifdef COMPAT_FREEBSD32 + copy: +#endif (*cpfn)(d, d->bd_sbuf, curlen + hdrlen, pkt, hdr.bh_caplen); d->bd_slen = curlen + totlen; Modified: stable/8/sys/net/bpfdesc.h ============================================================================== --- stable/8/sys/net/bpfdesc.h Sun May 9 12:34:20 2010 (r207814) +++ stable/8/sys/net/bpfdesc.h Sun May 9 12:36:51 2010 (r207815) @@ -97,6 +97,7 @@ struct bpf_d { u_int64_t bd_wfcount; /* number of packets that matched write filter */ u_int64_t bd_wdcount; /* number of packets dropped during a write */ u_int64_t bd_zcopy; /* number of zero copy operations */ + u_char bd_compat32; /* 32-bit stream on LP64 system */ }; /* Values for bd_state */