svn commit: r228986 - in head: share/man/man4 sys/net

Adrian Chadd adrian at freebsd.org
Sat Dec 31 00:13:08 UTC 2011


This just broke wlan. Please consider fixing this patch :)


Adrian

*** Interface: wlan0: start
can't re-use a leaf (wlan0)!
panic: bpfattach tscfgoid
KDB: enter: panic
[ thread pid 166 tid 100048 ]Stopped at      kdb_enter+0x4c: lui     at,0x8048
db>
db> bt
Tracing pid 166 tid 100048 td 0x80c37900
db_trace_thread+30 (?,?,?,?) ra 80074cc0 sp c40075f0 sz 24
80074bac+114 (0,?,ffffffff,?) ra 8007427c sp c4007608 sz 32
80073ef4+388 (?,?,?,?) ra 80074400 sp c4007628 sz 168
db_command_loop+70 (?,?,?,?) ra 80076ac4 sp c40076d0 sz 24
800769d0+f4 (?,?,?,?) ra 801b7560 sp c40076e8 sz 424
kdb_trap+110 (?,?,?,?) ra 8035c7ec sp c4007890 sz 48
trap+bf4 (?,?,?,?) ra 80354560 sp c40078c0 sz 184
MipsKernGenException+134 (0,4,803c089c,113) ra 801b72d8 sp c4007978 sz 200
kdb_enter+4c (?,?,?,?) ra 8017f88c sp c4007a40 sz 24
panic+11c (?,0,80706500,0) ra 802304b8 sp c4007a58 sz 40
bpfattach2+cc (?,?,?,?) ra 802305e0 sp c4007a80 sz 64
bpfattach+10 (?,?,?,?) ra 802448ec sp c4007ac0 sz 24
ether_ifattach+d0 (?,?,?,?) ra 8025f0ac sp c4007ad8 sz 32
ieee80211_vap_attach+104 (?,?,?,?) ra 8007ffe8 sp c4007af8 sz 96
8007f960+688 (?,?,0,?) ra 8026a39c sp c4007b58 sz 88
8026a22c+170 (?,?,?,?) ra 802430dc sp c4007bb0 sz 88
ifc_simple_create+80 (?,?,?,?) ra 80242b04 sp c4007c08 sz 64
80242ab0+54 (?,?,?,?) ra 80242d78 sp c4007c48 sz 40
if_clone_create+a8 (?,?,?,?) ra 8023bdd4 sp c4007c70 sz 40
ifioctl+3a4 (?,?,80c7f460,80c37900) ra 801d8070 sp c4007c98 sz 144
soo_ioctl+3b0 (?,?,?,?) ra 801d2804 sp c4007d28 sz 40
kern_ioctl+248 (?,?,?,?) ra 801d29ac sp c4007d50 sz 64
sys_ioctl+130 (?,?,?,?) ra 8035c3ec sp c4007d90 sz 56
trap+7f4 (?,?,?,?) ra 8035475c sp c4007dc8 sz 184
MipsUserGenException+10c (?,?,?,4061d590) ra 0 sp c4007e80 sz 0
pid 166
db> reset


