MFC: Change the life cycle of bpf interface objects to close attach/detach

races with bpf(4).  This includes shims to preserve the ABI for any old
modules.  For more details see the commit log for 1.166 of sys/net/bpf.c.
This commit is contained in:
jhb 2007-01-19 23:01:34 +00:00
parent 663437bbf2
commit bd48914a94
38 changed files with 197 additions and 186 deletions

View File

@ -1761,8 +1761,12 @@ pfsync_sendout(sc)
KASSERT(m != NULL, ("pfsync_sendout: null mbuf"));
#endif
#if NBPFILTER > 0
#ifdef __FreeBSD__
BPF_MTAP(ifp, m);
#else
if (ifp->if_bpf)
bpf_mtap(ifp->if_bpf, m);
#endif
#endif
if (sc->sc_mbuf_net) {

View File

@ -980,7 +980,7 @@ arl_read(sc, buf, len)
* Check if there's a bpf filter listening on this interface.
* If so, hand off the raw packet to bpf.
*/
if (ifp->if_bpf) {
if (bpf_peers_present(ifp->if_bpf)) {
/*
* Note that the interface cannot be in promiscuous mode if
* there are no bpf listeners. And if el are in promiscuous

View File

@ -3019,7 +3019,7 @@ ath_rx_proc(void *arg, int npending)
* pass decrypt+mic errors but others may be
* interesting (e.g. crc).
*/
if (sc->sc_drvbpf != NULL &&
if (bpf_peers_present(sc->sc_drvbpf) &&
(ds->ds_rxstat.rs_status & sc->sc_monpass)) {
bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap,
BUS_DMASYNC_POSTREAD);
@ -3050,7 +3050,8 @@ ath_rx_proc(void *arg, int npending)
sc->sc_stats.ast_ant_rx[ds->ds_rxstat.rs_antenna]++;
if (sc->sc_drvbpf != NULL && !ath_rx_tap(sc, m, ds, tsf, nf)) {
if (bpf_peers_present(sc->sc_drvbpf) &&
!ath_rx_tap(sc, m, ds, tsf, nf)) {
m_freem(m); /* XXX reclaim */
goto rx_next;
}
@ -3752,9 +3753,9 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf
ieee80211_dump_pkt(mtod(m0, caddr_t), m0->m_len,
sc->sc_hwmap[txrate].ieeerate, -1);
if (ic->ic_rawbpf)
if (bpf_peers_present(ic->ic_rawbpf))
bpf_mtap(ic->ic_rawbpf, m0);
if (sc->sc_drvbpf) {
if (bpf_peers_present(sc->sc_drvbpf)) {
u_int64_t tsf = ath_hal_gettsf64(ah);
sc->sc_tx_th.wt_tsf = htole64(tsf);

View File

@ -796,7 +796,7 @@ awi_start(struct ifnet *ifp)
}
IFQ_DEQUEUE(&ifp->if_snd, m0);
#if NBPFILTER > 0
if (ifp->if_bpf)
if (bpf_peers_present(ifp->if_bpf))
bpf_mtap(ifp->if_bpf, m0);
#endif
if ((ifp->if_flags & IFF_LINK0) || sc->sc_adhoc_ap)
@ -839,7 +839,7 @@ awi_start(struct ifnet *ifp)
ifp->if_opackets++;
}
#if NBPFILTER > 0
if (ic->ic_rawbpf)
if (bpf_peers_present(ic->ic_rawbpf))
bpf_mtap(ic->ic_rawbpf, m0);
#endif
if (dowep) {

View File

@ -1069,10 +1069,10 @@ static void ce_send (drv_t *d)
if (! m)
return;
#ifndef NETGRAPH
if (d->ifp->if_bpf)
#if __FreeBSD_version >= 500000
BPF_MTAP (d->ifp, m);
BPF_MTAP (d->ifp, m);
#else
if (d->ifp->if_bpf)
bpf_mtap (d->ifp, m);
#endif
#endif
@ -1191,10 +1191,10 @@ static void ce_receive (ce_chan_t *c, unsigned char *data, int len)
m->m_pkthdr.rcvif = d->ifp;
/* Check if there's a BPF listener on this interface.
* If so, hand off the raw packet to bpf. */
if (d->ifp->if_bpf)
#if __FreeBSD_version >= 500000
BPF_TAP (d->ifp, data, len);
BPF_TAP (d->ifp, data, len);
#else
if (d->ifp->if_bpf)
bpf_tap (d->ifp, data, len);
#endif
IF_ENQUEUE(&d->rqueue, m);

View File

@ -821,8 +821,7 @@ static void cp_send (drv_t *d)
if (! m)
return;
#ifndef NETGRAPH
if (d->ifp->if_bpf)
BPF_MTAP (d->ifp, m);
BPF_MTAP (d->ifp, m);
#endif
len = m_length (m, NULL);
if (len >= BUFSZ)
@ -931,8 +930,7 @@ static void cp_receive (cp_chan_t *c, unsigned char *data, int len)
m->m_pkthdr.rcvif = d->ifp;
/* Check if there's a BPF listener on this interface.
* If so, hand off the raw packet to bpf. */
if (d->ifp->if_bpf)
BPF_TAP (d->ifp, data, len);
BPF_TAP (d->ifp, data, len);
IF_ENQUEUE (&d->queue, m);
#endif
}

View File

@ -1030,8 +1030,7 @@ static void ct_send (drv_t *d)
if (! m)
return;
#ifndef NETGRAPH
if (d->ifp->if_bpf)
BPF_MTAP (d->ifp, m);
BPF_MTAP (d->ifp, m);
#endif
len = m_length (m, NULL);
if (! m->m_next)
@ -1151,8 +1150,7 @@ static void ct_receive (ct_chan_t *c, char *data, int len)
m->m_pkthdr.rcvif = d->ifp;
/* Check if there's a BPF listener on this interface.
* If so, hand off the raw packet to bpf. */
if (d->ifp->if_bpf)
BPF_TAP (d->ifp, data, len);
BPF_TAP (d->ifp, data, len);
IF_ENQUEUE (&d->queue, m);
#endif
}

View File

@ -1185,8 +1185,7 @@ static void cx_send (drv_t *d)
if (! m)
return;
#ifndef NETGRAPH
if (d->ifp->if_bpf)
BPF_MTAP (d->ifp, m);
BPF_MTAP (d->ifp, m);
#endif
len = m_length (m, NULL);
if (! m->m_next)
@ -1342,8 +1341,7 @@ static void cx_receive (cx_chan_t *c, char *data, int len)
m->m_pkthdr.rcvif = d->ifp;
/* Check if there's a BPF listener on this interface.
* If so, hand off the raw packet to bpf. */
if (d->ifp->if_bpf)
BPF_TAP (d->ifp, data, len);
BPF_TAP (d->ifp, data, len);
IF_ENQUEUE (&d->queue, m);
#endif
}

View File

@ -776,7 +776,7 @@ en_txdma(struct en_softc *sc, struct en_txslot *slot)
sc->vccs[tx.vci]->obytes += tx.datalen;
#ifdef ENABLE_BPF
if (sc->ifp->if_bpf != NULL) {
if (bpf_peers_present(sc->ifp->if_bpf)) {
/*
* adjust the top of the mbuf to skip the TBD if present
* before passing the packet to bpf.
@ -794,7 +794,7 @@ en_txdma(struct en_softc *sc, struct en_txslot *slot)
tx.m->m_pkthdr.len = tx.datalen;
}
BPF_MTAP(sc->ifp, tx.m);
bpf_mtap(sc->ifp->if_bpf, tx.m);
}
#endif

View File

@ -838,7 +838,7 @@ fwip_stream_input(struct fw_xferq *xferq)
* Record the sender ID for possible BPF usage.
*/
src = ntohl(p[1]) >> 16;
if (ifp->if_bpf) {
if (bpf_peers_present(ifp->if_bpf)) {
mtag = m_tag_alloc(MTAG_FIREWIRE,
MTAG_FIREWIRE_SENDER_EUID,
2*sizeof(uint32_t), M_NOWAIT);
@ -939,7 +939,7 @@ fwip_unicast_input(struct fw_xfer *xfer)
return;
}
if (ifp->if_bpf) {
if (bpf_peers_present(ifp->if_bpf)) {
/*
* Record the sender ID for possible BPF usage.
*/

View File

@ -1205,8 +1205,7 @@ gem_start_locked(ifp)
bus_space_write_4(sc->sc_bustag, sc->sc_h, GEM_TX_KICK,
sc->sc_txnext);
if (ifp->if_bpf != NULL)
bpf_mtap(ifp->if_bpf, m0);
BPF_MTAP(ifp, m0);
} while (1);
if (txmfail == -1 || sc->sc_txfree == 0) {

View File

@ -1071,7 +1071,7 @@ ipw_data_intr(struct ipw_softc *sc, struct ipw_status *status,
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = le32toh(status->len);
if (sc->sc_drvbpf != NULL) {
if (bpf_peers_present(sc->sc_drvbpf)) {
struct ipw_rx_radiotap_header *tap = &sc->sc_rxtap;
tap->wr_flags = 0;
@ -1348,7 +1348,7 @@ ipw_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni)
wh = mtod(m0, struct ieee80211_frame *);
}
if (sc->sc_drvbpf != NULL) {
if (bpf_peers_present(sc->sc_drvbpf)) {
struct ipw_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
@ -1516,7 +1516,7 @@ ipw_start(struct ifnet *ifp)
continue;
}
if (ic->ic_rawbpf != NULL)
if (bpf_peers_present(ic->ic_rawbpf))
bpf_mtap(ic->ic_rawbpf, m0);
if (ipw_tx_start(ifp, m0, ni) != 0) {

View File

@ -1302,7 +1302,7 @@ iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i,
m_adj(m, sizeof (struct iwi_hdr) + sizeof (struct iwi_frame));
if (sc->sc_drvbpf != NULL) {
if (bpf_peers_present(sc->sc_drvbpf)) {
struct iwi_rx_radiotap_header *tap = &sc->sc_rxtap;
tap->wr_flags = 0;
@ -1831,7 +1831,7 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni,
wh = mtod(m0, struct ieee80211_frame *);
}
if (sc->sc_drvbpf != NULL) {
if (bpf_peers_present(sc->sc_drvbpf)) {
struct iwi_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
@ -1986,7 +1986,7 @@ iwi_start(struct ifnet *ifp)
continue;
}
if (ic->ic_rawbpf != NULL)
if (bpf_peers_present(ic->ic_rawbpf))
bpf_mtap(ic->ic_rawbpf, m0);
if (iwi_tx_start(ifp, m0, ni, ac) != 0) {

View File

@ -1153,8 +1153,8 @@ my_rxeof(struct my_softc * sc)
* broadcast packet, multicast packet, matches our ethernet
* address or the interface is in promiscuous mode.
*/
if (ifp->if_bpf) {
BPF_MTAP(ifp, m);
if (bpf_peers_present(ifp->if_bpf)) {
bpf_mtap(ifp->if_bpf, m);
if (ifp->if_flags & IFF_PROMISC &&
(bcmp(eh->ether_dhost, IFP2ENADDR(sc->my_ifp),
ETHER_ADDR_LEN) &&

View File

@ -455,7 +455,7 @@ static void
lptap(struct ifnet *ifp, struct mbuf *m)
{
u_int32_t af = AF_INET;
BPF_MTAP2(ifp, &af, sizeof(af), m);
bpf_mtap2(ifp->if_bpf, &af, sizeof(af), m);
}
static void
@ -514,7 +514,7 @@ lp_intr (void *arg)
sc->sc_ifp->if_ibytes += len;
top = m_devget(sc->sc_ifbuf + CLPIPHDRLEN, len, 0, sc->sc_ifp, 0);
if (top) {
if (sc->sc_ifp->if_bpf)
if (bpf_peers_present(sc->sc_ifp->if_bpf))
lptap(sc->sc_ifp, top);
netisr_queue(NETISR_IP, top); /* mbuf is free'd on failure. */
}
@ -559,7 +559,7 @@ lp_intr (void *arg)
sc->sc_ifp->if_ibytes += len;
top = m_devget(sc->sc_ifbuf + LPIPHDRLEN, len, 0, sc->sc_ifp, 0);
if (top) {
if (sc->sc_ifp->if_bpf)
if (bpf_peers_present(sc->sc_ifp->if_bpf))
lptap(sc->sc_ifp, top);
netisr_queue(NETISR_IP, top); /* mbuf is free'd on failure. */
}
@ -694,7 +694,7 @@ lpoutput (struct ifnet *ifp, struct mbuf *m,
} else {
ifp->if_opackets++;
ifp->if_obytes += m->m_pkthdr.len;
if (ifp->if_bpf)
if (bpf_peers_present(ifp->if_bpf))
lptap(ifp, m);
}
@ -739,7 +739,7 @@ lpoutput (struct ifnet *ifp, struct mbuf *m,
} else {
ifp->if_opackets++;
ifp->if_obytes += m->m_pkthdr.len;
if (ifp->if_bpf)
if (bpf_peers_present(ifp->if_bpf))
lptap(ifp, m);
}

View File

@ -1225,7 +1225,7 @@ rt2560_decryption_intr(struct rt2560_softc *sc)
m->m_pkthdr.len = m->m_len =
(le32toh(desc->flags) >> 16) & 0xfff;
if (sc->sc_drvbpf != NULL) {
if (bpf_peers_present(sc->sc_drvbpf)) {
struct rt2560_rx_radiotap_header *tap = &sc->sc_rxtap;
uint32_t tsf_lo, tsf_hi;
@ -1346,7 +1346,7 @@ rt2560_beacon_expire(struct rt2560_softc *sc)
ieee80211_beacon_update(ic, data->ni, &sc->sc_bo, data->m, 1);
if (ic->ic_rawbpf != NULL)
if (bpf_peers_present(ic->ic_rawbpf))
bpf_mtap(ic->ic_rawbpf, data->m);
rt2560_tx_bcn(sc, data->m, data->ni);
@ -1606,7 +1606,7 @@ rt2560_tx_bcn(struct rt2560_softc *sc, struct mbuf *m0,
return error;
}
if (sc->sc_drvbpf != NULL) {
if (bpf_peers_present(sc->sc_drvbpf)) {
struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
@ -1663,7 +1663,7 @@ rt2560_tx_mgt(struct rt2560_softc *sc, struct mbuf *m0,
return error;
}
if (sc->sc_drvbpf != NULL) {
if (bpf_peers_present(sc->sc_drvbpf)) {
struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
@ -1882,7 +1882,7 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0,
wh = mtod(m0, struct ieee80211_frame *);
}
if (sc->sc_drvbpf != NULL) {
if (bpf_peers_present(sc->sc_drvbpf)) {
struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
@ -1961,7 +1961,7 @@ rt2560_start(struct ifnet *ifp)
ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
m0->m_pkthdr.rcvif = NULL;
if (ic->ic_rawbpf != NULL)
if (bpf_peers_present(ic->ic_rawbpf))
bpf_mtap(ic->ic_rawbpf, m0);
if (rt2560_tx_mgt(sc, m0, ni) != 0)
@ -1997,7 +1997,7 @@ rt2560_start(struct ifnet *ifp)
continue;
}
if (ic->ic_rawbpf != NULL)
if (bpf_peers_present(ic->ic_rawbpf))
bpf_mtap(ic->ic_rawbpf, m0);
if (rt2560_tx_data(sc, m0, ni) != 0) {

View File

@ -1136,7 +1136,7 @@ rt2661_rx_intr(struct rt2661_softc *sc)
m->m_pkthdr.len = m->m_len =
(le32toh(desc->flags) >> 16) & 0xfff;
if (sc->sc_drvbpf != NULL) {
if (bpf_peers_present(sc->sc_drvbpf)) {
struct rt2661_rx_radiotap_header *tap = &sc->sc_rxtap;
uint32_t tsf_lo, tsf_hi;
@ -1484,7 +1484,7 @@ rt2661_tx_mgt(struct rt2661_softc *sc, struct mbuf *m0,
return error;
}
if (sc->sc_drvbpf != NULL) {
if (bpf_peers_present(sc->sc_drvbpf)) {
struct rt2661_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
@ -1708,7 +1708,7 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
wh = mtod(m0, struct ieee80211_frame *);
}
if (sc->sc_drvbpf != NULL) {
if (bpf_peers_present(sc->sc_drvbpf)) {
struct rt2661_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
@ -1786,7 +1786,7 @@ rt2661_start(struct ifnet *ifp)
ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
m0->m_pkthdr.rcvif = NULL;
if (ic->ic_rawbpf != NULL)
if (bpf_peers_present(ic->ic_rawbpf))
bpf_mtap(ic->ic_rawbpf, m0);
if (rt2661_tx_mgt(sc, m0, ni) != 0)
@ -1840,7 +1840,7 @@ rt2661_start(struct ifnet *ifp)
continue;
}
if (ic->ic_rawbpf != NULL)
if (bpf_peers_present(ic->ic_rawbpf))
bpf_mtap(ic->ic_rawbpf, m0);
if (rt2661_tx_data(sc, m0, ni, ac) != 0) {

View File

@ -958,7 +958,7 @@ ural_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
m->m_pkthdr.len = m->m_len = (le32toh(desc->flags) >> 16) & 0xfff;
m->m_flags |= M_HASFCS; /* h/w leaves FCS */
if (sc->sc_drvbpf != NULL) {
if (bpf_peers_present(sc->sc_drvbpf)) {
struct ural_rx_radiotap_header *tap = &sc->sc_rxtap;
tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
@ -1206,7 +1206,7 @@ ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
flags |= RAL_TX_TIMESTAMP;
}
if (sc->sc_drvbpf != NULL) {
if (bpf_peers_present(sc->sc_drvbpf)) {
struct ural_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
@ -1295,7 +1295,7 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
*(uint16_t *)wh->i_dur = htole16(dur);
}
if (sc->sc_drvbpf != NULL) {
if (bpf_peers_present(sc->sc_drvbpf)) {
struct ural_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
@ -1357,7 +1357,7 @@ ural_start(struct ifnet *ifp)
ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
m0->m_pkthdr.rcvif = NULL;
if (ic->ic_rawbpf != NULL)
if (bpf_peers_present(ic->ic_rawbpf))
bpf_mtap(ic->ic_rawbpf, m0);
if (ural_tx_mgt(sc, m0, ni) != 0)
@ -1393,7 +1393,7 @@ ural_start(struct ifnet *ifp)
continue;
}
if (ic->ic_rawbpf != NULL)
if (bpf_peers_present(ic->ic_rawbpf))
bpf_mtap(ic->ic_rawbpf, m0);
if (ural_tx_data(sc, m0, ni) != 0) {

View File

@ -966,7 +966,7 @@ wi_start(struct ifnet *ifp)
wh = mtod(m0, struct ieee80211_frame *);
}
#if NBPFILTER > 0
if (ic->ic_rawbpf)
if (bpf_peers_present(ic->ic_rawbpf))
bpf_mtap(ic->ic_rawbpf, m0);
#endif
frmhdr.wi_tx_ctl = htole16(WI_ENC_TX_802_11|WI_TXCNTL_TX_EX);
@ -985,7 +985,7 @@ wi_start(struct ifnet *ifp)
frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT);
}
#if NBPFILTER > 0
if (sc->sc_drvbpf) {
if (bpf_peers_present(ic->ic_rawbpf)) {
sc->sc_tx_th.wt_rate =
ni->ni_rates.rs_rates[ni->ni_txrate];
bpf_mtap2(sc->sc_drvbpf,
@ -1539,7 +1539,7 @@ wi_rx_intr(struct wi_softc *sc)
}
#if NBPFILTER > 0
if (sc->sc_drvbpf) {
if (bpf_peers_present(sc->sc_drvbpf)) {
/* XXX replace divide by table */
sc->sc_rx_th.wr_rate = frmhdr.wi_rx_rate / 5;
sc->sc_rx_th.wr_antsignal = frmhdr.wi_rx_signal;

View File

@ -883,7 +883,7 @@ ipr_rx_data_rdy(int unit)
}
#endif
if(sc->sc_ifp->if_bpf)
if(bpf_peers_present(sc->sc_ifp->if_bpf))
{
/* prepend the address family as a four byte field */
struct mbuf mm;
@ -891,7 +891,7 @@ ipr_rx_data_rdy(int unit)
mm.m_next = m;
mm.m_len = 4;
mm.m_data = (char *)⁡
BPF_MTAP(sc->sc_ifp, &mm);
bpf_mtap(sc->sc_ifp->if_bpf, &mm);
}
if(netisr_queue(NETISR_IP, m)) /* (0) on success. */
@ -936,7 +936,7 @@ ipr_tx_queue_empty(int unit)
microtime(&sc->sc_ifp->if_lastchange);
if(sc->sc_ifp->if_bpf)
if(bpf_peers_present(sc->sc_ifp->if_bpf))
{
/* prepend the address family as a four byte field */
@ -945,7 +945,7 @@ ipr_tx_queue_empty(int unit)
mm.m_next = m;
mm.m_len = 4;
mm.m_data = (char *)⁡
BPF_MTAP(sc->sc_ifp, &mm);
bpf_mtap(sc->sc_ifp->if_bpf, &mm);
}
#if I4BIPRACCT

View File

@ -299,7 +299,6 @@ bpf_attachd(d, bp)
LIST_INSERT_HEAD(&bp->bif_dlist, d, bd_next);
bpf_bpfd_cnt++;
*bp->bif_driverp = bp;
BPFIF_UNLOCK(bp);
}
@ -325,12 +324,6 @@ bpf_detachd(d)
LIST_REMOVE(d, bd_next);
bpf_bpfd_cnt--;
/*
* Let the driver know that there are no more listeners.
*/
if (LIST_EMPTY(&bp->bif_dlist))
*bp->bif_driverp = NULL;
d->bd_bif = NULL;
BPFD_UNLOCK(d);
BPFIF_UNLOCK(bp);
@ -1080,51 +1073,33 @@ bpf_setif(d, ifr)
struct ifnet *theywant;
theywant = ifunit(ifr->ifr_name);
if (theywant == NULL)
return ENXIO;
if (theywant == NULL || theywant->if_bpf == NULL)
return (ENXIO);
bp = theywant->if_bpf;
/*
* Look through attached interfaces for the named one.
* Allocate the packet buffers if we need to.
* If we're already attached to requested interface,
* just flush the buffer.
*/
mtx_lock(&bpf_mtx);
LIST_FOREACH(bp, &bpf_iflist, bif_next) {
struct ifnet *ifp = bp->bif_ifp;
if (ifp == NULL || ifp != theywant)
continue;
/* skip additional entry */
if (bp->bif_driverp != &ifp->if_bpf)
continue;
mtx_unlock(&bpf_mtx);
/*
* We found the requested interface.
* Allocate the packet buffers if we need to.
* If we're already attached to requested interface,
* just flush the buffer.
*/
if (d->bd_sbuf == NULL) {
error = bpf_allocbufs(d);
if (error != 0)
return (error);
}
if (bp != d->bd_bif) {
if (d->bd_bif)
/*
* Detach if attached to something else.
*/
bpf_detachd(d);
bpf_attachd(d, bp);
}
BPFD_LOCK(d);
reset_d(d);
BPFD_UNLOCK(d);
return (0);
if (d->bd_sbuf == NULL) {
error = bpf_allocbufs(d);
if (error != 0)
return (error);
}
mtx_unlock(&bpf_mtx);
/* Not found. */
return (ENXIO);
if (bp != d->bd_bif) {
if (d->bd_bif)
/*
* Detach if attached to something else.
*/
bpf_detachd(d);
bpf_attachd(d, bp);
}
BPFD_LOCK(d);
reset_d(d);
BPFD_UNLOCK(d);
return (0);
}
/*
@ -1244,13 +1219,6 @@ bpf_tap(bp, pkt, pktlen)
int gottime;
struct timeval tv;
/*
* Lockless read to avoid cost of locking the interface if there are
* no descriptors attached.
*/
if (LIST_EMPTY(&bp->bif_dlist))
return;
gottime = 0;
BPFIF_LOCK(bp);
LIST_FOREACH(d, &bp->bif_dlist, bd_next) {
@ -1315,13 +1283,6 @@ bpf_mtap(bp, m)
gottime = 0;
/*
* Lockless read to avoid cost of locking the interface if there are
* no descriptors attached.
*/
if (LIST_EMPTY(&bp->bif_dlist))
return;
pktlen = m_length(m, NULL);
BPFIF_LOCK(bp);
@ -1367,13 +1328,6 @@ bpf_mtap2(bp, data, dlen, m)
gottime = 0;
/*
* Lockless read to avoid cost of locking the interface if there are
* no descriptors attached.
*/
if (LIST_EMPTY(&bp->bif_dlist))
return;
pktlen = m_length(m, NULL);
/*
* Craft on-stack mbuf suitable for passing to bpf_filter.
@ -1566,17 +1520,16 @@ bpfattach2(ifp, dlt, hdrlen, driverp)
panic("bpfattach");
LIST_INIT(&bp->bif_dlist);
bp->bif_driverp = driverp;
bp->bif_ifp = ifp;
bp->bif_dlt = dlt;
mtx_init(&bp->bif_mtx, "bpf interface lock", NULL, MTX_DEF);
KASSERT(*driverp == NULL, ("bpfattach2: driverp already initialized"));
*driverp = bp;
mtx_lock(&bpf_mtx);
LIST_INSERT_HEAD(&bpf_iflist, bp, bif_next);
mtx_unlock(&bpf_mtx);
*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
@ -1815,6 +1768,7 @@ SYSINIT(bpfdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE,bpf_drvinit,NULL)
* A 'better' implementation would allow the core bpf functionality
* to be loaded at runtime.
*/
static struct bpf_if bp_null;
void
bpf_tap(bp, pkt, pktlen)
@ -1845,6 +1799,8 @@ bpfattach(ifp, dlt, hdrlen)
struct ifnet *ifp;
u_int dlt, hdrlen;
{
bpfattach2(ifp, dlt, hdrlen, &ifp->if_bpf);
}
void
@ -1853,6 +1809,8 @@ bpfattach2(ifp, dlt, hdrlen, driverp)
u_int dlt, hdrlen;
struct bpf_if **driverp;
{
*driverp = &bp_null;
}
void
@ -1880,3 +1838,50 @@ bpf_validate(f, len)
}
#endif /* !DEV_BPF && !NETGRAPH_BPF */
/*
* ABI compatibility hacks. Older drivers check if_bpf against NULL
* to see if there are active listeners. In the new ABI, if_bpf is
* always non-NULL, so bpf_*tap() are always invoked. We check for
* listeners in these wrappers and call the real functions if needed.
*/
#undef bpf_tap
#undef bpf_mtap
#undef bpf_mtap2
void bpf_tap(struct bpf_if *, u_char *, u_int);
void bpf_mtap(struct bpf_if *, struct mbuf *);
void bpf_mtap2(struct bpf_if *, void *, u_int, struct mbuf *);
void
bpf_tap(bp, pkt, pktlen)
struct bpf_if *bp;
u_char *pkt;
u_int pktlen;
{
if (bpf_peers_present(bp))
bpf_tap_new(bp, pkt, pktlen);
}
void
bpf_mtap(bp, m)
struct bpf_if *bp;
struct mbuf *m;
{
if (bpf_peers_present(bp))
bpf_mtap_new(bp, m);
}
void
bpf_mtap2(bp, d, l, m)
struct bpf_if *bp;
void *d;
u_int l;
struct mbuf *m;
{
if (bpf_peers_present(bp))
bpf_mtap2_new(bp, d, l, m);
}

View File

@ -615,7 +615,23 @@ struct bpf_dltlist {
};
#ifdef _KERNEL
struct bpf_if;
/*
* Descriptor associated with each attached hardware interface.
*/
struct bpf_if {
LIST_ENTRY(bpf_if) bif_next; /* list of all interfaces */
LIST_HEAD(, bpf_d) bif_dlist; /* descriptor list */
u_int bif_dlt; /* link layer type */
u_int bif_hdrlen; /* length of header (with padding) */
struct ifnet *bif_ifp; /* corresponding interface */
struct mtx bif_mtx; /* mutex for interface */
};
/* ABI compatibility hacks. */
#define bpf_tap bpf_tap_new
#define bpf_mtap bpf_mtap_new
#define bpf_mtap2 bpf_mtap2_new
int bpf_validate(const struct bpf_insn *, int);
void bpf_tap(struct bpf_if *, u_char *, u_int);
void bpf_mtap(struct bpf_if *, struct mbuf *);
@ -627,18 +643,27 @@ void bpfdetach(struct ifnet *);
void bpfilterattach(int);
u_int bpf_filter(const struct bpf_insn *, u_char *, u_int, u_int);
static __inline int
bpf_peers_present(struct bpf_if *bpf)
{
if (!LIST_EMPTY(&bpf->bif_dlist))
return (1);
return (0);
}
#define BPF_TAP(_ifp,_pkt,_pktlen) do { \
if ((_ifp)->if_bpf) \
if (bpf_peers_present((_ifp)->if_bpf)) \
bpf_tap((_ifp)->if_bpf, (_pkt), (_pktlen)); \
} while (0)
#define BPF_MTAP(_ifp,_m) do { \
if ((_ifp)->if_bpf) { \
if (bpf_peers_present((_ifp)->if_bpf)) { \
M_ASSERTVALID(_m); \
bpf_mtap((_ifp)->if_bpf, (_m)); \
} \
} while (0)
#define BPF_MTAP2(_ifp,_data,_dlen,_m) do { \
if ((_ifp)->if_bpf) { \
if (bpf_peers_present((_ifp)->if_bpf)) { \
M_ASSERTVALID(_m); \
bpf_mtap2((_ifp)->if_bpf,(_data),(_dlen),(_m)); \
} \

View File

@ -117,19 +117,6 @@ struct bpf_d {
(((bd)->bd_immediate || (bd)->bd_state == BPF_TIMED_OUT) && \
(bd)->bd_slen != 0))
/*
* Descriptor associated with each attached hardware interface.
*/
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) */
struct ifnet *bif_ifp; /* corresponding interface */
struct mtx bif_mtx; /* mutex for interface */
};
/*
* External representation of the bpf descriptor
*/

View File

@ -187,7 +187,7 @@ discoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
dst->sa_family = af;
}
if (ifp->if_bpf) {
if (bpf_peers_present(ifp->if_bpf)) {
u_int af = dst->sa_family;
bpf_mtap2(ifp->if_bpf, &af, sizeof(af), m);
}

View File

@ -280,7 +280,7 @@ ipsec_bpf(struct mbuf *m, struct secasvar *sav, int af)
if ((encif->if_drv_flags & IFF_DRV_RUNNING) == 0)
return;
if (encif->if_bpf) {
if (bpf_peers_present(encif->if_bpf)) {
flags = 0;
if (sav->alg_enc != SADB_EALG_NONE)
flags |= M_CONF;

View File

@ -235,7 +235,7 @@ faithoutput(ifp, m, dst, rt)
dst->sa_family = af;
}
if (ifp->if_bpf) {
if (bpf_peers_present(ifp->if_bpf)) {
af = dst->sa_family;
bpf_mtap2(ifp->if_bpf, &af, sizeof(af), m);
}

View File

@ -190,7 +190,7 @@ firewire_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
/*
* Let BPF tap off a copy before we encapsulate.
*/
if (ifp->if_bpf) {
if (bpf_peers_present(ifp->if_bpf)) {
struct fw_bpfhdr h;
if (unicast)
bcopy(destfw, h.firewire_dhost, 8);
@ -565,7 +565,7 @@ firewire_input(struct ifnet *ifp, struct mbuf *m, uint16_t src)
* Give bpf a chance at the packet. The link-level driver
* should have left us a tag with the EUID of the sender.
*/
if (ifp->if_bpf) {
if (bpf_peers_present(ifp->if_bpf)) {
struct fw_bpfhdr h;
struct m_tag *mtag;

View File

@ -442,9 +442,7 @@ gif_output(ifp, m, dst, rt)
}
af = dst->sa_family;
if (ifp->if_bpf) {
bpf_mtap2(ifp->if_bpf, &af, sizeof(af), m);
}
BPF_MTAP2(ifp, &af, sizeof(af), m);
ifp->if_opackets++;
ifp->if_obytes += m->m_pkthdr.len;
@ -501,7 +499,7 @@ gif_input(m, af, ifp)
mac_create_mbuf_from_ifnet(ifp, m);
#endif
if (ifp->if_bpf) {
if (bpf_peers_present(ifp->if_bpf)) {
u_int32_t af1 = af;
bpf_mtap2(ifp->if_bpf, &af1, sizeof(af1), m);
}

View File

@ -282,7 +282,7 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
dst->sa_family = af;
}
if (ifp->if_bpf) {
if (bpf_peers_present(ifp->if_bpf)) {
af = dst->sa_family;
bpf_mtap2(ifp->if_bpf, &af, sizeof(af), m);
}

View File

@ -269,11 +269,11 @@ if_simloop(ifp, m, af, hlen)
* -> passes to lo0's BPF (even in case of IPv6, where ifp!=lo0)
*/
if (hlen > 0) {
if (ifp->if_bpf != NULL) {
if (bpf_peers_present(ifp->if_bpf)) {
bpf_mtap(ifp->if_bpf, m);
}
} else {
if (loif->if_bpf != NULL) {
if (bpf_peers_present(loif->if_bpf)) {
if ((m->m_flags & M_MCAST) == 0 || loif == ifp) {
/* XXX beware sizeof(af) != 4 */
u_int32_t af1 = af;

View File

@ -662,7 +662,7 @@ sltstart(struct tty *tp)
* queueing, and the connection id compression will get
* munged when this happens.
*/
if (SL2IFP(sc)->if_bpf) {
if (bpf_peers_present(SL2IFP(sc)->if_bpf)) {
/*
* We need to save the TCP/IP header before it's
* compressed. To avoid complicated code, we just
@ -696,7 +696,7 @@ sltstart(struct tty *tp)
*mtod(m, u_char *) |= sl_compress_tcp(m, ip,
&sc->sc_comp, 1);
}
if (SL2IFP(sc)->if_bpf && sc->bpfbuf) {
if (bpf_peers_present(SL2IFP(sc)->if_bpf) && sc->bpfbuf) {
/*
* Put the SLIP pseudo-"link header" in place. The
* compressed header is now at the beginning of the
@ -922,7 +922,7 @@ slinput(int c, struct tty *tp)
/* less than min length packet - ignore */
goto newpack;
if (SL2IFP(sc)->if_bpf) {
if (bpf_peers_present(SL2IFP(sc)->if_bpf)) {
/*
* Save the compressed header, so we
* can tack it on later. Note that we
@ -961,7 +961,7 @@ slinput(int c, struct tty *tp)
} else
goto error;
}
if (SL2IFP(sc)->if_bpf) {
if (bpf_peers_present(SL2IFP(sc)->if_bpf)) {
/*
* Put the SLIP pseudo-"link header" in place.
* We couldn't do this any earlier since

View File

@ -509,7 +509,7 @@ stf_output(ifp, m, dst, rt)
}
bcopy(ptr, &in4, sizeof(in4));
if (ifp->if_bpf) {
if (bpf_peers_present(ifp->if_bpf)) {
/*
* We need to prepend the address family as
* a four byte field. Cons up a dummy header
@ -756,7 +756,7 @@ in_stf_input(m, off)
m->m_pkthdr.rcvif = ifp;
if (ifp->if_bpf) {
if (bpf_peers_present(ifp->if_bpf)) {
/*
* We need to prepend the address family as
* a four byte field. Cons up a dummy header

View File

@ -536,7 +536,7 @@ tunoutput(
dst->sa_family = af;
}
if (ifp->if_bpf) {
if (bpf_peers_present(ifp->if_bpf)) {
af = dst->sa_family;
bpf_mtap2(ifp->if_bpf, &af, sizeof(af), m0);
}

View File

@ -423,7 +423,7 @@ ieee80211_input(struct ieee80211com *ic, struct mbuf *m,
}
/* copy to listener after decrypt */
if (ic->ic_rawbpf)
if (bpf_peers_present(ic->ic_rawbpf))
bpf_mtap(ic->ic_rawbpf, m);
/*
@ -534,7 +534,7 @@ ieee80211_input(struct ieee80211com *ic, struct mbuf *m,
wh = mtod(m, struct ieee80211_frame *);
wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
}
if (ic->ic_rawbpf)
if (bpf_peers_present(ic->ic_rawbpf))
bpf_mtap(ic->ic_rawbpf, m);
(*ic->ic_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp);
m_freem(m);
@ -561,7 +561,7 @@ ieee80211_input(struct ieee80211com *ic, struct mbuf *m,
ifp->if_ierrors++;
out:
if (m != NULL) {
if (ic->ic_rawbpf)
if (bpf_peers_present(ic->ic_rawbpf))
bpf_mtap(ic->ic_rawbpf, m);
m_freem(m);
}
@ -731,7 +731,7 @@ ieee80211_deliver_data(struct ieee80211com *ic,
return;
out:
if (m != NULL) {
if (ic->ic_rawbpf)
if (bpf_peers_present(ic->ic_rawbpf))
bpf_mtap(ic->ic_rawbpf, m);
m_freem(m);
}

View File

@ -418,7 +418,7 @@ static void
ng_iface_bpftap(struct ifnet *ifp, struct mbuf *m, sa_family_t family)
{
KASSERT(family != AF_UNSPEC, ("%s: family=AF_UNSPEC", __func__));
if (ifp->if_bpf != NULL) {
if (bpf_peers_present(ifp->if_bpf)) {
int32_t family4 = (int32_t)family;
bpf_mtap2(ifp->if_bpf, &family4, sizeof(family4), m);
}

View File

@ -219,8 +219,7 @@ ng_sppp_start (struct ifnet *ifp)
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
while ((m = sppp_dequeue (ifp)) != NULL) {
if (ifp->if_bpf)
BPF_MTAP (ifp, m);
BPF_MTAP (ifp, m);
len = m->m_pkthdr.len;
NG_SEND_DATA_ONLY (error, priv->hook, m);
@ -382,8 +381,7 @@ ng_sppp_rcvdata (hook_p hook, item_p item)
m->m_pkthdr.rcvif = SP2IFP(pp);
/* Berkeley packet filter */
if (SP2IFP(pp)->if_bpf)
BPF_MTAP (SP2IFP(pp), m);
BPF_MTAP (SP2IFP(pp), m);
/* Send packet */
sppp_input (SP2IFP(pp), m);

View File

@ -658,7 +658,7 @@ carp_input_c(struct mbuf *m, struct carp_header *ch, sa_family_t af)
SC2IFP(sc)->if_ipackets++;
SC2IFP(sc)->if_ibytes += m->m_pkthdr.len;
if (SC2IFP(sc)->if_bpf) {
if (bpf_peers_present(SC2IFP(sc)->if_bpf)) {
struct ip *ip = mtod(m, struct ip *);
uint32_t af1 = af;

View File

@ -206,7 +206,7 @@ gre_input2(struct mbuf *m ,int hlen, u_char proto)
/* Unlike NetBSD, in FreeBSD m_adj() adjusts m->m_pkthdr.len as well */
m_adj(m, hlen);
if (GRE2IFP(sc)->if_bpf) {
if (bpf_peers_present(GRE2IFP(sc)->if_bpf)) {
bpf_mtap2(GRE2IFP(sc)->if_bpf, &af, sizeof(af), m);
}
@ -289,7 +289,7 @@ gre_mobile_input(struct mbuf *m, int hlen)
ip->ip_sum = 0;
ip->ip_sum = in_cksum(m, (ip->ip_hl << 2));
if (GRE2IFP(sc)->if_bpf) {
if (bpf_peers_present(GRE2IFP(sc)->if_bpf)) {
u_int32_t af = AF_INET;
bpf_mtap2(GRE2IFP(sc)->if_bpf, &af, sizeof(af), m);
}