From mboxrd@z Thu Jan 1 00:00:00 1970 From: Willem de Bruijn Subject: [PATCH net-next RFC] selftests: test timestamps in psock_tpacket Date: Wed, 29 Nov 2017 20:52:07 -0500 Message-ID: <20171130015207.43554-1-willemdebruijn.kernel@gmail.com> References: Cc: arnd@arndb.de, Willem de Bruijn To: netdev@vger.kernel.org Return-path: Received: from mail-yw0-f171.google.com ([209.85.161.171]:33617 "EHLO mail-yw0-f171.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753002AbdK3BwM (ORCPT ); Wed, 29 Nov 2017 20:52:12 -0500 Received: by mail-yw0-f171.google.com with SMTP id k80so2153552ywe.0 for ; Wed, 29 Nov 2017 17:52:12 -0800 (PST) In-Reply-To: Sender: netdev-owner@vger.kernel.org List-ID: From: Willem de Bruijn Packet rings can return timestamps. Optionally test this path. Verify that the returned values are sane. Also test new timestamp modes skip and ns64. Signed-off-by: Willem de Bruijn --- tools/testing/selftests/net/psock_tpacket.c | 125 +++++++++++++++++++++++++++- 1 file changed, 124 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/psock_tpacket.c b/tools/testing/selftests/net/psock_tpacket.c index 7f6cd9fdacf3..5af11016a5de 100644 --- a/tools/testing/selftests/net/psock_tpacket.c +++ b/tools/testing/selftests/net/psock_tpacket.c @@ -36,6 +36,7 @@ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. */ +#include #include #include #include @@ -57,6 +58,7 @@ #include #include #include +#include #include "psock_lib.h" @@ -75,6 +77,19 @@ #define NUM_PACKETS 100 #define ALIGN_8(x) (((x) + 8 - 1) & ~(8 - 1)) +const uint64_t tstamp_bound_ns64 = 1000UL * 1000 * 1000; + +enum cfg_tstamp_type { + tstype_none, + tstype_default, + tstype_skip, + tstype_ns64 +}; + +static enum cfg_tstamp_type cfg_tstamp; + +static uint64_t tstamp_start_ns64; + struct ring { struct iovec *rd; uint8_t *mm_space; @@ -150,6 +165,43 @@ static void test_payload(void *pay, size_t len) } } +static void test_tstamp(uint32_t sec, uint32_t nsec) +{ + uint64_t tstamp_ns64; + + if (!cfg_tstamp) + return; + + if (cfg_tstamp == tstype_skip) { + if (sec || nsec) { + fprintf(stderr, "%s: unexpected tstamp %u:%u\n", + __func__, sec, nsec); + exit(1); + } + return; + } + + if (cfg_tstamp == tstype_ns64) + tstamp_ns64 = (((uint64_t) sec) << 32) | nsec; + else + tstamp_ns64 = (sec * 1000UL * 1000 * 1000) + nsec; + + if (tstamp_ns64 < tstamp_start_ns64) { + fprintf(stderr, "tstamp: %lu lowerbound=%lu under=%lu\n", + tstamp_ns64, tstamp_start_ns64, + tstamp_start_ns64 - tstamp_ns64); + exit(1); + } + if (tstamp_ns64 > tstamp_start_ns64 + tstamp_bound_ns64) { + fprintf(stderr, "tstamp: %lu upperbound=%lu over=%lu\n", + tstamp_ns64, + tstamp_start_ns64 + tstamp_bound_ns64, + tstamp_ns64 - (tstamp_start_ns64 + + tstamp_bound_ns64)); + exit(1); + } +} + static void create_payload(void *pay, size_t *len) { int i; @@ -256,12 +308,18 @@ static void walk_v1_v2_rx(int sock, struct ring *ring) case TPACKET_V1: test_payload((uint8_t *) ppd.raw + ppd.v1->tp_h.tp_mac, ppd.v1->tp_h.tp_snaplen); + test_tstamp(ppd.v1->tp_h.tp_sec, + cfg_tstamp == tstype_ns64 ? + ppd.v1->tp_h.tp_usec : + ppd.v1->tp_h.tp_usec * 1000); total_bytes += ppd.v1->tp_h.tp_snaplen; break; case TPACKET_V2: test_payload((uint8_t *) ppd.raw + ppd.v2->tp_h.tp_mac, ppd.v2->tp_h.tp_snaplen); + test_tstamp(ppd.v2->tp_h.tp_sec, + ppd.v2->tp_h.tp_nsec); total_bytes += ppd.v2->tp_h.tp_snaplen; break; } @@ -572,6 +630,7 @@ static void __v3_walk_block(struct block_desc *pbd, const int block_num) bytes_with_padding += ALIGN_8(ppd->tp_snaplen + ppd->tp_mac); test_payload((uint8_t *) ppd + ppd->tp_mac, ppd->tp_snaplen); + test_tstamp(ppd->tp_sec, ppd->tp_nsec); status_bar_update(); total_packets++; @@ -766,6 +825,38 @@ static void unmap_ring(int sock, struct ring *ring) free(ring->rd); } +static void setup_tstamp(int sock) +{ + struct timeval tv; + int one = 1; + + gettimeofday(&tv, NULL); + tstamp_start_ns64 = (tv.tv_sec * 1000UL * 1000 * 1000) + + (tv.tv_usec * 1000UL); + +/* TODO: remove before submit: temporary */ +#ifndef PACKET_SKIPTIMESTAMP +#define PACKET_SKIPTIMESTAMP 23 +#endif +#ifndef PACKET_TIMESTAMP_NS64 +#define PACKET_TIMESTAMP_NS64 24 +#endif + + if (cfg_tstamp == tstype_skip) { + if (setsockopt(sock, SOL_PACKET, PACKET_SKIPTIMESTAMP, + &one, sizeof(one))) { + perror("setsockopt skiptimestamp"); + exit(1); + } + } else if (cfg_tstamp == tstype_ns64) { + if (setsockopt(sock, SOL_PACKET, PACKET_TIMESTAMP_NS64, + &one, sizeof(one))) { + perror("setsockopt timestamp ns64"); + exit(1); + } + } +} + static int test_kernel_bit_width(void) { char in[512], *ptr; @@ -829,6 +920,8 @@ static int test_tpacket(int version, int type) } sock = pfsocket(version); + if (cfg_tstamp) + setup_tstamp(sock); memset(&ring, 0, sizeof(ring)); setup_ring(sock, &ring, version, type); mmap_ring(sock, &ring); @@ -841,10 +934,40 @@ static int test_tpacket(int version, int type) return 0; } -int main(void) +static void usage(const char *filepath) +{ + fprintf(stderr, "Usage: %s [-t ]\n", filepath); + exit(1); +} + +static void parse_opts(int argc, char **argv) +{ + int c; + + while ((c = getopt(argc, argv, "t:")) != -1) { + switch (c) { + case 't': + if (!strcmp(optarg, "default")) + cfg_tstamp = tstype_default; + else if (!strcmp(optarg, "skip")) + cfg_tstamp = tstype_skip; + else if (!strcmp(optarg, "ns64")) + cfg_tstamp = tstype_ns64; + else + usage(argv[0]); + break; + default: + usage(argv[0]); + } + } +} + +int main(int argc, char **argv) { int ret = 0; + parse_opts(argc, argv); + ret |= test_tpacket(TPACKET_V1, PACKET_RX_RING); ret |= test_tpacket(TPACKET_V1, PACKET_TX_RING); -- 2.15.0.531.g2ccb3012c9-goog