On 30 December 2011 00:57, Lawrence Stewart <lstewart at freebsd.org> wrote:
> Author: lstewart
> Date: Fri Dec 30 08:57:58 2011
> New Revision: 228986
> URL: http://svn.freebsd.org/changeset/base/228986
>
> Log:
>  - Introduce the net.bpf.tscfg sysctl tree and associated code so as to make one
>    aspect of time stamp configuration per interface rather than per BPF
>    descriptor. Prior to this, the order in which BPF devices were opened and the
>    per descriptor time stamp configuration settings could cause non-deterministic
>    and unintended behaviour with respect to time stamping. With the new scheme, a
>    BPF attached interface's tscfg sysctl entry can be set to "default", "none",
>    "fast", "normal" or "external". Setting "default" means use the system default
>    option (set with the net.bpf.tscfg.default sysctl), "none" means do not
>    generate time stamps for tapped packets, "fast" means generate time stamps for
>    tapped packets using a hz granularity system clock read, "normal" means
>    generate time stamps for tapped packets using a full timecounter granularity
>    system clock read and "external" (currently unimplemented) means use the time
>    stamp provided with the packet from an underlying source.
>
>  - Utilise the recently introduced sysclock_getsnapshot() and
>    sysclock_snap2bintime() KPIs to ensure the system clock is only read once per
>    packet, regardless of the number of BPF descriptors and time stamp formats
>    requested. Use the per BPF attached interface time stamp configuration to
>    control if sysclock_getsnapshot() is called and whether the system clock read
>    is fast or normal. The per BPF descriptor time stamp configuration is then
>    used to control how the system clock snapshot is converted to a bintime by
>    sysclock_snap2bintime().
>
>  - Remove all FAST related BPF descriptor flag variants. Performing a "fast"
>    read of the system clock is now controlled per BPF attached interface using
>    the net.bpf.tscfg sysctl tree.
>
>  - Update the bpf.4 man page.
>
>  Committed on behalf of Julien Ridoux and Darryl Veitch from the University of
>  Melbourne, Australia, as part of the FreeBSD Foundation funded "Feed-Forward
>  Clock Synchronization Algorithms" project.
>
>  For more information, see http://www.synclab.org/radclock/
>
>  In collaboration with:        Julien Ridoux (jridoux at unimelb edu au)
>
> Modified:
>  head/share/man/man4/bpf.4
>  head/sys/net/bpf.c
>  head/sys/net/bpf.h
>
> Modified: head/share/man/man4/bpf.4
> ==============================================================================
> --- head/share/man/man4/bpf.4   Fri Dec 30 06:24:59 2011        (r228985)
> +++ head/share/man/man4/bpf.4   Fri Dec 30 08:57:58 2011        (r228986)
> @@ -49,7 +49,7 @@
>  .\"
>  .\" $FreeBSD$
>  .\"
> -.Dd June 15, 2010
> +.Dd December 30, 2011
>  .Dt BPF 4
>  .Os
>  .Sh NAME
> @@ -516,61 +516,48 @@ by default.
>  .It Dv BIOCSTSTAMP
>  .It Dv BIOCGTSTAMP
>  .Pq Li u_int
> -Set or get format and resolution of the time stamps returned by BPF.
> +Set or get the format and resolution of time stamps returned by BPF.
> +The per-BPF descriptor configuration provided by the
> +.Dv BIOCSTSTAMP
> +IOCTL complements the per-interface time stamp configuration detailed in the
> +.Sx CONFIGURATION
> +section.
> +.Pp
>  Set to
> -.Dv BPF_T_MICROTIME ,
> -.Dv BPF_T_MICROTIME_FAST ,
> -.Dv BPF_T_MICROTIME_MONOTONIC ,
> +.Dv BPF_T_MICROTIME
>  or
> -.Dv BPF_T_MICROTIME_MONOTONIC_FAST
> +.Dv BPF_T_MICROTIME_MONOTONIC
>  to get time stamps in 64-bit
>  .Vt struct timeval
>  format.
>  Set to
> -.Dv BPF_T_NANOTIME ,
> -.Dv BPF_T_NANOTIME_FAST ,
> -.Dv BPF_T_NANOTIME_MONOTONIC ,
> +.Dv BPF_T_NANOTIME
>  or
> -.Dv BPF_T_NANOTIME_MONOTONIC_FAST
> +.Dv BPF_T_NANOTIME_MONOTONIC
>  to get time stamps in 64-bit
>  .Vt struct timespec
>  format.
>  Set to
> -.Dv BPF_T_BINTIME ,
> -.Dv BPF_T_BINTIME_FAST ,
> -.Dv BPF_T_NANOTIME_MONOTONIC ,
> +.Dv BPF_T_BINTIME
>  or
> -.Dv BPF_T_BINTIME_MONOTONIC_FAST
> +.Dv BPF_T_BINTIME_MONOTONIC
>  to get time stamps in 64-bit
>  .Vt struct bintime
>  format.
>  Set to
>  .Dv BPF_T_NONE
> -to ignore time stamp.
> +to not set a time stamp.
> +By default, time stamps are initilized to
> +.Dv BPF_T_MICROTIME .
> +.Pp
>  All 64-bit time stamp formats are wrapped in
>  .Vt struct bpf_ts .
>  The
> -.Dv BPF_T_MICROTIME_FAST ,
> -.Dv BPF_T_NANOTIME_FAST ,
> -.Dv BPF_T_BINTIME_FAST ,
> -.Dv BPF_T_MICROTIME_MONOTONIC_FAST ,
> -.Dv BPF_T_NANOTIME_MONOTONIC_FAST ,
> -and
> -.Dv BPF_T_BINTIME_MONOTONIC_FAST
> -are analogs of corresponding formats without _FAST suffix but do not perform
> -a full time counter query, so their accuracy is one timer tick.
> -The
>  .Dv BPF_T_MICROTIME_MONOTONIC ,
>  .Dv BPF_T_NANOTIME_MONOTONIC ,
> -.Dv BPF_T_BINTIME_MONOTONIC ,
> -.Dv BPF_T_MICROTIME_MONOTONIC_FAST ,
> -.Dv BPF_T_NANOTIME_MONOTONIC_FAST ,
>  and
> -.Dv BPF_T_BINTIME_MONOTONIC_FAST
> +.Dv BPF_T_BINTIME_MONOTONIC
>  store the time elapsed since kernel boot.
> -This setting is initialized to
> -.Dv BPF_T_MICROTIME
> -by default.
>  .It Dv BIOCFEEDBACK
>  .Pq Li u_int
>  Set packet feedback mode.
> @@ -692,14 +679,14 @@ Currently,
>  .Vt bpf_hdr
>  is used when the time stamp is set to
>  .Dv BPF_T_MICROTIME ,
> -.Dv BPF_T_MICROTIME_FAST ,
>  .Dv BPF_T_MICROTIME_MONOTONIC ,
> -.Dv BPF_T_MICROTIME_MONOTONIC_FAST ,
>  or
>  .Dv BPF_T_NONE
> -for backward compatibility reasons.  Otherwise,
> +for backward compatibility reasons.
> +Otherwise,
>  .Vt bpf_xhdr
> -is used.  However,
> +is used.
> +However,
>  .Vt bpf_hdr
>  may be deprecated in the near future.
>  Suitable precautions
> @@ -952,6 +939,48 @@ array initializers:
>  .Fn BPF_STMT opcode operand
>  and
>  .Fn BPF_JUMP opcode operand true_offset false_offset .
> +.Sh CONFIGURATION
> +Per-interface BPF time stamp configuration is possible via the
> +.Va net.bpf.tscfg
> +.Xr sysctl 8
> +tree which provides the following variables:
> +.Bl -tag -width "    " -offset indent
> +.It Va net.bpf.tscfg.default
> +The default time stamp configuration setting used by all BPF attached interfaces
> +which have not been explicitly changed.
> +Valid values are "none", "fast", "normal" and "external".
> +The default is "normal".
> +.It Va net.bpf.tscfg.<interface>
> +The time stamp configuration setting used by a specific BPF attached interface.
> +There will be a separate entry in the
> +.Va net.bpf.tscfg
> +sysctl tree for each BPF attached interface.
> +Valid values are "default", "none", "fast", "normal" and "external".
> +The default is "default", which means the system wide default setting specified
> +by the
> +.Va net.bpf.tscfg.default
> +sysctl is used.
> +.El
> +.Pp
> +The meaning of each per-interface time stamp configuration option is as follows:
> +.Bl -tag -width "    " -offset indent
> +.It none
> +Do not generate a time stamp for all packets tapped from this interface.
> +.It fast
> +Generate a time stamp for all packets tapped from this interface by doing a fast
> +read of the system clock.
> +Fast reads have a granularity equivalent to the underlying kernel tick rate.
> +.It normal
> +Generate a time stamp for all packets tapped from this interface by doing a full
> +read of the system clock.
> +Full reads are slower than fast reads, but provide full hardware time counter
> +granularity for the time stamp.
> +.It external
> +Something external to BPF is capable of generating time stamps for all packets
> +tapped from this interface and BPF should use these external time stamps.
> +Currently unimplemented, but will become useful when drivers for NICs which
> +support hardware packet time stamping add support for this feature.
> +.El
>  .Sh FILES
>  .Bl -tag -compact -width /dev/bpf
>  .It Pa /dev/bpf
>
> Modified: head/sys/net/bpf.c
> ==============================================================================
> --- head/sys/net/bpf.c  Fri Dec 30 06:24:59 2011        (r228985)
> +++ head/sys/net/bpf.c  Fri Dec 30 08:57:58 2011        (r228986)
> @@ -1,12 +1,17 @@
>  /*-
>  * Copyright (c) 1990, 1991, 1993
> - *     The Regents of the University of California.  All rights reserved.
> + *     The Regents of the University of California.
> + * Copyright (c) 2011 The University of Melbourne.
> + * All rights reserved.
>  *
>  * This code is derived from the Stanford/CMU enet packet filter,
>  * (net/enet.c) distributed as part of 4.3BSD, and code contributed
>  * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
>  * Berkeley Laboratory.
>  *
> + * Portions of this software were developed by Julien Ridoux at the University
> + * of Melbourne under sponsorship from the FreeBSD Foundation.
> + *
>  * Redistribution and use in source and binary forms, with or without
>  * modification, are permitted provided that the following conditions
>  * are met:
> @@ -55,6 +60,7 @@ __FBSDID("$FreeBSD$");
>  #include <sys/signalvar.h>
>  #include <sys/filio.h>
>  #include <sys/sockio.h>
> +#include <sys/timeffc.h>
>  #include <sys/ttycom.h>
>  #include <sys/uio.h>
>
> @@ -112,7 +118,7 @@ struct bpf_hdr32 {
>        uint16_t        bh_hdrlen;      /* length of bpf header (this struct
>                                           plus alignment padding) */
>  };
> -#endif
> +#endif /* !BURN_BRIDGES */
>
>  struct bpf_program32 {
>        u_int bf_len;
> @@ -130,7 +136,28 @@ struct bpf_dltlist32 {
>  #define        BIOCGDLTLIST32  _IOWR('B', 121, struct bpf_dltlist32)
>  #define        BIOCSETWF32     _IOW('B', 123, struct bpf_program32)
>  #define        BIOCSETFNR32    _IOW('B', 130, struct bpf_program32)
> -#endif
> +#endif /* COMPAT_FREEBSD32 */
> +
> +static const char *bpfiftstypes[] = {
> +       "default",
> +#define        BPF_TSTAMP_DEFAULT      0
> +       "none",
> +#define        BPF_TSTAMP_NONE         1
> +       "fast",
> +#define        BPF_TSTAMP_FAST         2
> +       "normal",
> +#define        BPF_TSTAMP_NORMAL       3
> +       "external"
> +#define        BPF_TSTAMP_EXTERNAL     4
> +};
> +#define        NUM_BPFIFTSTYPES        (sizeof(bpfiftstypes) / sizeof(*bpfiftstypes))
> +
> +#define        SET_CLOCKCFG_FLAGS(tstype, active, clock, flags) do {           \
> +       (flags) = 0;                                                    \
> +       (clock) = SYSCLOCK_FBCK;                                        \
> +       if ((tstype) & BPF_T_MONOTONIC)                                 \
> +               (flags) |= FBCLOCK_UPTIME;                              \
> +} while (0)
>
>  /*
>  * bpf_iflist is a list of BPF interface structures, each corresponding to a
> @@ -162,6 +189,7 @@ static void filt_bpfdetach(struct knote
>  static int     filt_bpfread(struct knote *, long);
>  static void    bpf_drvinit(void *);
>  static int     bpf_stats_sysctl(SYSCTL_HANDLER_ARGS);
> +static int     bpf_tscfg_sysctl_handler(SYSCTL_HANDLER_ARGS);
>
>  SYSCTL_NODE(_net, OID_AUTO, bpf, CTLFLAG_RW, 0, "bpf sysctl");
>  int bpf_maxinsns = BPF_MAXINSNS;
> @@ -172,6 +200,12 @@ SYSCTL_INT(_net_bpf, OID_AUTO, zerocopy_
>     &bpf_zerocopy_enable, 0, "Enable new zero-copy BPF buffer sessions");
>  static SYSCTL_NODE(_net_bpf, OID_AUTO, stats, CTLFLAG_MPSAFE | CTLFLAG_RW,
>     bpf_stats_sysctl, "bpf statistics portal");
> +static SYSCTL_NODE(_net_bpf, OID_AUTO, tscfg, CTLFLAG_RW, NULL,
> +    "Per-interface timestamp configuration");
> +static int bpf_default_tstype = BPF_TSTAMP_NORMAL;
> +SYSCTL_PROC(_net_bpf_tscfg, OID_AUTO, default,
> +    CTLTYPE_STRING | CTLFLAG_RW, NULL, 0, bpf_tscfg_sysctl_handler, "A",
> +    "Per-interface system wide default timestamp configuration");
>
>  static d_open_t        bpfopen;
>  static d_read_t        bpfread;
> @@ -1759,48 +1793,6 @@ filt_bpfread(struct knote *kn, long hint
>        return (ready);
>  }
>
> -#define        BPF_TSTAMP_NONE         0
> -#define        BPF_TSTAMP_FAST         1
> -#define        BPF_TSTAMP_NORMAL       2
> -#define        BPF_TSTAMP_EXTERN       3
> -
> -static int
> -bpf_ts_quality(int tstype)
> -{
> -
> -       if (tstype == BPF_T_NONE)
> -               return (BPF_TSTAMP_NONE);
> -       if ((tstype & BPF_T_FAST) != 0)
> -               return (BPF_TSTAMP_FAST);
> -
> -       return (BPF_TSTAMP_NORMAL);
> -}
> -
> -static int
> -bpf_gettime(struct bintime *bt, int tstype, struct mbuf *m)
> -{
> -       struct m_tag *tag;
> -       int quality;
> -
> -       quality = bpf_ts_quality(tstype);
> -       if (quality == BPF_TSTAMP_NONE)
> -               return (quality);
> -
> -       if (m != NULL) {
> -               tag = m_tag_locate(m, MTAG_BPF, MTAG_BPF_TIMESTAMP, NULL);
> -               if (tag != NULL) {
> -                       *bt = *(struct bintime *)(tag + 1);
> -                       return (BPF_TSTAMP_EXTERN);
> -               }
> -       }
> -       if (quality == BPF_TSTAMP_NORMAL)
> -               binuptime(bt);
> -       else
> -               getbinuptime(bt);
> -
> -       return (quality);
> -}
> -
>  /*
>  * Incoming linkage from device drivers.  Process the packet pkt, of length
>  * pktlen, which is stored in a contiguous buffer.  The packet is parsed
> @@ -1811,14 +1803,23 @@ void
>  bpf_tap(struct bpf_if *bp, u_char *pkt, u_int pktlen)
>  {
>        struct bintime bt;
> +       struct sysclock_snap cs;
>        struct bpf_d *d;
> +       int tstype, whichclock;
> +       u_int clockflags, slen;
>  #ifdef BPF_JITTER
>        bpf_jit_filter *bf;
>  #endif
> -       u_int slen;
> -       int gottime;
>
> -       gottime = BPF_TSTAMP_NONE;
> +       tstype = bp->tstype;
> +       if (tstype == BPF_TSTAMP_DEFAULT)
> +               tstype = bpf_default_tstype;
> +
> +       if (tstype == BPF_TSTAMP_NORMAL || tstype == BPF_TSTAMP_FAST)
> +               sysclock_getsnapshot(&cs, tstype == BPF_TSTAMP_FAST ? 1 : 0);
> +       else
> +               bzero(&bt, sizeof(bt));
> +
>        BPFIF_LOCK(bp);
>        LIST_FOREACH(d, &bp->bif_dlist, bd_next) {
>                BPFD_LOCK(d);
> @@ -1838,8 +1839,16 @@ bpf_tap(struct bpf_if *bp, u_char *pkt,
>                slen = bpf_filter(d->bd_rfilter, pkt, pktlen, pktlen);
>                if (slen != 0) {
>                        d->bd_fcount++;
> -                       if (gottime < bpf_ts_quality(d->bd_tstamp))
> -                               gottime = bpf_gettime(&bt, d->bd_tstamp, NULL);
> +                       if (tstype == BPF_TSTAMP_NORMAL ||
> +                           tstype == BPF_TSTAMP_FAST) {
> +                               whichclock = -1;
> +                               SET_CLOCKCFG_FLAGS(d->bd_tstamp,
> +                                   cs.sysclock_active, whichclock, clockflags);
> +                               KASSERT(whichclock >= 0, ("Bogus BPF tstamp "
> +                                   "configuration: 0x%04x", d->bd_tstamp));
> +                               sysclock_snap2bintime(&cs, &bt, whichclock,
> +                                   clockflags);
> +                       }
>  #ifdef MAC
>                        if (mac_bpfdesc_check_receive(d, bp->bif_ifp) == 0)
>  #endif
> @@ -1862,12 +1871,13 @@ void
>  bpf_mtap(struct bpf_if *bp, struct mbuf *m)
>  {
>        struct bintime bt;
> +       struct sysclock_snap cs;
>        struct bpf_d *d;
> +       u_int clockflags, pktlen, slen;
> +       int tstype, whichclock;
>  #ifdef BPF_JITTER
>        bpf_jit_filter *bf;
>  #endif
> -       u_int pktlen, slen;
> -       int gottime;
>
>        /* Skip outgoing duplicate packets. */
>        if ((m->m_flags & M_PROMISC) != 0 && m->m_pkthdr.rcvif == NULL) {
> @@ -1875,9 +1885,22 @@ bpf_mtap(struct bpf_if *bp, struct mbuf
>                return;
>        }
>
> +       tstype = bp->tstype;
> +       if (tstype == BPF_TSTAMP_DEFAULT)
> +               tstype = bpf_default_tstype;
> +
> +       if (tstype == BPF_TSTAMP_NORMAL || tstype == BPF_TSTAMP_FAST)
> +               sysclock_getsnapshot(&cs, tstype == BPF_TSTAMP_FAST ?
> +                   1 : 0);
> +#ifdef notyet
> +       else if (tstype == BPF_TSTAMP_EXTERNAL)
> +               /* XXX: Convert external tstamp to bintime. */
> +#endif
> +       else
> +               bzero(&bt, sizeof(bt));
> +
>        pktlen = m_length(m, NULL);
>
> -       gottime = BPF_TSTAMP_NONE;
>        BPFIF_LOCK(bp);
>        LIST_FOREACH(d, &bp->bif_dlist, bd_next) {
>                if (BPF_CHECK_DIRECTION(d, m->m_pkthdr.rcvif, bp->bif_ifp))
> @@ -1894,8 +1917,16 @@ bpf_mtap(struct bpf_if *bp, struct mbuf
>                slen = bpf_filter(d->bd_rfilter, (u_char *)m, pktlen, 0);
>                if (slen != 0) {
>                        d->bd_fcount++;
> -                       if (gottime < bpf_ts_quality(d->bd_tstamp))
> -                               gottime = bpf_gettime(&bt, d->bd_tstamp, m);
> +                       if (tstype == BPF_TSTAMP_NORMAL ||
> +                           tstype == BPF_TSTAMP_FAST) {
> +                               whichclock = -1;
> +                               SET_CLOCKCFG_FLAGS(d->bd_tstamp,
> +                                   cs.sysclock_active, whichclock, clockflags);
> +                               KASSERT(whichclock >= 0, ("Bogus BPF tstamp "
> +                                   "configuration: 0x%04x", d->bd_tstamp));
> +                               sysclock_snap2bintime(&cs, &bt, whichclock,
> +                                   clockflags);
> +                       }
>  #ifdef MAC
>                        if (mac_bpfdesc_check_receive(d, bp->bif_ifp) == 0)
>  #endif
> @@ -1915,10 +1946,11 @@ void
>  bpf_mtap2(struct bpf_if *bp, void *data, u_int dlen, struct mbuf *m)
>  {
>        struct bintime bt;
> +       struct sysclock_snap cs;
>        struct mbuf mb;
>        struct bpf_d *d;
> -       u_int pktlen, slen;
> -       int gottime;
> +       u_int clockflags, pktlen, slen;
> +       int tstype, whichclock;
>
>        /* Skip outgoing duplicate packets. */
>        if ((m->m_flags & M_PROMISC) != 0 && m->m_pkthdr.rcvif == NULL) {
> @@ -1926,6 +1958,20 @@ bpf_mtap2(struct bpf_if *bp, void *data,
>                return;
>        }
>
> +       tstype = bp->tstype;
> +       if (tstype == BPF_TSTAMP_DEFAULT)
> +               tstype = bpf_default_tstype;
> +
> +       if (tstype == BPF_TSTAMP_NORMAL || tstype == BPF_TSTAMP_FAST)
> +               sysclock_getsnapshot(&cs, tstype == BPF_TSTAMP_FAST ?
> +                   1 : 0);
> +#ifdef notyet
> +       else if (tstype == BPF_TSTAMP_EXTERNAL)
> +               /* XXX: Convert extern tstamp to bintime. */
> +#endif
> +       else
> +               bzero(&bt, sizeof(bt));
> +
>        pktlen = m_length(m, NULL);
>        /*
>         * Craft on-stack mbuf suitable for passing to bpf_filter.
> @@ -1937,7 +1983,6 @@ bpf_mtap2(struct bpf_if *bp, void *data,
>        mb.m_len = dlen;
>        pktlen += dlen;
>
> -       gottime = BPF_TSTAMP_NONE;
>        BPFIF_LOCK(bp);
>        LIST_FOREACH(d, &bp->bif_dlist, bd_next) {
>                if (BPF_CHECK_DIRECTION(d, m->m_pkthdr.rcvif, bp->bif_ifp))
> @@ -1947,8 +1992,16 @@ bpf_mtap2(struct bpf_if *bp, void *data,
>                slen = bpf_filter(d->bd_rfilter, (u_char *)&mb, pktlen, 0);
>                if (slen != 0) {
>                        d->bd_fcount++;
> -                       if (gottime < bpf_ts_quality(d->bd_tstamp))
> -                               gottime = bpf_gettime(&bt, d->bd_tstamp, m);
> +                       if (tstype == BPF_TSTAMP_NORMAL ||
> +                           tstype == BPF_TSTAMP_FAST) {
> +                               whichclock = -1;
> +                               SET_CLOCKCFG_FLAGS(d->bd_tstamp,
> +                                   cs.sysclock_active, whichclock, clockflags);
> +                               KASSERT(whichclock >= 0, ("Bogus BPF tstamp "
> +                                   "configuration: 0x%04x", d->bd_tstamp));
> +                               sysclock_snap2bintime(&cs, &bt, whichclock,
> +                                   clockflags);
> +                       }
>  #ifdef MAC
>                        if (mac_bpfdesc_check_receive(d, bp->bif_ifp) == 0)
>  #endif
> @@ -1962,11 +2015,6 @@ bpf_mtap2(struct bpf_if *bp, void *data,
>
>  #undef BPF_CHECK_DIRECTION
>
> -#undef BPF_TSTAMP_NONE
> -#undef BPF_TSTAMP_FAST
> -#undef BPF_TSTAMP_NORMAL
> -#undef BPF_TSTAMP_EXTERN
> -
>  static int
>  bpf_hdrlen(struct bpf_d *d)
>  {
> @@ -1998,15 +2046,9 @@ bpf_hdrlen(struct bpf_d *d)
>  static void
>  bpf_bintime2ts(struct bintime *bt, struct bpf_ts *ts, int tstype)
>  {
> -       struct bintime bt2;
>        struct timeval tsm;
>        struct timespec tsn;
>
> -       if ((tstype & BPF_T_MONOTONIC) == 0) {
> -               bt2 = *bt;
> -               bintime_add(&bt2, &boottimebin);
> -               bt = &bt2;
> -       }
>        switch (BPF_T_FORMAT(tstype)) {
>        case BPF_T_MICROTIME:
>                bintime2timeval(bt, &tsm);
> @@ -2200,6 +2242,64 @@ bpf_freed(struct bpf_d *d)
>  }
>
>  /*
> + * Show or change the per bpf_if or system wide default timestamp configuration.
> + */
> +static int
> +bpf_tscfg_sysctl_handler(SYSCTL_HANDLER_ARGS)
> +{
> +       char tstype_name[16];
> +       struct bpf_if *bp;
> +       int error, tstype;
> +
> +       bp = (struct bpf_if *)arg1;
> +
> +       if (req->newptr == NULL) {
> +               /*
> +                * Return the name of the BPF interface's timestamp setting, or
> +                * the system wide default if bp is NULL.
> +                */
> +               strlcpy(tstype_name,
> +                   bpfiftstypes[bp ? bp->tstype : bpf_default_tstype],
> +                   sizeof(tstype_name));
> +               error = sysctl_handle_string(oidp, tstype_name,
> +                   sizeof(tstype_name), req);
> +       } else {
> +               /*
> +                * Change the timestamp configuration for this BPF interface or
> +                * the system wide default setting.
> +                */
> +               error = EINVAL;
> +               for (tstype = 0; tstype < NUM_BPFIFTSTYPES; tstype++) {
> +                       if (strncmp((char *)req->newptr, bpfiftstypes[tstype],
> +                           strlen(bpfiftstypes[tstype])) == 0) {
> +                               /* User specified type found in bpfiftstypes. */
> +                               if (strcmp(oidp->oid_name, "default") == 0) {
> +                                       /*
> +                                        * Don't allow BPF_TSTAMP_DEFAULT to be
> +                                        * assigned to the
> +                                        * "net.bpf.tscfg.default" OID.
> +                                        */
> +                                       if (tstype != BPF_TSTAMP_DEFAULT) {
> +                                               bpf_default_tstype = tstype;
> +                                               error = 0;
> +                                       }
> +                               } else {
> +                                       /*
> +                                        * Valid tstype for
> +                                        * "net.bpf.tscfg.<iface>" OID.
> +                                        */
> +                                       bp->tstype = tstype;
> +                                       error = 0;
> +                               }
> +                               break;
> +                       }
> +               }
> +       }
> +
> +       return (error);
> +}
> +
> +/*
>  * 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).
>  */
> @@ -2225,6 +2325,17 @@ bpfattach2(struct ifnet *ifp, u_int dlt,
>        if (bp == NULL)
>                panic("bpfattach");
>
> +       bp->tscfgoid = SYSCTL_ADD_PROC(NULL,
> +           SYSCTL_STATIC_CHILDREN(_net_bpf_tscfg), OID_AUTO, ifp->if_xname,
> +           CTLTYPE_STRING | CTLFLAG_RW, bp, sizeof(bp),
> +           bpf_tscfg_sysctl_handler, "A",
> +           "Interface BPF timestamp configuration");
> +       if (bp->tscfgoid == NULL) {
> +               free(bp, M_BPF);
> +               panic("bpfattach tscfgoid");
> +       }
> +
> +       bp->tstype = BPF_TSTAMP_DEFAULT;
>        LIST_INIT(&bp->bif_dlist);
>        bp->bif_ifp = ifp;
>        bp->bif_dlt = dlt;
> @@ -2278,6 +2389,7 @@ bpfdetach(struct ifnet *ifp)
>                BPFD_UNLOCK(d);
>        }
>
> +       sysctl_remove_oid(bp->tscfgoid, 1, 0);
>        mtx_destroy(&bp->bif_mtx);
>        free(bp, M_BPF);
>  }
>
> Modified: head/sys/net/bpf.h
> ==============================================================================
> --- head/sys/net/bpf.h  Fri Dec 30 06:24:59 2011        (r228985)
> +++ head/sys/net/bpf.h  Fri Dec 30 08:57:58 2011        (r228986)
> @@ -1,12 +1,17 @@
>  /*-
>  * Copyright (c) 1990, 1991, 1993
> - *     The Regents of the University of California.  All rights reserved.
> + *     The Regents of the University of California.
> + * Copyright (c) 2011 The University of Melbourne.
> + * All rights reserved.
>  *
>  * This code is derived from the Stanford/CMU enet packet filter,
>  * (net/enet.c) distributed as part of 4.3BSD, and code contributed
>  * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
>  * Berkeley Laboratory.
>  *
> + * Portions of this software were developed by Julien Ridoux at the University
> + * of Melbourne under sponsorship from the FreeBSD Foundation.
> + *
>  * Redistribution and use in source and binary forms, with or without
>  * modification, are permitted provided that the following conditions
>  * are met:
> @@ -166,25 +171,17 @@ enum bpf_direction {
>  #define        BPF_T_NONE              0x0003
>  #define        BPF_T_FORMAT_MASK       0x0003
>  #define        BPF_T_NORMAL            0x0000
> -#define        BPF_T_FAST              0x0100
> -#define        BPF_T_MONOTONIC         0x0200
> -#define        BPF_T_MONOTONIC_FAST    (BPF_T_FAST | BPF_T_MONOTONIC)
> -#define        BPF_T_FLAG_MASK         0x0300
> +#define        BPF_T_MONOTONIC         0x0100
> +#define        BPF_T_FLAG_MASK         0x0100
>  #define        BPF_T_FORMAT(t)         ((t) & BPF_T_FORMAT_MASK)
>  #define        BPF_T_FLAG(t)           ((t) & BPF_T_FLAG_MASK)
>  #define        BPF_T_VALID(t)                                          \
>     ((t) == BPF_T_NONE || (BPF_T_FORMAT(t) != BPF_T_NONE &&    \
>     ((t) & ~(BPF_T_FORMAT_MASK | BPF_T_FLAG_MASK)) == 0))
>
> -#define        BPF_T_MICROTIME_FAST            (BPF_T_MICROTIME | BPF_T_FAST)
> -#define        BPF_T_NANOTIME_FAST             (BPF_T_NANOTIME | BPF_T_FAST)
> -#define        BPF_T_BINTIME_FAST              (BPF_T_BINTIME | BPF_T_FAST)
>  #define        BPF_T_MICROTIME_MONOTONIC       (BPF_T_MICROTIME | BPF_T_MONOTONIC)
>  #define        BPF_T_NANOTIME_MONOTONIC        (BPF_T_NANOTIME | BPF_T_MONOTONIC)
>  #define        BPF_T_BINTIME_MONOTONIC         (BPF_T_BINTIME | BPF_T_MONOTONIC)
> -#define        BPF_T_MICROTIME_MONOTONIC_FAST  (BPF_T_MICROTIME | BPF_T_MONOTONIC_FAST)
> -#define        BPF_T_NANOTIME_MONOTONIC_FAST   (BPF_T_NANOTIME | BPF_T_MONOTONIC_FAST)
> -#define        BPF_T_BINTIME_MONOTONIC_FAST    (BPF_T_BINTIME | BPF_T_MONOTONIC_FAST)
>
>  /*
>  * Structure prepended to each packet.
> @@ -1100,6 +1097,8 @@ struct bpf_if {
>        u_int bif_hdrlen;               /* length of link header */
>        struct ifnet *bif_ifp;          /* corresponding interface */
>        struct mtx      bif_mtx;        /* mutex for interface */
> +       struct sysctl_oid *tscfgoid;    /* timestamp sysctl oid for interface */
> +       int tstype;                     /* timestamp setting for interface */
>  };
>
>  void    bpf_bufheld(struct bpf_d *d);


More information about the svn-src-head mailing list