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
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to