From: Vivien Didelot Date: Tue, 9 Jun 2020 19:07:19 +0000 (-0400) Subject: net/pcap: support Tx nanosecond timestamps X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=a7d42145cc187adaa336e48f1bdd83a6f5673773;p=dpdk.git net/pcap: support Tx nanosecond timestamps When capturing packets into a PCAP file, DPDK currently uses microseconds for the timestamps. But libpcap supports interpreting tv_usec as nanoseconds depending on the file timestamp precision, as of commit ba89e4a18e8b ("Make timestamps precision configurable"). To support this, use PCAP_TSTAMP_PRECISION_NANO when creating the empty PCAP file as specified by PCAP_OPEN_DEAD(3PCAP) and implement nanosecond timeval addition. This also ensures that the precision reported by capinfos is nanoseconds (9). Note that NSEC_PER_SEC is defined as 1000000000L instead of 1e9 since the latter might be interpreted as floating point. Signed-off-by: Vivien Didelot Acked-by: Ferruh Yigit --- diff --git a/doc/guides/rel_notes/release_20_08.rst b/doc/guides/rel_notes/release_20_08.rst index 86d2402130..f5a22bc4b9 100644 --- a/doc/guides/rel_notes/release_20_08.rst +++ b/doc/guides/rel_notes/release_20_08.rst @@ -56,6 +56,12 @@ New Features Also, make sure to start the actual text at the margin. ========================================================= +* **Updated PCAP driver.** + + Updated PCAP driver with new features and improvements, including: + + * Support software Tx nanosecond timestamps precision. + * **Updated Mellanox mlx5 driver.** Updated Mellanox mlx5 driver with new features and improvements, including: diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c index b4c79d174f..13a3d0ac7a 100644 --- a/drivers/net/pcap/rte_eth_pcap.c +++ b/drivers/net/pcap/rte_eth_pcap.c @@ -287,6 +287,8 @@ eth_null_rx(void *queue __rte_unused, return 0; } +#define NSEC_PER_SEC 1000000000L + static inline void calculate_timestamp(struct timeval *ts) { uint64_t cycles; @@ -294,8 +296,14 @@ calculate_timestamp(struct timeval *ts) { cycles = rte_get_timer_cycles() - start_cycles; cur_time.tv_sec = cycles / hz; - cur_time.tv_usec = (cycles % hz) * 1e6 / hz; - timeradd(&start_time, &cur_time, ts); + cur_time.tv_usec = (cycles % hz) * NSEC_PER_SEC / hz; + + ts->tv_sec = start_time.tv_sec + cur_time.tv_sec; + ts->tv_usec = start_time.tv_usec + cur_time.tv_usec; + if (ts->tv_usec >= NSEC_PER_SEC) { + ts->tv_usec -= NSEC_PER_SEC; + ts->tv_sec += 1; + } } /* @@ -475,7 +483,8 @@ open_single_tx_pcap(const char *pcap_filename, pcap_dumper_t **dumper) * with pcap_dump_open(). We create big enough an Ethernet * pcap holder. */ - tx_pcap = pcap_open_dead(DLT_EN10MB, RTE_ETH_PCAP_SNAPSHOT_LEN); + tx_pcap = pcap_open_dead_with_tstamp_precision(DLT_EN10MB, + RTE_ETH_PCAP_SNAPSHOT_LEN, PCAP_TSTAMP_PRECISION_NANO); if (tx_pcap == NULL) { PMD_LOG(ERR, "Couldn't create dead pcap"); return -1;