On 11/01/18(Thu) 23:10, David Gwynne wrote:
> 
> 
> > On 11 Jan 2018, at 9:11 pm, Martin Pieuchot <m...@openbsd.org> wrote:
> > 
> > On 11/01/18(Thu) 11:58, David Gwynne wrote:
> >> im sending this out more as a backup than a serious diff.
> > 
> > I love this.  It's one of the steps to be able to use bpf(4) for USB.
> 
> oh yeah.
> 
> > 
> > Is there an easy way to also remove the mbuf requirement?  For example
> > I'd like to call bpf_mtap() or similar in usb_transfer_complete().
> 
> is the usb payload in one or two contig buffers? we could just fake it.

Yes, it's  KERNADDR(&xfer->dmabuf, 0) of size `xfer->actlen'.

> >> this tweaks bpf so it can be used by subsystems, not just interfaces.
> >> this is done by making bpf store and use names (eg, "pf" and "em0")
> >> instead of just interfaces. interfaces get some special handling
> >> so you can't bpfwrite or enable ifpromisc unless bif_ifp is set.
> >> 
> >> an example use of this is attaching bpf to pf. you can see all the
> >> packets handed to pf_test with this diff and tcpdump -ni pf.
> >> 
> >> Index: bpf.c
> >> ===================================================================
> >> RCS file: /cvs/src/sys/net/bpf.c,v
> >> retrieving revision 1.165
> >> diff -u -p -r1.165 bpf.c
> >> --- bpf.c  30 Dec 2017 23:08:29 -0000      1.165
> >> +++ bpf.c  10 Jan 2018 07:27:45 -0000
> >> @@ -93,7 +93,7 @@ struct bpf_if    *bpf_iflist;
> >> LIST_HEAD(, bpf_d) bpf_d_list;
> >> 
> >> int        bpf_allocbufs(struct bpf_d *);
> >> -void      bpf_ifname(struct ifnet *, struct ifreq *);
> >> +void      bpf_ifname(struct bpf_if*, struct ifreq *);
> >> int        _bpf_mtap(caddr_t, const struct mbuf *, u_int,
> >>        void (*)(const void *, void *, size_t));
> >> void       bpf_mcopy(const void *, void *, size_t);
> >> @@ -320,6 +320,8 @@ bpf_detachd(struct bpf_d *d)
> >>    if (d->bd_promisc) {
> >>            int error;
> >> 
> >> +          KASSERT(bp->bif_ifp != NULL);
> >> +
> >>            d->bd_promisc = 0;
> >> 
> >>            bpf_get(d);
> >> @@ -593,7 +595,7 @@ bpfwrite(dev_t dev, struct uio *uio, int
> >>    bpf_get(d);
> >>    ifp = d->bd_bif->bif_ifp;
> >> 
> >> -  if ((ifp->if_flags & IFF_UP) == 0) {
> >> +  if (ifp == NULL || (ifp->if_flags & IFF_UP) == 0) {
> >>            error = ENETDOWN;
> >>            goto out;
> >>    }
> >> @@ -789,7 +791,7 @@ bpfioctl(dev_t dev, u_long cmd, caddr_t 
> >>                     * No interface attached yet.
> >>                     */
> >>                    error = EINVAL;
> >> -          } else {
> >> +          } else if (d->bd_bif->bif_ifp != NULL) { 
> >>                    if (d->bd_promisc == 0) {
> >>                            MUTEX_ASSERT_UNLOCKED(&d->bd_mtx);
> >>                            error = ifpromisc(d->bd_bif->bif_ifp, 1);
> >> @@ -839,7 +841,7 @@ bpfioctl(dev_t dev, u_long cmd, caddr_t 
> >>            if (d->bd_bif == NULL)
> >>                    error = EINVAL;
> >>            else
> >> -                  bpf_ifname(d->bd_bif->bif_ifp, (struct ifreq *)addr);
> >> +                  bpf_ifname(d->bd_bif, (struct ifreq *)addr);
> >>            break;
> >> 
> >>    /*
> >> @@ -1049,10 +1051,7 @@ bpf_setif(struct bpf_d *d, struct ifreq 
> >>     * Look through attached interfaces for the named one.
> >>     */
> >>    for (bp = bpf_iflist; bp != NULL; bp = bp->bif_next) {
> >> -          struct ifnet *ifp = bp->bif_ifp;
> >> -
> >> -          if (ifp == NULL ||
> >> -              strcmp(ifp->if_xname, ifr->ifr_name) != 0)
> >> +          if (strcmp(bp->bif_name, ifr->ifr_name) != 0)
> >>                    continue;
> >> 
> >>            if (candidate == NULL || candidate->bif_dlt > bp->bif_dlt)
> >> @@ -1090,9 +1089,9 @@ out:
> >>  * Copy the interface name to the ifreq.
> >>  */
> >> void
> >> -bpf_ifname(struct ifnet *ifp, struct ifreq *ifr)
> >> +bpf_ifname(struct bpf_if *bif, struct ifreq *ifr)
> >> {
> >> -  bcopy(ifp->if_xname, ifr->ifr_name, IFNAMSIZ);
> >> +  bcopy(bif->bif_name, ifr->ifr_name, sizeof(ifr->ifr_name));
> >> }
> >> 
> >> /*
> >> @@ -1538,21 +1537,17 @@ bpf_put(struct bpf_d *bd)
> >>    free(bd, M_DEVBUF, sizeof(*bd));
> >> }
> >> 
> >> -/*
> >> - * Attach an interface to bpf.  driverp is a pointer to a (struct bpf_if 
> >> *)
> >> - * in the driver's softc; dlt is the link layer type; hdrlen is the fixed
> >> - * size of the link header (variable length headers not yet supported).
> >> - */
> >> -void
> >> -bpfattach(caddr_t *driverp, struct ifnet *ifp, u_int dlt, u_int hdrlen)
> >> +void *
> >> +bpfsattach(caddr_t *bpfp, const char *name, u_int dlt, u_int hdrlen)
> >> {
> >>    struct bpf_if *bp;
> >> 
> >>    if ((bp = malloc(sizeof(*bp), M_DEVBUF, M_NOWAIT)) == NULL)
> >>            panic("bpfattach");
> >>    SRPL_INIT(&bp->bif_dlist);
> >> -  bp->bif_driverp = (struct bpf_if **)driverp;
> >> -  bp->bif_ifp = ifp;
> >> +  bp->bif_driverp = (struct bpf_if **)bpfp;
> >> +  bp->bif_name = name;
> >> +  bp->bif_ifp = NULL;
> >>    bp->bif_dlt = dlt;
> >> 
> >>    bp->bif_next = bpf_iflist;
> >> @@ -1567,6 +1562,17 @@ bpfattach(caddr_t *driverp, struct ifnet
> >>     * performance reasons and to alleviate alignment restrictions).
> >>     */
> >>    bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen;
> >> +
> >> +  return (bp);
> >> +}
> >> +
> >> +void
> >> +bpfattach(caddr_t *driverp, struct ifnet *ifp, u_int dlt, u_int hdrlen)
> >> +{
> >> +  struct bpf_if *bp;
> >> +
> >> +  bp = bpfsattach(driverp, ifp->if_xname, dlt, hdrlen);
> >> +  bp->bif_ifp = ifp;
> >> }
> >> 
> >> /* Detach an interface from its attached bpf device.  */
> >> @@ -1574,31 +1580,39 @@ void
> >> bpfdetach(struct ifnet *ifp)
> >> {
> >>    struct bpf_if *bp, *nbp, **pbp = &bpf_iflist;
> >> -  struct bpf_d *bd;
> >> -  int maj;
> >> 
> >>    KERNEL_ASSERT_LOCKED();
> >> 
> >>    for (bp = bpf_iflist; bp; bp = nbp) {
> >> -          nbp= bp->bif_next;
> >> +          nbp = bp->bif_next;
> >>            if (bp->bif_ifp == ifp) {
> >>                    *pbp = nbp;
> >> 
> >> -                  /* Locate the major number. */
> >> -                  for (maj = 0; maj < nchrdev; maj++)
> >> -                          if (cdevsw[maj].d_open == bpfopen)
> >> -                                  break;
> >> -
> >> -                  while ((bd = SRPL_FIRST_LOCKED(&bp->bif_dlist)))
> >> -                          vdevgone(maj, bd->bd_unit, bd->bd_unit, VCHR);
> >> -
> >> -                  free(bp, M_DEVBUF, sizeof *bp);
> >> +                  bpfsdetach(bp);
> >>            } else
> >>                    pbp = &bp->bif_next;
> >>    }
> >>    ifp->if_bpf = NULL;
> >> }
> >> 
> >> +void
> >> +bpfsdetach(void *p)
> >> +{
> >> +  struct bpf_if *bp = p;
> >> +  struct bpf_d *bd;
> >> +  int maj;
> >> +
> >> +  /* Locate the major number. */
> >> +  for (maj = 0; maj < nchrdev; maj++)
> >> +          if (cdevsw[maj].d_open == bpfopen)
> >> +                  break;
> >> +
> >> +  while ((bd = SRPL_FIRST_LOCKED(&bp->bif_dlist)))
> >> +          vdevgone(maj, bd->bd_unit, bd->bd_unit, VCHR);
> >> +
> >> +  free(bp, M_DEVBUF, sizeof *bp);
> >> +}
> >> +
> >> int
> >> bpf_sysctl_locked(int *name, u_int namelen, void *oldp, size_t *oldlenp,
> >>     void *newp, size_t newlen)
> >> @@ -1674,14 +1688,14 @@ int
> >> bpf_getdltlist(struct bpf_d *d, struct bpf_dltlist *bfl)
> >> {
> >>    int n, error;
> >> -  struct ifnet *ifp;
> >>    struct bpf_if *bp;
> >> +  const char *name;
> >> 
> >> -  ifp = d->bd_bif->bif_ifp;
> >> +  name = d->bd_bif->bif_name;
> >>    n = 0;
> >>    error = 0;
> >>    for (bp = bpf_iflist; bp != NULL; bp = bp->bif_next) {
> >> -          if (bp->bif_ifp != ifp)
> >> +          if (strcmp(name, bp->bif_name) != 0)
> >>                    continue;
> >>            if (bfl->bfl_list != NULL) {
> >>                    if (n >= bfl->bfl_len)
> >> @@ -1704,15 +1718,17 @@ bpf_getdltlist(struct bpf_d *d, struct b
> >> int
> >> bpf_setdlt(struct bpf_d *d, u_int dlt)
> >> {
> >> -  struct ifnet *ifp;
> >> +  const char *name;
> >>    struct bpf_if *bp;
> >> 
> >>    MUTEX_ASSERT_LOCKED(&d->bd_mtx);
> >>    if (d->bd_bif->bif_dlt == dlt)
> >>            return (0);
> >> -  ifp = d->bd_bif->bif_ifp;
> >> +  name = d->bd_bif->bif_name;
> >>    for (bp = bpf_iflist; bp != NULL; bp = bp->bif_next) {
> >> -          if (bp->bif_ifp == ifp && bp->bif_dlt == dlt)
> >> +          if (strcmp(name, bp->bif_name) != 0)
> >> +                  continue;
> >> +          if (bp->bif_dlt == dlt)
> >>                    break;
> >>    }
> >>    if (bp == NULL)
> >> Index: bpf.h
> >> ===================================================================
> >> RCS file: /cvs/src/sys/net/bpf.h,v
> >> retrieving revision 1.62
> >> diff -u -p -r1.62 bpf.h
> >> --- bpf.h  22 Feb 2017 09:56:03 -0000      1.62
> >> +++ bpf.h  10 Jan 2018 07:27:45 -0000
> >> @@ -313,6 +313,8 @@ int     bpf_mtap_af(caddr_t, u_int32_t, con
> >> int         bpf_mtap_ether(caddr_t, const struct mbuf *, u_int);
> >> void        bpfattach(caddr_t *, struct ifnet *, u_int, u_int);
> >> void        bpfdetach(struct ifnet *);
> >> +void      *bpfsattach(caddr_t *, const char *, u_int, u_int);
> >> +void       bpfsdetach(void *);
> >> void        bpfilterattach(int);
> >> 
> >> u_int       bpf_mfilter(const struct bpf_insn *, const struct mbuf *, 
> >> u_int);
> >> Index: bpfdesc.h
> >> ===================================================================
> >> RCS file: /cvs/src/sys/net/bpfdesc.h,v
> >> retrieving revision 1.35
> >> diff -u -p -r1.35 bpfdesc.h
> >> --- bpfdesc.h      24 Jan 2017 10:08:30 -0000      1.35
> >> +++ bpfdesc.h      10 Jan 2018 07:27:45 -0000
> >> @@ -103,6 +103,7 @@ struct bpf_if {
> >>    struct bpf_if **bif_driverp;    /* pointer into softc */
> >>    u_int bif_dlt;                  /* link layer type */
> >>    u_int bif_hdrlen;               /* length of header (with padding) */
> >> +  const char *bif_name;           /* name of "subsystem" */
> >>    struct ifnet *bif_ifp;          /* corresponding interface */
> >> };
> >> 
> >> Index: pf.c
> >> ===================================================================
> >> RCS file: /cvs/src/sys/net/pf.c,v
> >> retrieving revision 1.1054
> >> diff -u -p -r1.1054 pf.c
> >> --- pf.c   29 Dec 2017 23:55:22 -0000      1.1054
> >> +++ pf.c   10 Jan 2018 07:27:45 -0000
> >> @@ -104,6 +104,11 @@
> >> #include <ddb/db_interface.h>
> >> #endif
> >> 
> >> +#if NBPFILTER > 0
> >> +#include <net/bpf.h>
> >> +caddr_t pf_bpf;
> >> +#endif
> >> +
> >> /*
> >>  * Global variables
> >>  */
> >> @@ -6719,6 +6724,11 @@ pf_test(sa_family_t af, int fwdir, struc
> >> 
> >>    if (!pf_status.running)
> >>            return (PF_PASS);
> >> +
> >> +#if NBPFILTER > 0
> >> +  if (pf_bpf)
> >> +          bpf_mtap_af(pf_bpf, af, *m0, BPF_DIRECTION_IN);
> >> +#endif
> >> 
> >> #if NCARP > 0
> >>    if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
> >> Index: pf_ioctl.c
> >> ===================================================================
> >> RCS file: /cvs/src/sys/net/pf_ioctl.c,v
> >> retrieving revision 1.326
> >> diff -u -p -r1.326 pf_ioctl.c
> >> --- pf_ioctl.c     28 Nov 2017 16:05:46 -0000      1.326
> >> +++ pf_ioctl.c     10 Jan 2018 07:27:45 -0000
> >> @@ -35,6 +35,7 @@
> >>  *
> >>  */
> >> 
> >> +#include "bpfilter.h"
> >> #include "pfsync.h"
> >> #include "pflog.h"
> >> 
> >> @@ -84,6 +85,11 @@
> >> #include <net/if_pfsync.h>
> >> #endif /* NPFSYNC > 0 */
> >> 
> >> +#if NBPFILTER > 0
> >> +#include <net/bpf.h>
> >> +extern caddr_t pf_bpf;
> >> +#endif
> >> +
> >> struct pool                 pf_tag_pl;
> >> 
> >> void                        pfattach(int);
> >> @@ -231,6 +237,10 @@ pfattach(int num)
> >> 
> >>    /* XXX do our best to avoid a conflict */
> >>    pf_status.hostid = arc4random();
> >> +
> >> +#if NBPFILTER > 0
> >> +  bpfsattach(&pf_bpf, "pf", DLT_LOOP, sizeof(u_int32_t));
> >> +#endif
> >> }
> >> 
> >> int
> >> 
> 

Reply via email to