Index: net/bpf.c =================================================================== RCS file: /cvs/src/sys/net/bpf.c,v retrieving revision 1.176 diff -u -p -r1.176 bpf.c --- net/bpf.c 10 Jun 2019 23:49:45 -0000 1.176 +++ net/bpf.c 12 Jun 2019 06:02:21 -0000 @@ -104,7 +104,8 @@ int bpfpoll(dev_t, int, struct proc *); int bpfkqfilter(dev_t, struct knote *); void bpf_wakeup(struct bpf_d *); void bpf_wakeup_cb(void *); -void bpf_catchpacket(struct bpf_d *, u_char *, size_t, size_t, +void bpf_catchpacket(struct bpf_d *, const struct mbuf *, + u_char *, size_t, size_t, void (*)(const void *, void *, size_t), struct timeval *); int bpf_getdltlist(struct bpf_d *, struct bpf_dltlist *); int bpf_setdlt(struct bpf_d *, u_int); @@ -690,6 +691,7 @@ bpfioctl(dev_t dev, u_long cmd, caddr_t case BIOCIMMEDIATE: case TIOCGPGRP: case BIOCGDIRFILT: + case BIOCGMETAHDR: break; default: return (EPERM); @@ -991,6 +993,13 @@ bpfioctl(dev_t dev, u_long cmd, caddr_t case BIOCGRSIG: *(u_int *)addr = d->bd_sig; break; + + case BIOCGMETAHDR: + *(u_int *)addr = d->bd_meta; + break; + case BIOCSMETAHDR: + d->bd_meta = *(u_int *)addr; + break; } return (error); @@ -1299,7 +1308,7 @@ _bpf_mtap(caddr_t arg, const struct mbuf } mtx_enter(&d->bd_mtx); - bpf_catchpacket(d, (u_char *)m, pktlen, slen, cpfn, + bpf_catchpacket(d, m, (u_char *)m, pktlen, slen, cpfn, &tv); mtx_leave(&d->bd_mtx); } @@ -1460,10 +1469,12 @@ bpf_mtap_ether(caddr_t arg, const struct * pkt is really an mbuf. */ void -bpf_catchpacket(struct bpf_d *d, u_char *pkt, size_t pktlen, size_t snaplen, +bpf_catchpacket(struct bpf_d *d, const struct mbuf *m, + u_char *pkt, size_t pktlen, size_t snaplen, void (*cpfn)(const void *, void *, size_t), struct timeval *tv) { struct bpf_hdr *hp; + struct bpf_hdr_meta *mhp; int totlen, curlen; int hdrlen, do_wakeup = 0; @@ -1472,6 +1483,10 @@ bpf_catchpacket(struct bpf_d *d, u_char return; hdrlen = d->bd_bif->bif_hdrlen; + if (d->bd_meta && m != NULL && ISSET(m->m_flags, M_PKTHDR)) + hdrlen += sizeof(*mhp); + else + m = NULL; /* * Figure out how many bytes to move. If the packet is @@ -1514,6 +1529,16 @@ bpf_catchpacket(struct bpf_d *d, u_char hp->bh_tstamp.tv_usec = tv->tv_usec; hp->bh_datalen = pktlen; hp->bh_hdrlen = hdrlen; + + if (m != NULL) { + mhp = (struct bpf_hdr_meta *)(hp + 1); + mhp->bh_ifidx = m->m_pkthdr.ph_ifidx; + mhp->bh_flowid = m->m_pkthdr.ph_flowid; + mhp->bh_drops = m->m_pkthdr.drops; + mhp->bh_prio = m->m_pkthdr.pf.prio; + mhp->_bh_spare = 0; + } + /* * Copy the packet data into the store buffer and update its length. */ @@ -1615,13 +1640,8 @@ bpfsattach(caddr_t *bpfp, const char *na *bp->bif_driverp = NULL; - /* - * Compute the length of the bpf header. This is not necessarily - * equal to SIZEOF_BPF_HDR because we want to insert spacing such - * that the network layer header begins on a longword boundary (for - * performance reasons and to alleviate alignment restrictions). - */ - bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen; + bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + sizeof(struct bpf_hdr)) - + hdrlen; return (bp); } Index: net/bpf.h =================================================================== RCS file: /cvs/src/sys/net/bpf.h,v retrieving revision 1.66 diff -u -p -r1.66 bpf.h --- net/bpf.h 17 Mar 2019 23:57:12 -0000 1.66 +++ net/bpf.h 12 Jun 2019 06:02:21 -0000 @@ -119,6 +119,8 @@ struct bpf_version { #define BIOCGDLTLIST _IOWR('B',123, struct bpf_dltlist) #define BIOCGDIRFILT _IOR('B',124, u_int) #define BIOCSDIRFILT _IOW('B',125, u_int) +#define BIOCGMETAHDR _IOR('B',126, u_int) +#define BIOCSMETAHDR _IOW('B',126, u_int) /* * Direction filters for BIOCSDIRFILT/BIOCGDIRFILT @@ -164,6 +166,14 @@ struct bpf_hdr { #define SIZEOF_BPF_HDR sizeof(struct bpf_hdr) #endif #endif + +struct bpf_hdr_meta { + u_int16_t bh_ifidx; /* receive interface index */ + u_int16_t bh_flowid; + u_int16_t bh_drops; /* packets dropped from last packet */ + u_int8_t bh_prio; + u_int8_t _bh_spare; +}; /* * Data-link level type codes. Index: net/bpfdesc.h =================================================================== RCS file: /cvs/src/sys/net/bpfdesc.h,v retrieving revision 1.38 diff -u -p -r1.38 bpfdesc.h --- net/bpfdesc.h 18 May 2019 12:59:32 -0000 1.38 +++ net/bpfdesc.h 12 Jun 2019 06:02:21 -0000 @@ -68,6 +68,8 @@ struct bpf_d { int bd_slen; /* current length of store buffer */ int bd_hlen; /* current length of hold buffer */ int bd_bufsize; /* absolute length of buffers */ + u_int bd_raccum; /* inter-record packet drops */ + u_int bd_daccum; /* inter-record filter drops */ int bd_in_uiomove; /* for debugging purpose */ @@ -87,6 +89,7 @@ struct bpf_d { u_char bd_locked; /* true if descriptor is locked */ u_char bd_fildrop; /* true if filtered packets will be dropped */ u_char bd_dirfilt; /* direction filter */ + u_char bd_meta; /* add meta header */ int bd_hdrcmplt; /* false to fill in src lladdr automatically */ int bd_async; /* non-zero if packet reception should generate signal */ int bd_sig; /* signal to send upon packet reception */ Index: sys/mbuf.h =================================================================== RCS file: /cvs/src/sys/sys/mbuf.h,v retrieving revision 1.244 diff -u -p -r1.244 mbuf.h --- sys/mbuf.h 10 Jun 2019 23:45:19 -0000 1.244 +++ sys/mbuf.h 12 Jun 2019 06:02:21 -0000 @@ -137,6 +137,7 @@ struct pkthdr { u_int ph_ifidx; /* rcv interface index */ u_int8_t ph_loopcnt; /* mbuf is looping in kernel */ u_int8_t ph_family; /* af, used when queueing */ + u_int16_t drops; struct pkthdr_pf pf; }; Index: dev/pci/if_mcx.c =================================================================== RCS file: /cvs/src/sys/dev/pci/if_mcx.c,v retrieving revision 1.26 diff -u -p -r1.26 if_mcx.c --- dev/pci/if_mcx.c 11 Jun 2019 06:28:09 -0000 1.26 +++ dev/pci/if_mcx.c 12 Jun 2019 06:02:21 -0000 @@ -1253,7 +1253,8 @@ struct mcx_cq_entry { uint32_t __reserved__[2]; uint32_t cq_byte_cnt; uint64_t cq_timestamp; - uint32_t cq_rx_drops; + uint8_t cq_rx_drops; + uint8_t cq_flow_tag[3]; uint16_t cq_wqe_count; uint8_t cq_signature; uint8_t cq_opcode_owner; @@ -5652,6 +5653,7 @@ mcx_process_rx(struct mcx_softc *sc, str ms->ms_m = NULL; m->m_pkthdr.len = m->m_len = bemtoh32(&cqe->cq_byte_cnt); + m->m_pkthdr.drops = cqe->cq_rx_drops; if (cqe->cq_rx_hash_type) { m->m_pkthdr.ph_flowid = M_FLOWID_VALID |