diff options
author | sam <sam@FreeBSD.org> | 2002-11-14 23:24:13 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2002-11-14 23:24:13 +0000 |
commit | 0d8343cbfe5785460a546de1e7776dffb5f146f4 (patch) | |
tree | 7d2fb45eb235de0f7e542dc0f28df6a6d3201f69 /sys | |
parent | 57696113da17cbfc851dc94e4456bcd4f1baedc0 (diff) | |
download | FreeBSD-src-0d8343cbfe5785460a546de1e7776dffb5f146f4.zip FreeBSD-src-0d8343cbfe5785460a546de1e7776dffb5f146f4.tar.gz |
o add support for multiple link types per interface (e.g. 802.11 and Ethernet)
o introduce BPF_TAP and BPF_MTAP macros to hide implementation details and
ease code portability
o use m_getcl where appropriate
Reviewed by: many
Approved by: re
Obtained from: NetBSD (multiple link type support)
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/bpf.c | 62 | ||||
-rw-r--r-- | sys/net/bpf.h | 17 | ||||
-rw-r--r-- | sys/net/bpfdesc.h | 1 |
3 files changed, 53 insertions, 27 deletions
diff --git a/sys/net/bpf.c b/sys/net/bpf.c index ea0b946..2faf483 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -204,19 +204,17 @@ bpf_movein(uio, linktype, mp, sockp, datlen) if ((unsigned)len > MCLBYTES) return (EIO); - MGETHDR(m, M_TRYWAIT, MT_DATA); - if (m == 0) - return (ENOBUFS); if (len > MHLEN) { - MCLGET(m, M_TRYWAIT); - if ((m->m_flags & M_EXT) == 0) { - error = ENOBUFS; - goto bad; - } + m = m_getcl(M_TRYWAIT, MT_DATA, M_PKTHDR); + } else { + MGETHDR(m, M_TRYWAIT, MT_DATA); } + if (m == NULL) + return (ENOBUFS); m->m_pkthdr.len = m->m_len = len; m->m_pkthdr.rcvif = NULL; *mp = m; + /* * Make room for link header. */ @@ -235,7 +233,7 @@ bpf_movein(uio, linktype, mp, sockp, datlen) error = uiomove(mtod(m, caddr_t), len - hlen, uio); if (!error) return (0); - bad: +bad: m_freem(m); return (error); } @@ -258,7 +256,7 @@ bpf_attachd(d, bp) d->bd_next = bp->bif_dlist; bp->bif_dlist = d; - bp->bif_ifp->if_bpf = bp; + *bp->bif_driverp = bp; BPFIF_UNLOCK(bp); } @@ -304,7 +302,7 @@ bpf_detachd(d) /* * Let the driver know that there are no more listeners. */ - d->bd_bif->bif_ifp->if_bpf = 0; + *d->bd_bif->bif_driverp = 0; BPFIF_UNLOCK(bp); d->bd_bif = 0; } @@ -969,6 +967,9 @@ bpf_setif(d, ifr) if (ifp == 0 || ifp != theywant) continue; + /* skip additional entry */ + if (bp->bif_driverp != (struct bpf_if **)&ifp->if_bpf) + continue; mtx_unlock(&bpf_mtx); /* @@ -1058,16 +1059,14 @@ bpfpoll(dev, events, td) * buffer. */ void -bpf_tap(ifp, pkt, pktlen) - struct ifnet *ifp; +bpf_tap(bp, pkt, pktlen) + struct bpf_if *bp; register u_char *pkt; register u_int pktlen; { - struct bpf_if *bp; register struct bpf_d *d; register u_int slen; - bp = ifp->if_bpf; BPFIF_LOCK(bp); for (d = bp->bif_dlist; d != 0; d = d->bd_next) { BPFD_LOCK(d); @@ -1075,7 +1074,7 @@ bpf_tap(ifp, pkt, pktlen) slen = bpf_filter(d->bd_filter, pkt, pktlen, pktlen); if (slen != 0) { #ifdef MAC - if (mac_check_bpfdesc_receive(d, ifp) == 0) + if (mac_check_bpfdesc_receive(d, bp->bif_ifp) == 0) #endif catchpacket(d, pkt, pktlen, slen, bcopy); } @@ -1115,17 +1114,16 @@ bpf_mcopy(src_arg, dst_arg, len) * Incoming linkage from device drivers, when packet is in an mbuf chain. */ void -bpf_mtap(ifp, m) - struct ifnet *ifp; +bpf_mtap(bp, m) + struct bpf_if *bp; struct mbuf *m; { - struct bpf_if *bp = ifp->if_bpf; struct bpf_d *d; u_int pktlen, slen; pktlen = m_length(m, NULL); if (pktlen == m->m_len) { - bpf_tap(ifp, mtod(m, u_char *), pktlen); + bpf_tap(bp, mtod(m, u_char *), pktlen); return; } @@ -1138,7 +1136,7 @@ bpf_mtap(ifp, m) slen = bpf_filter(d->bd_filter, (u_char *)m, pktlen, 0); if (slen != 0) #ifdef MAC - if (mac_check_bpfdesc_receive(d, ifp) == 0) + if (mac_check_bpfdesc_receive(d, bp->bif_ifp) == 0) #endif catchpacket(d, (u_char *)m, pktlen, slen, bpf_mcopy); @@ -1266,21 +1264,37 @@ bpf_freed(d) } /* + * Attach an interface to bpf. dlt is the link layer type; hdrlen is the + * fixed size of the link header (variable length headers not yet supported). + */ +void +bpfattach(ifp, dlt, hdrlen) + struct ifnet *ifp; + u_int dlt, hdrlen; +{ + + bpfattach2(ifp, dlt, hdrlen, &ifp->if_bpf); +} + +/* * Attach an interface to bpf. ifp is a pointer to the structure * defining the interface to be attached, dlt is the link layer type, * and hdrlen is the fixed size of the link header (variable length * headers are not yet supporrted). */ void -bpfattach(ifp, dlt, hdrlen) +bpfattach2(ifp, dlt, hdrlen, driverp) struct ifnet *ifp; u_int dlt, hdrlen; + struct bpf_if **driverp; { struct bpf_if *bp; bp = (struct bpf_if *)malloc(sizeof(*bp), M_BPF, M_NOWAIT | M_ZERO); if (bp == 0) panic("bpfattach"); + bp->bif_dlist = 0; + bp->bif_driverp = driverp; bp->bif_ifp = ifp; bp->bif_dlt = dlt; mtx_init(&bp->bif_mtx, "bpf interface lock", NULL, MTX_DEF); @@ -1290,7 +1304,7 @@ bpfattach(ifp, dlt, hdrlen) bpf_iflist = bp; mtx_unlock(&bpf_mtx); - bp->bif_ifp->if_bpf = 0; + *bp->bif_driverp = 0; /* * Compute the length of the bpf header. This is not necessarily @@ -1301,7 +1315,7 @@ bpfattach(ifp, dlt, hdrlen) bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen; if (bootverbose) - printf("bpf: %s%d attached\n", ifp->if_name, ifp->if_unit); + if_printf(ifp, "bpf attached\n"); } /* diff --git a/sys/net/bpf.h b/sys/net/bpf.h index 31d8fc2..5e931ce 100644 --- a/sys/net/bpf.h +++ b/sys/net/bpf.h @@ -340,14 +340,25 @@ struct bpf_insn { #define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } #ifdef _KERNEL +struct bpf_if; int bpf_validate(const struct bpf_insn *, int); -void bpf_tap(struct ifnet *, u_char *, u_int); -void bpf_mtap(struct ifnet *, struct mbuf *); +void bpf_tap(struct bpf_if *, u_char *, u_int); +void bpf_mtap(struct bpf_if *, struct mbuf *); void bpfattach(struct ifnet *, u_int, u_int); +void bpfattach2(struct ifnet *, u_int, u_int, struct bpf_if **); void bpfdetach(struct ifnet *); void bpfilterattach(int); u_int bpf_filter(const struct bpf_insn *, u_char *, u_int, u_int); + +#define BPF_TAP(_ifp,_pkt,_pktlen) do { \ + if ((_ifp)->if_bpf) \ + bpf_tap((_ifp)->if_bpf, (_pkt), (_pktlen)); \ +} while (0) +#define BPF_MTAP(_ifp,_m) do { \ + if ((_ifp)->if_bpf) \ + bpf_mtap((_ifp)->if_bpf, (_m)); \ +} while (0) #endif /* @@ -355,4 +366,4 @@ u_int bpf_filter(const struct bpf_insn *, u_char *, u_int, u_int); */ #define BPF_MEMWORDS 16 -#endif +#endif /* _NET_BPF_H_ */ diff --git a/sys/net/bpfdesc.h b/sys/net/bpfdesc.h index 2dd6f43..fe059cd 100644 --- a/sys/net/bpfdesc.h +++ b/sys/net/bpfdesc.h @@ -110,6 +110,7 @@ struct bpf_d { struct bpf_if { struct bpf_if *bif_next; /* list of all interfaces */ struct 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 */ |