Page MenuHomeFreeBSD

D42943.id131103.diff
No OneTemporary

D42943.id131103.diff

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 <sys/_eventhandler.h>
#include <sys/ck.h>
#include <net/dlt.h>
+#include <sys/_ffcounter.h>
/* 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 <sys/cdefs.h>
#include "opt_bpf.h"
#include "opt_ddb.h"
+#include "opt_ffclock.h"
#include "opt_netgraph.h"
#include <sys/param.h>
@@ -58,6 +59,7 @@
#include <sys/signalvar.h>
#include <sys/filio.h>
#include <sys/sockio.h>
+#include <sys/timeffc.h>
#include <sys/ttycom.h>
#include <sys/uio.h>
#include <sys/sysent.h>
@@ -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 <sys/mount.h>
@@ -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;

File Metadata

Mime Type
text/plain
Expires
Tue, May 19, 8:25 AM (4 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33302655
Default Alt Text
D42943.id131103.diff (21 KB)

Event Timeline