--- libaitio/src/bpf.c 2013/06/25 08:45:50 1.1.2.7 +++ libaitio/src/bpf.c 2013/06/25 09:29:34 1.1.2.10 @@ -163,6 +163,7 @@ io_etherOpen(const char *csIface, int flags, int whdr, io_etherClose(eth, zcbuf); return -1; } + memset(&ifr, 0, sizeof ifr); strlcpy(ifr.ifr_name, szStr, sizeof ifr.ifr_name); if (ioctl(eth, BIOCSETIF, &ifr) == -1) { LOGERR; @@ -198,6 +199,19 @@ io_etherSend(int eth, const void *buf, size_t buflen) } #ifdef __FreeBSD__ +static inline void +ackZCbuf(struct bpf_zbuf_header * __restrict bzh) +{ + atomic_store_rel_int(&bzh->bzh_user_gen, bzh->bzh_kernel_gen); +} + +static inline int +chkZCbuf(struct bpf_zbuf_header * __restrict bzh) +{ + /* return true if userspace owns buffer, and false otherwise. */ + return (bzh->bzh_user_gen != atomic_load_acq_int(&bzh->bzh_kernel_gen)); +} + static inline ssize_t nextZCbuf(void ** __restrict zcache, struct bpf_zbuf * __restrict zbuf, const void * __restrict buf) @@ -207,20 +221,24 @@ nextZCbuf(void ** __restrict zcache, struct bpf_zbuf * if (!*zcache || *zcache == zbuf->bz_bufb) { bzh = (struct bpf_zbuf_header *) zbuf->bz_bufa; - if (bzh->bzh_user_gen != atomic_load_acq_int(&bzh->bzh_kernel_gen)) { + if (chkZCbuf(bzh)) { rlen = atomic_load_acq_int(&bzh->bzh_kernel_len); *zcache = zbuf->bz_bufa; if (buf) buf = ((caddr_t) *zcache) + sizeof(struct bpf_zbuf_header); - } + ackZCbuf(bzh); + } else + io_SetErr(EAGAIN, "kernel owns the buffer"); } else if (*zcache == zbuf->bz_bufa) { bzh = (struct bpf_zbuf_header *) zbuf->bz_bufb; - if (bzh->bzh_user_gen != atomic_load_acq_int(&bzh->bzh_kernel_gen)) { + if (chkZCbuf(bzh)) { rlen = atomic_load_acq_int(&bzh->bzh_kernel_len); *zcache = zbuf->bz_bufb; if (buf) buf = ((caddr_t) *zcache) + sizeof(struct bpf_zbuf_header); - } + ackZCbuf(bzh); + } else + io_SetErr(EAGAIN, "kernel owns the buffer"); } return rlen;