Re: bgpd switch mrt format to extended timestamp

2018-07-16 Thread Sebastian Benoit
ok benno@

Claudio Jeker(cje...@diehard.n-r-g.com) on 2018.07.16 22:33:17 +0200:
> 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 -   1.84
> +++ mrt.c 16 Jul 2018 20:25:45 -
> @@ -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(, peer, MSG_PROTOCOL_BGP4MP, subtype,
> + if (mrt_dump_hdr_se(, 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(, peer, MSG_PROTOCOL_BGP4MP, subtype,
> + if (mrt_dump_hdr_se(, 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, );
>  
> - 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 -  1.31
> +++ mrt.h 13 Jul 2018 13:54:07 -
> @@ -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
> 

bgpd switch mrt format to extended timestamp

2018-07-16 Thread Claudio Jeker
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 -   1.84
+++ mrt.c   16 Jul 2018 20:25:45 -
@@ -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(, peer, MSG_PROTOCOL_BGP4MP, subtype,
+   if (mrt_dump_hdr_se(, 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(, peer, MSG_PROTOCOL_BGP4MP, subtype,
+   if (mrt_dump_hdr_se(, 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, );
 
-   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 -  1.31
+++ mrt.h   13 Jul 2018 13:54:07 -
@@ -39,6 +39,7 @@
  * length field. Which is accounted in the length field.
  */
 #define MRT_HEADER_SIZE12
+#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_SIZE16
-#define MRT_BGP4MP_IPv6_HEADER_SIZE40
+#define MRT_BGP4MP_IPv4_HEADER_SIZE16
+#define MRT_BGP4MP_IPv6_HEADER_SIZE40
+#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_SIZE20
-#define MRT_BGP4MP_AS4_IPv6_HEADER_SIZE44
+#define MRT_BGP4MP_AS4_IPv4_HEADER_SIZE20
+#define MRT_BGP4MP_AS4_IPv6_HEADER_SIZE44
+#define MRT_BGP4MP_ET_AS4_IPv4_HEADER_SIZE 24
+#define