> 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.

> 
>> 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