diff --git a/share/man/man4/bpf.4 b/share/man/man4/bpf.4 --- a/share/man/man4/bpf.4 +++ b/share/man/man4/bpf.4 @@ -47,7 +47,7 @@ .\" This document is derived in part from the enet man page (enet.4) .\" distributed with 4.3BSD Unix. .\" -.Dd October 13, 2021 +.Dd Nov 30, 2023 .Dt BPF 4 .Os .Sh NAME @@ -541,7 +541,13 @@ .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 clock type, format and resolution of the time stamps returned by +.Nm bpf. +The default clock is the prevailing system clock, which in turn defaults to the +traditional FBC (FeedBack Clock). The following presets +cover all FORMAT and FLAG flag combinations for the system clock, with a default +of +.Dv BPF_T_MICROTIME. Set to .Dv BPF_T_MICROTIME , .Dv BPF_T_MICROTIME_FAST , @@ -575,27 +581,31 @@ 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 -store the time elapsed since kernel boot. -This setting is initialized to -.Dv BPF_T_MICROTIME -by default. +.Dv BPF_T_*_FAST formats +are analogs of corresponding formats without the _FAST suffix but do not +perform a full time counter query, so they suffer a timestamping error of up to +one timecounter tick. The +.Dv BPF_T_*_MONOTONIC* +formats are uptime clocks, that is they supply the time elapsed since kernel +boot, rather than UTC. +To explicitly select the underlying clock used, the above presets can be or-ed +with one of the CLOCK formats +.Dv BPF_T_FBC, +.Dv BPF_T_MONOFFC, +.Dv BPF_T_NATFFC, +.Dv BPF_T_DIFFFFC, +where the latter three are FFCLOCK (FeedForward Clock) options. The following +presets are available for FFclock use, all returning FORMAT bintime for absolute +timestamps, in addition to a separate raw timestamp (FFCounter read). Set to +.Dv BPF_T_BINTIME_FFC_NATFFC +to obtain a UTC FFclock following the native FF daemon clock precisely, +.Dv BPF_T_BINTIME_FFC_MONOFFC +for the FFclock UTC system clock which is guaranteed to progress monotonically, +and finally, +.Dv BPF_T_BINTIME_FFC_DIFFFFC +to access the difference clock. Use this for highly accurate measurement of time +differences below (roughly) a 1hr timescale (eg sub-ns errors +for RTTs). .It Dv BIOCFEEDBACK .Pq Li u_int Set packet feedback mode. @@ -665,7 +675,7 @@ now supports several standard .Xr ioctl 2 Ns 's which allow the user to do async and/or non-blocking I/O to an open -.I bpf +.Nm bpf file descriptor. .Bl -tag -width SIOCGIFADDR .It Dv FIONREAD @@ -722,6 +732,8 @@ uint32_t bh_datalen; /* original length of packet */ u_short bh_hdrlen; /* length of bpf header (this struct plus alignment padding) */ + ffcounter bh_ffcounter; /* feedforward counter stamp */ + }; struct bpf_hdr { @@ -730,12 +742,13 @@ uint32_t bh_datalen; /* original length of packet */ u_short bh_hdrlen; /* length of bpf header (this struct plus alignment padding) */ + ffcounter bh_ffcounter; /* feedforward counter stamp */ }; .Ed .Pp The fields, whose values are stored in host order, and are: .Pp -.Bl -tag -compact -width bh_datalen +.Bl -tag -compact -width bh_ffcounter .It Li bh_tstamp The time at which the packet was processed by the packet filter. .It Li bh_caplen @@ -753,6 +766,8 @@ .Fn sizeof "struct bpf_xhdr" or .Fn sizeof "struct bpf_hdr" . +.It Li bh_ffcounter +The raw timestamp (FeedForward counter reading) of packet arrival. .El .Pp The diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c --- a/sys/kern/kern_tc.c +++ b/sys/kern/kern_tc.c @@ -1350,7 +1350,7 @@ } /* If snapshot was created with !fast, delta will be >0. */ - if (flags & FFCLOCK_FAST && cs->delta > 0) { + if (!(flags & FFCLOCK_FAST) && cs->delta > 0) { ffclock_convert_delta((ffcounter)cs->delta,period,&bt2); bintime_add(bt, &bt2); } diff --git a/sys/net/bpf.h b/sys/net/bpf.h --- a/sys/net/bpf.h +++ b/sys/net/bpf.h @@ -43,6 +43,7 @@ #include #include #include +#include /* BSD style release date */ #define BPF_RELEASE 199606 @@ -165,23 +166,57 @@ BPF_D_OUT /* See outgoing packets */ }; -/* Time stamping functions */ -#define BPF_T_MICROTIME 0x0000 -#define BPF_T_NANOTIME 0x0001 -#define BPF_T_BINTIME 0x0002 -#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_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)) +/* Time stamping flags. */ +/* FORMAT flags [ mutually exclusive, not to be ORed. ] */ +#define BPF_T_MICROTIME 0x0000 +#define BPF_T_NANOTIME 0x0001 +#define BPF_T_BINTIME 0x0002 +#define BPF_T_NONE 0x0003 // relates to ts only, FFRAW independent +#define BPF_T_FORMAT_MASK 0x0003 +/* FFRAW flag */ +#define BPF_T_NOFFC 0x0000 // no FFcount +#define BPF_T_FFC 0x0010 // want FFcount +#define BPF_T_FFRAW_MASK 0x0010 +/* FLAG flags [ can view bits as ORable flags ] */ +#define BPF_T_NORMAL 0x0000 // UTC, !FAST +#define BPF_T_FAST 0x0100 // UTC, FAST +#define BPF_T_MONOTONIC 0x0200 // UPTIME, !FAST +#define BPF_T_MONOTONIC_FAST 0x0300 // UPTIME, FAST +#define BPF_T_FLAG_MASK 0x0300 +/* CLOCK flags [ mutually exclusive, not to be ORed. ] */ +#define BPF_T_SYSC 0x0000 // read current sysclock +#define BPF_T_FBC 0x1000 // read FBclock +#define BPF_T_MONOFFC 0x2000 // read monoFFC (sysclock reads are mono) +#define BPF_T_NATFFC 0x3000 // read natFFC +#define BPF_T_DIFFFFC 0x4000 // read diffFFC +#define BPF_T_CLOCK_MASK 0x7000 + +/* Extract FORMAT, FFRAW, FLAG, CLOCK bits. */ +#define BPF_T_FORMAT(t) ((t) & BPF_T_FORMAT_MASK) +#define BPF_T_FFRAW(t) ((t) & BPF_T_FFRAW_MASK) +#define BPF_T_FLAG(t) ((t) & BPF_T_FLAG_MASK) +#define BPF_T_CLOCK(t) ((t) & BPF_T_CLOCK_MASK) +/* + * Used to vet descriptor passed to BPF via BIOCSTSTAMP ioctl. + * All components are independent, and either always meaningful, or + * not acted on if not meaningful. Hence checks reduce to ensuring no bits in + * undefined positions, and not asking for a FF clock that doesn't exist. +*/ +#ifdef FFCLOCK +#define BPF_T_VALID(t) ( ((t) & ~(BPF_T_FORMAT_MASK | BPF_T_FFRAW_MASK | \ + BPF_T_FLAG_MASK | BPF_T_CLOCK_MASK)) == 0 \ + && BPF_T_CLOCK(t)<=BPF_T_DIFFFFC ) +#else +#define BPF_T_VALID(t) ( ((t) & ~(BPF_T_FORMAT_MASK | BPF_T_FFRAW_MASK | \ + BPF_T_FLAG_MASK | BPF_T_CLOCK_MASK)) == 0 \ + && BPF_T_CLOCK(t)<=BPF_T_FBC ) +#endif + +/* + * Presets to ease tstype selection for users. These cover all FORMAT*FLAG + * combinations for a default clock of BPF_T_SYSC, with BPF_T_NOFFC . + */ #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) @@ -190,7 +225,13 @@ #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) +#define BPF_T_BINTIME_MONOTONIC_FAST (BPF_T_BINTIME | BPF_T_MONOTONIC_ + +/* Presets for the main FFCLOCK choices, all with BPF_T_FFC. */ +#define BPF_T_BINTIME_FFC_MONOFFC (BPF_T_BINTIME | BPF_T_FFC | BPF_T_MONOFFC) +#define BPF_T_BINTIME_FFC_NATFFC (BPF_T_BINTIME | BPF_T_FFC | BPF_T_NATFFC) +#define BPF_T_BINTIME_FFC_DIFFFFC (BPF_T_BINTIME | BPF_T_FFC | BPF_T_DIFFFFC) + /* * Structure prepended to each packet. @@ -205,6 +246,7 @@ bpf_u_int32 bh_datalen; /* original length of packet */ u_short bh_hdrlen; /* length of bpf header (this struct plus alignment padding) */ + ffcounter bh_ffcounter; /* feedforward counter stamp */ }; /* Obsolete */ struct bpf_hdr { @@ -213,6 +255,7 @@ bpf_u_int32 bh_datalen; /* original length of packet */ u_short bh_hdrlen; /* length of bpf header (this struct plus alignment padding) */ + ffcounter bh_ffcounter; /* feedforward counter stamp */ }; #ifdef _KERNEL #define MTAG_BPF 0x627066 diff --git a/sys/net/bpf.c b/sys/net/bpf.c --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -40,6 +40,7 @@ #include #include "opt_bpf.h" #include "opt_ddb.h" +#include "opt_ffclock.h" #include "opt_netgraph.h" #include @@ -58,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -132,8 +134,13 @@ #define PRINET 26 /* interruptible */ #define BPF_PRIO_MAX 7 -#define SIZEOF_BPF_HDR(type) \ +#ifdef FFCLOCK /* New bh_ffcounter member, placed at end to ease ABI issues. */ +#define SIZEOF_BPF_HDR(type) \ + (offsetof(type, bh_ffcounter) + sizeof(((type *)0)->bh_ffcounter)) +#else +#define SIZEOF_BPF_HDR(type) \ (offsetof(type, bh_hdrlen) + sizeof(((type *)0)->bh_hdrlen)) +#endif #ifdef COMPAT_FREEBSD32 #include @@ -153,6 +160,7 @@ uint32_t bh_datalen; /* original length of packet */ uint16_t bh_hdrlen; /* length of bpf header (this struct plus alignment padding) */ + ffcounter bh_ffcounter; /* feedforward counter stamp */ }; #endif @@ -205,7 +213,11 @@ bpf_wakeup(struct bpf_d *); static void catchpacket(struct bpf_d *, u_char *, u_int, u_int, void (*)(struct bpf_d *, caddr_t, u_int, void *, u_int), +#ifdef FFCLOCK + struct bintime *, ffcounter *); +#else struct bintime *); +#endif static void reset_d(struct bpf_d *); static int bpf_setf(struct bpf_d *, struct bpf_program *, u_long cmd); static int bpf_getdltlist(struct bpf_d *, struct bpf_dltlist *); @@ -1779,7 +1791,8 @@ break; /* - * Get packet timestamp format and resolution. + * Get packet timestamp descriptor, describing the requested CLOCK, + * FFRAW (raw counter return), FLAG qualifiers, and FORMAT (resolution). */ case BIOCGTSTAMP: BPFD_LOCK(d); @@ -1788,7 +1801,8 @@ break; /* - * Set packet timestamp format and resolution. + * Set packet timestamp descriptor, describing the requested CLOCK, + * FFRAW (raw counter return), FLAG qualifiers, and FORMAT (resolution). */ case BIOCSTSTAMP: { @@ -2244,52 +2258,39 @@ } } -#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) +/* + * Translate the FLAG and CLOCK dimensions of the BPF_T_ timestamp descriptor + * held in tstype, to the sysclock flag system for clock-type specification. + * The specification requires that the clock family be separately carried, BOTH + * the default FB and FF (nativeFFC) clocks correspond to sysflags=0. + * The FORMAT and FFRAW dimensions are ignored as they are processed elsewhere. + */ +static void +translate_clock_flags(int tstype, int *clockfamily, uint32_t *sysflags) { + int clock; - if (tstype == BPF_T_NONE) - return (BPF_TSTAMP_NONE); - if ((tstype & BPF_T_FAST) != 0) - return (BPF_TSTAMP_FAST); - - return (BPF_TSTAMP_NORMAL); -} + *sysflags = 0; + clock = BPF_T_CLOCK(tstype); -static int -bpf_gettime(struct bintime *bt, int tstype, struct mbuf *m) -{ - struct timespec ts; - struct m_tag *tag; - int quality; - - quality = bpf_ts_quality(tstype); - if (quality == BPF_TSTAMP_NONE) - return (quality); - - if (m != NULL) { - if ((m->m_flags & (M_PKTHDR | M_TSTMP)) == (M_PKTHDR | M_TSTMP)) { - mbuf_tstmp2timespec(m, &ts); - timespec2bintime(&ts, bt); - return (BPF_TSTAMP_EXTERN); - } - tag = m_tag_locate(m, MTAG_BPF, MTAG_BPF_TIMESTAMP, NULL); - if (tag != NULL) { - *bt = *(struct bintime *)(tag + 1); - return (BPF_TSTAMP_EXTERN); - } + if ( (clock == BPF_T_SYSC && sysclock_active == SYSCLOCK_FB) || + clock == BPF_T_FBC ) { // FB case + *clockfamily = SYSCLOCK_FB; + if (tstype & BPF_T_FAST) + *sysflags = FBCLOCK_FAST; + if (tstype & BPF_T_MONOTONIC) + *sysflags |= FBCLOCK_UPTIME; + } else { // FF case + *clockfamily = SYSCLOCK_FF; + if (tstype & BPF_T_FAST) + *sysflags = FFCLOCK_FAST; + if (tstype & BPF_T_MONOTONIC) + *sysflags |= FFCLOCK_UPTIME; + if (clock == BPF_T_MONOFFC || clock == BPF_T_SYSC) + *sysflags |= FFCLOCK_MONO; + if (clock == BPF_T_DIFFFFC) + *sysflags |= FFCLOCK_DIFF; } - if (quality == BPF_TSTAMP_NORMAL) - binuptime(bt); - else - getbinuptime(bt); - - return (quality); } /* @@ -2303,14 +2304,18 @@ { struct epoch_tracker et; struct bintime bt; + struct sysclock_snap cs; + int clockfamily; + uint32_t flags; struct bpf_d *d; #ifdef BPF_JITTER bpf_jit_filter *bf; #endif u_int slen; - int gottime; - gottime = BPF_TSTAMP_NONE; + /* Obtain state data and tc counter timestamp for FF and FB clocks. */ + sysclock_getsnapshot(&cs, 0); + NET_EPOCH_ENTER(et); CK_LIST_FOREACH(d, &bp->bif_dlist, bd_next) { counter_u64_add(d->bd_rcount, 1); @@ -2333,14 +2338,34 @@ */ BPFD_LOCK(d); counter_u64_add(d->bd_fcount, 1); - if (gottime < bpf_ts_quality(d->bd_tstamp)) - gottime = bpf_gettime(&bt, d->bd_tstamp, - NULL); + + /* No normal timestamp desired, skip ahead. */ + if (BPF_T_FORMAT(d->bd_tstamp) == BPF_T_NONE) { + bzero(&bt, sizeof(bt)); + goto ts_filled; + } + /* Prepare a ts from the requested clock. */ + translate_clock_flags(d->bd_tstamp, &clockfamily, &flags); + sysclock_snap2bintime(&cs, &bt, clockfamily, flags); + +ts_filled: #ifdef MAC if (mac_bpfdesc_check_receive(d, bp->bif_ifp) == 0) #endif +#ifdef FFCLOCK + { + ffcounter ffcount = 0; + if (BPF_T_FFRAW(d->bd_tstamp) == BPF_T_FFC) + catchpacket(d, pkt, pktlen, slen, + bpf_append_mbuf, &bt, &cs.ffcount); + else + catchpacket(d, pkt, pktlen, slen, + bpf_append_mbuf, &bt, &ffcount); + } +#else catchpacket(d, pkt, pktlen, slen, bpf_append_bytes, &bt); +#endif BPFD_UNLOCK(d); } } @@ -2367,12 +2392,16 @@ { struct epoch_tracker et; struct bintime bt; + struct timespec ts; + struct sysclock_snap cs; + int clockfamily; + uint32_t flags; struct bpf_d *d; + struct m_tag *tag = NULL; #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_rcvif(m) == NULL) { @@ -2380,8 +2409,10 @@ return; } + /* Obtain state data and tc counter timestamp for FF and FB clocks */ + sysclock_getsnapshot(&cs, 0); + pktlen = m_length(m, NULL); - gottime = BPF_TSTAMP_NONE; NET_EPOCH_ENTER(et); CK_LIST_FOREACH(d, &bp->bif_dlist, bd_next) { @@ -2401,13 +2432,49 @@ BPFD_LOCK(d); counter_u64_add(d->bd_fcount, 1); - if (gottime < bpf_ts_quality(d->bd_tstamp)) - gottime = bpf_gettime(&bt, d->bd_tstamp, m); + + /* No normal timestamp desired, skip ahead. */ + if (BPF_T_FORMAT(d->bd_tstamp) == BPF_T_NONE) { + bzero(&bt, sizeof(bt)); + goto ts_filled; + } + /* Use the externally supplied ts, if available. */ + if (m != NULL) { + if ((m->m_flags & (M_PKTHDR | M_TSTMP)) == + (M_PKTHDR | M_TSTMP)) { + mbuf_tstmp2timespec(m, &ts); + timespec2bintime(&ts, &bt); + goto ts_filled; + } + tag = m_tag_locate(m, MTAG_BPF, + MTAG_BPF_TIMESTAMP, NULL); + if (tag != NULL) { + bt = *(struct bintime *)(tag + 1); + goto ts_filled; + } + } + /* Prepare a ts from the requested clock. */ + translate_clock_flags(d->bd_tstamp, &clockfamily, &flags); + sysclock_snap2bintime(&cs, &bt, clockfamily, flags); + +ts_filled: #ifdef MAC if (mac_bpfdesc_check_receive(d, bp->bif_ifp) == 0) #endif +#ifdef FFCLOCK + { + ffcounter ffcount = 0; + if (BPF_T_FFRAW(d->bd_tstamp) == BPF_T_FFC) + catchpacket(d, (u_char *)m, pktlen,slen, + bpf_append_mbuf, &bt, &cs.ffcount); + else + catchpacket(d, (u_char *)m, pktlen,slen, + bpf_append_mbuf, &bt, &ffcount); + } +#else catchpacket(d, (u_char *)m, pktlen, slen, bpf_append_mbuf, &bt); +#endif BPFD_UNLOCK(d); } } @@ -2432,10 +2499,14 @@ { struct epoch_tracker et; struct bintime bt; + struct timespec ts; + struct sysclock_snap cs; + int clockfamily; + uint32_t flags; struct mbuf mb; struct bpf_d *d; + struct m_tag *tag = NULL; u_int pktlen, slen; - int gottime; /* Skip outgoing duplicate packets. */ if ((m->m_flags & M_PROMISC) != 0 && m->m_pkthdr.rcvif == NULL) { @@ -2443,6 +2514,9 @@ return; } + /* Obtain state data and tc counter timestamp for FF and FB clocks */ + sysclock_getsnapshot(&cs, 0); + pktlen = m_length(m, NULL); /* * Craft on-stack mbuf suitable for passing to bpf_filter. @@ -2455,8 +2529,6 @@ mb.m_len = dlen; pktlen += dlen; - gottime = BPF_TSTAMP_NONE; - NET_EPOCH_ENTER(et); CK_LIST_FOREACH(d, &bp->bif_dlist, bd_next) { if (BPF_CHECK_DIRECTION(d, m->m_pkthdr.rcvif, bp->bif_ifp)) @@ -2467,13 +2539,49 @@ BPFD_LOCK(d); counter_u64_add(d->bd_fcount, 1); - if (gottime < bpf_ts_quality(d->bd_tstamp)) - gottime = bpf_gettime(&bt, d->bd_tstamp, m); + + /* No normal timestamp desired, skip ahead. */ + if (BPF_T_FORMAT(d->bd_tstamp) == BPF_T_NONE) { + bzero(&bt, sizeof(bt)); + goto ts_filled; + } + /* Use the externally supplied ts, if available. */ + if (m != NULL) { + if ((m->m_flags & (M_PKTHDR | M_TSTMP)) == + (M_PKTHDR | M_TSTMP)) { + mbuf_tstmp2timespec(m, &ts); + timespec2bintime(&ts, &bt); + goto ts_filled; + } + tag = m_tag_locate(m, MTAG_BPF, + MTAG_BPF_TIMESTAMP, NULL); + if (tag != NULL) { + bt = *(struct bintime *)(tag + 1); + goto ts_filled; + } + } + /* Prepare a ts from the requested clock. */ + translate_clock_flags(d->bd_tstamp, &clockfamily, &flags); + sysclock_snap2bintime(&cs, &bt, clockfamily, flags); + +ts_filled: #ifdef MAC if (mac_bpfdesc_check_receive(d, bp->bif_ifp) == 0) #endif +#ifdef FFCLOCK + { + ffcounter ffcount = 0; + if (BPF_T_FFRAW(d->bd_tstamp) == BPF_T_FFC) + catchpacket(d, (u_char *)&mb, pktlen,slen, + bpf_append_mbuf, &bt, &cs.ffcount); + else + catchpacket(d, (u_char *)&mb, pktlen,slen, + bpf_append_mbuf, &bt, &ffcount); + } +#else catchpacket(d, (u_char *)&mb, pktlen, slen, bpf_append_mbuf, &bt); +#endif BPFD_UNLOCK(d); } } @@ -2490,10 +2598,6 @@ } #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) @@ -2523,19 +2627,13 @@ return (hdrlen - d->bd_bif->bif_hdrlen); } +/* This function interprets only the FORMAT dimension of tstype */ static void bpf_bintime2ts(struct bintime *bt, struct bpf_ts *ts, int tstype) { - struct bintime bt2, boottimebin; struct timeval tsm; struct timespec tsn; - if ((tstype & BPF_T_MONOTONIC) == 0) { - bt2 = *bt; - getboottimebin(&boottimebin); - bintime_add(&bt2, &boottimebin); - bt = &bt2; - } switch (BPF_T_FORMAT(tstype)) { case BPF_T_MICROTIME: bintime2timeval(bt, &tsm); @@ -2564,7 +2662,11 @@ static void catchpacket(struct bpf_d *d, u_char *pkt, u_int pktlen, u_int snaplen, void (*cpfn)(struct bpf_d *, caddr_t, u_int, void *, u_int), +#ifdef FFCLOCK + struct bintime *bt, ffcounter *ffcount) +#else struct bintime *bt) +#endif { static char zeroes[BPF_ALIGNMENT]; struct bpf_xhdr hdr; @@ -2661,9 +2763,10 @@ caplen = totlen - hdrlen; tstype = d->bd_tstamp; - do_timestamp = tstype != BPF_T_NONE; + do_timestamp = BPF_T_FORMAT(tstype) != BPF_T_NONE; #ifndef BURN_BRIDGES - if (tstype == BPF_T_NONE || BPF_T_FORMAT(tstype) == BPF_T_MICROTIME) { + if (BPF_T_FORMAT(tstype) == BPF_T_NONE || + BPF_T_FORMAT(tstype) == BPF_T_MICROTIME) { struct bpf_ts ts; if (do_timestamp) bpf_bintime2ts(bt, &ts, tstype); @@ -2674,6 +2777,9 @@ hdr32_old.bh_tstamp.tv_sec = ts.bt_sec; hdr32_old.bh_tstamp.tv_usec = ts.bt_frac; } +#ifdef FFCLOCK + hdr32_old.bh_ffcounter = *ffcount; +#endif hdr32_old.bh_datalen = pktlen; hdr32_old.bh_hdrlen = hdrlen; hdr32_old.bh_caplen = caplen; @@ -2687,6 +2793,9 @@ hdr_old.bh_tstamp.tv_sec = ts.bt_sec; hdr_old.bh_tstamp.tv_usec = ts.bt_frac; } +#ifdef FFCLOCK + hdr_old.bh_ffcounter = *ffcount; +#endif hdr_old.bh_datalen = pktlen; hdr_old.bh_hdrlen = hdrlen; hdr_old.bh_caplen = caplen; @@ -2703,6 +2812,9 @@ bzero(&hdr, sizeof(hdr)); if (do_timestamp) bpf_bintime2ts(bt, &hdr.bh_tstamp, tstype); +#ifdef FFCLOCK + hdr.bh_ffcounter = *ffcount; +#endif hdr.bh_datalen = pktlen; hdr.bh_hdrlen = hdrlen; hdr.bh_caplen = caplen;