For "dump (all|updates) (in|out)" it totally makes sense to use the extended timestamp format that includes microseconds as well. This way it is better visible when updates got processed. Table dumps are not affected since there the timestamp is not that useful.
bgpdump shows now the time with microseconds: TIME: 07/16/18 20:26:15.384935 TYPE: BGP4MP_ET/MESSAGE/Keepalive FROM: 10.82.41.92 AS196618 TO: 62.48.0.253 AS8271 TIME: 07/16/18 20:26:15.384949 TYPE: BGP4MP_ET/STATE_CHANGE PEER: 10.82.41.92 AS196618 STATE: Opensent/Openconfirm TIME: 07/16/18 20:26:15.386018 TYPE: BGP4MP_ET/STATE_CHANGE PEER: 10.82.41.92 AS196618 STATE: Openconfirm/Established TIME: 07/16/18 20:26:15.386217 TYPE: BGP4MP_ET/MESSAGE/Update FROM: 10.82.41.92 AS196618 TO: 62.48.0.253 AS8271 ... and bgpctl will do the same soon :) -- :wq Claudio Index: mrt.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/mrt.c,v retrieving revision 1.84 diff -u -p -r1.84 mrt.c --- mrt.c 5 Feb 2018 03:55:54 -0000 1.84 +++ mrt.c 16 Jul 2018 20:25:45 -0000 @@ -105,7 +105,7 @@ mrt_dump_bgp_msg(struct mrt *mrt, void * if (mrt->type == MRT_ALL_IN || mrt->type == MRT_UPDATE_IN) incoming = 1; - if (mrt_dump_hdr_se(&buf, peer, MSG_PROTOCOL_BGP4MP, subtype, + if (mrt_dump_hdr_se(&buf, peer, MSG_PROTOCOL_BGP4MP_ET, subtype, pkglen, incoming) == -1) return; @@ -128,7 +128,7 @@ mrt_dump_state(struct mrt *mrt, u_int16_ if (peer->capa.neg.as4byte) subtype = BGP4MP_STATE_CHANGE_AS4; - if (mrt_dump_hdr_se(&buf, peer, MSG_PROTOCOL_BGP4MP, subtype, + if (mrt_dump_hdr_se(&buf, peer, MSG_PROTOCOL_BGP4MP_ET, subtype, 2 * sizeof(short), 0) == -1) return; @@ -684,17 +684,17 @@ int mrt_dump_hdr_se(struct ibuf ** bp, struct peer *peer, u_int16_t type, u_int16_t subtype, u_int32_t len, int swap) { - time_t now; + struct timespec time; - if ((*bp = ibuf_dynamic(MRT_HEADER_SIZE, MRT_HEADER_SIZE + + if ((*bp = ibuf_dynamic(MRT_ET_HEADER_SIZE, MRT_ET_HEADER_SIZE + MRT_BGP4MP_AS4_IPv6_HEADER_SIZE + len)) == NULL) { log_warn("mrt_dump_hdr_se: ibuf_dynamic error"); return (-1); } - now = time(NULL); + clock_gettime(CLOCK_REALTIME, &time); - DUMP_LONG(*bp, now); + DUMP_LONG(*bp, time.tv_sec); DUMP_SHORT(*bp, type); DUMP_SHORT(*bp, subtype); @@ -702,16 +702,16 @@ mrt_dump_hdr_se(struct ibuf ** bp, struc case AF_INET: if (subtype == BGP4MP_STATE_CHANGE_AS4 || subtype == BGP4MP_MESSAGE_AS4) - len += MRT_BGP4MP_AS4_IPv4_HEADER_SIZE; + len += MRT_BGP4MP_ET_AS4_IPv4_HEADER_SIZE; else - len += MRT_BGP4MP_IPv4_HEADER_SIZE; + len += MRT_BGP4MP_ET_IPv4_HEADER_SIZE; break; case AF_INET6: if (subtype == BGP4MP_STATE_CHANGE_AS4 || subtype == BGP4MP_MESSAGE_AS4) - len += MRT_BGP4MP_AS4_IPv6_HEADER_SIZE; + len += MRT_BGP4MP_ET_AS4_IPv6_HEADER_SIZE; else - len += MRT_BGP4MP_IPv6_HEADER_SIZE; + len += MRT_BGP4MP_ET_IPv6_HEADER_SIZE; break; case 0: goto fail; @@ -721,6 +721,8 @@ mrt_dump_hdr_se(struct ibuf ** bp, struc } DUMP_LONG(*bp, len); + /* milisecond field use by the _ET format */ + DUMP_LONG(*bp, time.tv_nsec / 1000); if (subtype == BGP4MP_STATE_CHANGE_AS4 || subtype == BGP4MP_MESSAGE_AS4) { Index: mrt.h =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/mrt.h,v retrieving revision 1.31 diff -u -p -r1.31 mrt.h --- mrt.h 19 Sep 2011 11:19:32 -0000 1.31 +++ mrt.h 13 Jul 2018 13:54:07 -0000 @@ -39,6 +39,7 @@ * length field. Which is accounted in the length field. */ #define MRT_HEADER_SIZE 12 +#define MRT_ET_HEADER_SIZE 16 struct mrt_hdr { u_int32_t timestamp; @@ -87,11 +88,15 @@ enum MRT_BGP4MP_SUBTYPES { }; /* size of the BGP4MP headers without payload */ -#define MRT_BGP4MP_IPv4_HEADER_SIZE 16 -#define MRT_BGP4MP_IPv6_HEADER_SIZE 40 +#define MRT_BGP4MP_IPv4_HEADER_SIZE 16 +#define MRT_BGP4MP_IPv6_HEADER_SIZE 40 +#define MRT_BGP4MP_ET_IPv4_HEADER_SIZE 20 +#define MRT_BGP4MP_ET_IPv6_HEADER_SIZE 44 /* 4-byte AS variants of the previous */ -#define MRT_BGP4MP_AS4_IPv4_HEADER_SIZE 20 -#define MRT_BGP4MP_AS4_IPv6_HEADER_SIZE 44 +#define MRT_BGP4MP_AS4_IPv4_HEADER_SIZE 20 +#define MRT_BGP4MP_AS4_IPv6_HEADER_SIZE 44 +#define MRT_BGP4MP_ET_AS4_IPv4_HEADER_SIZE 24 +#define MRT_BGP4MP_ET_AS4_IPv6_HEADER_SIZE 48 /* If the type is PROTOCOL_BGP4MP and the subtype is either BGP4MP_STATE_CHANGE * or BGP4MP_MESSAGE the message consists of a common header plus the payload.