summaryrefslogtreecommitdiffstats
path: root/sys/net
diff options
context:
space:
mode:
authorlstewart <lstewart@FreeBSD.org>2011-11-21 04:17:24 +0000
committerlstewart <lstewart@FreeBSD.org>2011-11-21 04:17:24 +0000
commit1ce25155b2d01208512db186340fcee21173a4c8 (patch)
tree5b5d10522551ac013935e99d594da8cbc53c83a4 /sys/net
parentbda11ecfe1fe5a397eca69e769e9a3e1fcf1cfff (diff)
downloadFreeBSD-src-1ce25155b2d01208512db186340fcee21173a4c8.zip
FreeBSD-src-1ce25155b2d01208512db186340fcee21173a4c8.tar.gz
- When feed-forward clock support is compiled in, change the BPF header to
contain both a regular timestamp obtained from the system clock and the current feed-forward ffcounter value. This enables new possibilities including comparison of timekeeping performance and timestamp correction during post processing. - Add the net.bpf.ffclock_tstamp sysctl to provide a choice between timestamping packets using the feedback or feed-forward system clock. 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/ Submitted by: Julien Ridoux (jridoux at unimelb edu au)
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/bpf.c154
-rw-r--r--sys/net/bpf.h23
2 files changed, 165 insertions, 12 deletions
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index 3dd2f93..f7b73cc 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -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 FreeBSD Foundation.
+ * 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:
@@ -39,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include "opt_bpf.h"
#include "opt_compat.h"
+#include "opt_ffclock.h"
#include "opt_netgraph.h"
#include <sys/types.h>
@@ -55,6 +61,9 @@ __FBSDID("$FreeBSD$");
#include <sys/signalvar.h>
#include <sys/filio.h>
#include <sys/sockio.h>
+#ifdef FFCLOCK
+#include <sys/timeffc.h>
+#endif
#include <sys/ttycom.h>
#include <sys/uio.h>
@@ -90,8 +99,13 @@ MALLOC_DEFINE(M_BPF, "BPF", "BPF data");
#define PRINET 26 /* interruptible */
+#ifdef FFCLOCK
+#define SIZEOF_BPF_HDR(type) \
+ (offsetof(type, ffcount_stamp) + sizeof(((type *)0)->ffcount_stamp))
+#else
#define SIZEOF_BPF_HDR(type) \
(offsetof(type, bh_hdrlen) + sizeof(((type *)0)->bh_hdrlen))
+#endif
#ifdef COMPAT_FREEBSD32
#include <sys/mount.h>
@@ -111,6 +125,9 @@ struct bpf_hdr32 {
uint32_t bh_datalen; /* original length of packet */
uint16_t bh_hdrlen; /* length of bpf header (this struct
plus alignment padding) */
+#ifdef FFCLOCK
+ ffcounter ffcount_stamp; /* ffcounter timestamp of packet */
+#endif
};
#endif
@@ -151,9 +168,16 @@ static int bpf_setif(struct bpf_d *, struct ifreq *);
static void bpf_timed_out(void *);
static __inline void
bpf_wakeup(struct bpf_d *);
+#ifdef FFCLOCK
+static void catchpacket(struct bpf_d *, u_char *, unsigned int,
+ unsigned int, void (*)(struct bpf_d *, caddr_t,
+ unsigned int, void *, unsigned int), struct bintime *,
+ ffcounter *);
+#else
static void catchpacket(struct bpf_d *, u_char *, u_int, u_int,
void (*)(struct bpf_d *, caddr_t, u_int, void *, u_int),
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 *);
@@ -172,6 +196,12 @@ SYSCTL_INT(_net_bpf, OID_AUTO, zerocopy_enable, CTLFLAG_RW,
&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");
+#ifdef FFCLOCK
+static int bpf_ffclock_tstamp = 0;
+SYSCTL_INT(_net_bpf, OID_AUTO, ffclock_tstamp, CTLFLAG_RW,
+ &bpf_ffclock_tstamp, 0,
+ "Set BPF to timestamp using Feed-Forward clock by default");
+#endif
static d_open_t bpfopen;
static d_read_t bpfread;
@@ -698,6 +728,15 @@ bpfopen(struct cdev *dev, int flags, int fmt, struct thread *td)
callout_init_mtx(&d->bd_callout, &d->bd_mtx, 0);
knlist_init_mtx(&d->bd_sel.si_note, &d->bd_mtx);
+#ifdef FFCLOCK
+ /*
+ * Set the timestamping mode for this device, i.e. which clock is used.
+ * The default option is to use the feedback/ntpd system clock.
+ */
+ if (bpf_ffclock_tstamp)
+ d->bd_tstamp = d->bd_tstamp | BPF_T_FFCLOCK;
+#endif
+
return (0);
}
@@ -1776,8 +1815,13 @@ bpf_ts_quality(int tstype)
return (BPF_TSTAMP_NORMAL);
}
+#ifdef FFCLOCK
+static int
+bpf_gettime(struct bintime *bt, ffcounter *ffcount, int tstype, struct mbuf *m)
+#else
static int
bpf_gettime(struct bintime *bt, int tstype, struct mbuf *m)
+#endif
{
struct m_tag *tag;
int quality;
@@ -1793,11 +1837,31 @@ bpf_gettime(struct bintime *bt, int tstype, struct mbuf *m)
return (BPF_TSTAMP_EXTERN);
}
}
- if (quality == BPF_TSTAMP_NORMAL)
- binuptime(bt);
- else
- getbinuptime(bt);
-
+ if (quality == BPF_TSTAMP_NORMAL) {
+#ifdef FFCLOCK
+ if ((tstype & BPF_T_FFCLOCK) == 0) {
+ ffclock_read_counter(ffcount);
+#endif
+ binuptime(bt);
+#ifdef FFCLOCK
+ } else {
+ if ((tstype & BPF_T_MONOTONIC) == 0)
+ ffclock_abstime(ffcount, bt, NULL,
+ (FFCLOCK_LERP | FFCLOCK_LEAPSEC));
+ else
+ ffclock_abstime(ffcount, bt, NULL,
+ (FFCLOCK_LERP | FFCLOCK_UPTIME));
+ }
+#endif
+ } else {
+#ifdef FFCLOCK
+ if ((tstype & BPF_T_FFCLOCK) == BPF_T_FFCLOCK)
+ ffclock_abstime(ffcount, bt, NULL,
+ (FFCLOCK_LERP | FFCLOCK_LEAPSEC | FFCLOCK_FAST));
+ else
+#endif
+ getbinuptime(bt);
+ }
return (quality);
}
@@ -1817,6 +1881,9 @@ bpf_tap(struct bpf_if *bp, u_char *pkt, u_int pktlen)
#endif
u_int slen;
int gottime;
+#ifdef FFCLOCK
+ ffcounter ffcount;
+#endif
gottime = BPF_TSTAMP_NONE;
BPFIF_LOCK(bp);
@@ -1838,13 +1905,24 @@ bpf_tap(struct bpf_if *bp, u_char *pkt, u_int pktlen)
slen = bpf_filter(d->bd_rfilter, pkt, pktlen, pktlen);
if (slen != 0) {
d->bd_fcount++;
- if (gottime < bpf_ts_quality(d->bd_tstamp))
+ if (gottime < bpf_ts_quality(d->bd_tstamp)) {
+#ifdef FFCLOCK
+ gottime = bpf_gettime(&bt, &ffcount,
+ d->bd_tstamp, NULL);
+#else
gottime = bpf_gettime(&bt, d->bd_tstamp, NULL);
+#endif
+ }
#ifdef MAC
if (mac_bpfdesc_check_receive(d, bp->bif_ifp) == 0)
#endif
+#ifdef FFCLOCK
+ catchpacket(d, pkt, pktlen, slen,
+ bpf_append_bytes, &bt, &ffcount);
+#else
catchpacket(d, pkt, pktlen, slen,
bpf_append_bytes, &bt);
+#endif
}
BPFD_UNLOCK(d);
}
@@ -1868,6 +1946,9 @@ bpf_mtap(struct bpf_if *bp, struct mbuf *m)
#endif
u_int pktlen, slen;
int gottime;
+#ifdef FFCLOCK
+ ffcounter ffcount;
+#endif
/* Skip outgoing duplicate packets. */
if ((m->m_flags & M_PROMISC) != 0 && m->m_pkthdr.rcvif == NULL) {
@@ -1895,12 +1976,24 @@ bpf_mtap(struct bpf_if *bp, struct mbuf *m)
if (slen != 0) {
d->bd_fcount++;
if (gottime < bpf_ts_quality(d->bd_tstamp))
+ {
+#ifdef FFCLOCK
+ gottime = bpf_gettime(&bt, &ffcount,
+ d->bd_tstamp, m);
+#else
gottime = bpf_gettime(&bt, d->bd_tstamp, m);
+#endif
+ }
#ifdef MAC
if (mac_bpfdesc_check_receive(d, bp->bif_ifp) == 0)
#endif
+#ifdef FFCLOCK
+ 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);
}
@@ -1919,6 +2012,9 @@ bpf_mtap2(struct bpf_if *bp, void *data, u_int dlen, struct mbuf *m)
struct bpf_d *d;
u_int pktlen, slen;
int gottime;
+#ifdef FFCLOCK
+ ffcounter ffcount;
+#endif
/* Skip outgoing duplicate packets. */
if ((m->m_flags & M_PROMISC) != 0 && m->m_pkthdr.rcvif == NULL) {
@@ -1948,12 +2044,24 @@ bpf_mtap2(struct bpf_if *bp, void *data, u_int dlen, struct mbuf *m)
if (slen != 0) {
d->bd_fcount++;
if (gottime < bpf_ts_quality(d->bd_tstamp))
+ {
+#ifdef FFCLOCK
+ gottime = bpf_gettime(&bt, &ffcount,
+ d->bd_tstamp, m);
+#else
gottime = bpf_gettime(&bt, d->bd_tstamp, m);
+#endif
+ }
#ifdef MAC
if (mac_bpfdesc_check_receive(d, bp->bif_ifp) == 0)
#endif
+#ifdef FFCLOCK
+ catchpacket(d, (u_char *)m, pktlen, slen,
+ bpf_append_mbuf, &bt, &ffcount);
+#else
catchpacket(d, (u_char *)&mb, pktlen, slen,
bpf_append_mbuf, &bt);
+#endif
}
BPFD_UNLOCK(d);
}
@@ -2002,11 +2110,17 @@ bpf_bintime2ts(struct bintime *bt, struct bpf_ts *ts, int tstype)
struct timeval tsm;
struct timespec tsn;
- if ((tstype & BPF_T_MONOTONIC) == 0) {
- bt2 = *bt;
- bintime_add(&bt2, &boottimebin);
- bt = &bt2;
+#ifdef FFCLOCK
+ if ((tstype & BPF_T_FFCLOCK) == 0) {
+#endif
+ if ((tstype & BPF_T_MONOTONIC) == 0) {
+ bt2 = *bt;
+ bintime_add(&bt2, &boottimebin);
+ bt = &bt2;
+ }
+#ifdef FFCLOCK
}
+#endif
switch (BPF_T_FORMAT(tstype)) {
case BPF_T_MICROTIME:
bintime2timeval(bt, &tsm);
@@ -2032,10 +2146,17 @@ bpf_bintime2ts(struct bintime *bt, struct bpf_ts *ts, int tstype)
* bpf_append_mbuf is passed in to copy mbuf chains. In the latter case,
* pkt is really an mbuf.
*/
+#ifdef FFCLOCK
+static void
+catchpacket(struct bpf_d *d, u_char *pkt, unsigned int pktlen,
+ unsigned int snaplen, void (*cpfn)(struct bpf_d *, caddr_t, unsigned int,
+ void *, unsigned int), struct bintime *bt, ffcounter *ffcount)
+#else
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),
struct bintime *bt)
+#endif
{
struct bpf_xhdr hdr;
#ifndef BURN_BRIDGES
@@ -2123,6 +2244,9 @@ catchpacket(struct bpf_d *d, u_char *pkt, u_int pktlen, u_int snaplen,
if (d->bd_compat32) {
bzero(&hdr32_old, sizeof(hdr32_old));
if (do_timestamp) {
+#ifdef FFCLOCK
+ hdr32_old.ffcount_stamp = *ffcount;
+#endif
hdr32_old.bh_tstamp.tv_sec = ts.bt_sec;
hdr32_old.bh_tstamp.tv_usec = ts.bt_frac;
}
@@ -2136,6 +2260,9 @@ catchpacket(struct bpf_d *d, u_char *pkt, u_int pktlen, u_int snaplen,
#endif
bzero(&hdr_old, sizeof(hdr_old));
if (do_timestamp) {
+#ifdef FFCLOCK
+ hdr_old.ffcount_stamp = *ffcount;
+#endif
hdr_old.bh_tstamp.tv_sec = ts.bt_sec;
hdr_old.bh_tstamp.tv_usec = ts.bt_frac;
}
@@ -2154,7 +2281,12 @@ catchpacket(struct bpf_d *d, u_char *pkt, u_int pktlen, u_int snaplen,
*/
bzero(&hdr, sizeof(hdr));
if (do_timestamp)
+ {
+#ifdef FFCLOCK
+ hdr.ffcount_stamp = *ffcount;
+#endif
bpf_bintime2ts(bt, &hdr.bh_tstamp, tstype);
+ }
hdr.bh_datalen = pktlen;
hdr.bh_hdrlen = hdrlen;
hdr.bh_caplen = caplen;
diff --git a/sys/net/bpf.h b/sys/net/bpf.h
index d4c369d..8a80514 100644
--- a/sys/net/bpf.h
+++ b/sys/net/bpf.h
@@ -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 FreeBSD Foundation
+ * 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:
@@ -170,11 +175,21 @@ enum bpf_direction {
#define BPF_T_MONOTONIC 0x0200
#define BPF_T_MONOTONIC_FAST (BPF_T_FAST | BPF_T_MONOTONIC)
#define BPF_T_FLAG_MASK 0x0300
+#ifdef FFCLOCK
+#define BPF_T_FFCLOCK 0x8000
+#define BPF_T_CLOCK_MASK 0x8000
+#endif
#define BPF_T_FORMAT(t) ((t) & BPF_T_FORMAT_MASK)
#define BPF_T_FLAG(t) ((t) & BPF_T_FLAG_MASK)
+#ifdef FFCLOCK
+#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 | BPF_T_CLOCK_MASK)) == 0))
+#else
#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))
+#endif
#define BPF_T_MICROTIME_FAST (BPF_T_MICROTIME | BPF_T_FAST)
#define BPF_T_NANOTIME_FAST (BPF_T_NANOTIME | BPF_T_FAST)
@@ -199,6 +214,9 @@ struct bpf_xhdr {
bpf_u_int32 bh_datalen; /* original length of packet */
u_short bh_hdrlen; /* length of bpf header (this struct
plus alignment padding) */
+#ifdef FFCLOCK
+ ffcounter ffcount_stamp; /* feed-forward counter timestamp */
+#endif
};
/* Obsolete */
struct bpf_hdr {
@@ -207,6 +225,9 @@ struct bpf_hdr {
bpf_u_int32 bh_datalen; /* original length of packet */
u_short bh_hdrlen; /* length of bpf header (this struct
plus alignment padding) */
+#ifdef FFCLOCK
+ ffcounter ffcount_stamp; /* feed-forward counter timestamp */
+#endif
};
#ifdef _KERNEL
#define MTAG_BPF 0x627066
OpenPOWER on IntegriCloud