Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F157083197
D42943.id131103.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
21 KB
Referenced Files
None
Subscribers
None
D42943.id131103.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D42943: bpf: Full support for sysclock timestamping
Attached
Detach File
Event Timeline
Log In to Comment