Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 Nov 2011 04:17:24 +0000 (UTC)
From:      Lawrence Stewart <lstewart@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r227778 - head/sys/net
Message-ID:  <201111210417.pAL4HOdi023556@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: lstewart
Date: Mon Nov 21 04:17:24 2011
New Revision: 227778
URL: http://svn.freebsd.org/changeset/base/227778

Log:
  - 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)

Modified:
  head/sys/net/bpf.c
  head/sys/net/bpf.h

Modified: head/sys/net/bpf.c
==============================================================================
--- head/sys/net/bpf.c	Mon Nov 21 02:03:18 2011	(r227777)
+++ head/sys/net/bpf.c	Mon Nov 21 04:17:24 2011	(r227778)
@@ -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 *, str
 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_
     &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
 	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 tsty
 			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, 
 #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, 
 		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 
 #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 
 		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,
 	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,
 		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, struc
 	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, struc
  * 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
 		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
 #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
 	 */
 	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;

Modified: head/sys/net/bpf.h
==============================================================================
--- head/sys/net/bpf.h	Mon Nov 21 02:03:18 2011	(r227777)
+++ head/sys/net/bpf.h	Mon Nov 21 04:17:24 2011	(r227778)
@@ -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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201111210417.pAL4HOdi023556>