1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (C) 2022 Linutronix GmbH */ 3 4 #include <test_progs.h> 5 #include <network_helpers.h> 6 7 #include "test_time_tai.skel.h" 8 9 #include <time.h> 10 #include <stdint.h> 11 12 #define TAI_THRESHOLD 1000000000ULL /* 1s */ 13 #define NSEC_PER_SEC 1000000000ULL 14 15 static __u64 ts_to_ns(const struct timespec *ts) 16 { 17 return ts->tv_sec * NSEC_PER_SEC + ts->tv_nsec; 18 } 19 20 void test_time_tai(void) 21 { 22 struct __sk_buff skb = { 23 .cb[0] = 0, 24 .cb[1] = 0, 25 .tstamp = 0, 26 }; 27 LIBBPF_OPTS(bpf_test_run_opts, topts, 28 .data_in = &pkt_v4, 29 .data_size_in = sizeof(pkt_v4), 30 .ctx_in = &skb, 31 .ctx_size_in = sizeof(skb), 32 .ctx_out = &skb, 33 .ctx_size_out = sizeof(skb), 34 ); 35 struct test_time_tai *skel; 36 struct timespec now_tai; 37 __u64 ts1, ts2, now; 38 int ret, prog_fd; 39 40 /* Open and load */ 41 skel = test_time_tai__open_and_load(); 42 if (!ASSERT_OK_PTR(skel, "tai_open")) 43 return; 44 45 /* Run test program */ 46 prog_fd = bpf_program__fd(skel->progs.time_tai); 47 ret = bpf_prog_test_run_opts(prog_fd, &topts); 48 ASSERT_OK(ret, "test_run"); 49 50 /* Retrieve generated TAI timestamps */ 51 ts1 = skb.tstamp; 52 ts2 = skb.cb[0] | ((__u64)skb.cb[1] << 32); 53 54 /* TAI != 0 */ 55 ASSERT_NEQ(ts1, 0, "tai_ts1"); 56 ASSERT_NEQ(ts2, 0, "tai_ts2"); 57 58 /* TAI is moving forward only */ 59 ASSERT_GE(ts2, ts1, "tai_forward"); 60 61 /* Check for future */ 62 ret = clock_gettime(CLOCK_TAI, &now_tai); 63 ASSERT_EQ(ret, 0, "tai_gettime"); 64 now = ts_to_ns(&now_tai); 65 66 ASSERT_TRUE(now > ts1, "tai_future_ts1"); 67 ASSERT_TRUE(now > ts2, "tai_future_ts2"); 68 69 /* Check for reasonable range */ 70 ASSERT_TRUE(now - ts1 < TAI_THRESHOLD, "tai_range_ts1"); 71 ASSERT_TRUE(now - ts2 < TAI_THRESHOLD, "tai_range_ts2"); 72 73 test_time_tai__destroy(skel); 74 } 75