162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef __TEST_PROGS_H 362306a36Sopenharmony_ci#define __TEST_PROGS_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <stdio.h> 662306a36Sopenharmony_ci#include <unistd.h> 762306a36Sopenharmony_ci#include <errno.h> 862306a36Sopenharmony_ci#include <string.h> 962306a36Sopenharmony_ci#include <assert.h> 1062306a36Sopenharmony_ci#include <stdlib.h> 1162306a36Sopenharmony_ci#include <stdarg.h> 1262306a36Sopenharmony_ci#include <time.h> 1362306a36Sopenharmony_ci#include <signal.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include <linux/types.h> 1662306a36Sopenharmony_citypedef __u16 __sum16; 1762306a36Sopenharmony_ci#include <arpa/inet.h> 1862306a36Sopenharmony_ci#include <linux/if_ether.h> 1962306a36Sopenharmony_ci#include <linux/if_packet.h> 2062306a36Sopenharmony_ci#include <linux/ip.h> 2162306a36Sopenharmony_ci#include <linux/ipv6.h> 2262306a36Sopenharmony_ci#include <linux/filter.h> 2362306a36Sopenharmony_ci#include <linux/perf_event.h> 2462306a36Sopenharmony_ci#include <linux/socket.h> 2562306a36Sopenharmony_ci#include <linux/unistd.h> 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#include <sys/ioctl.h> 2862306a36Sopenharmony_ci#include <sys/wait.h> 2962306a36Sopenharmony_ci#include <sys/types.h> 3062306a36Sopenharmony_ci#include <sys/time.h> 3162306a36Sopenharmony_ci#include <sys/param.h> 3262306a36Sopenharmony_ci#include <fcntl.h> 3362306a36Sopenharmony_ci#include <pthread.h> 3462306a36Sopenharmony_ci#include <linux/bpf.h> 3562306a36Sopenharmony_ci#include <linux/err.h> 3662306a36Sopenharmony_ci#include <bpf/bpf.h> 3762306a36Sopenharmony_ci#include <bpf/libbpf.h> 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci#include "test_iptunnel_common.h" 4062306a36Sopenharmony_ci#include "bpf_util.h" 4162306a36Sopenharmony_ci#include <bpf/bpf_endian.h> 4262306a36Sopenharmony_ci#include "trace_helpers.h" 4362306a36Sopenharmony_ci#include "testing_helpers.h" 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_cienum verbosity { 4662306a36Sopenharmony_ci VERBOSE_NONE, 4762306a36Sopenharmony_ci VERBOSE_NORMAL, 4862306a36Sopenharmony_ci VERBOSE_VERY, 4962306a36Sopenharmony_ci VERBOSE_SUPER, 5062306a36Sopenharmony_ci}; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_cistruct test_filter { 5362306a36Sopenharmony_ci char *name; 5462306a36Sopenharmony_ci char **subtests; 5562306a36Sopenharmony_ci int subtest_cnt; 5662306a36Sopenharmony_ci}; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_cistruct test_filter_set { 5962306a36Sopenharmony_ci struct test_filter *tests; 6062306a36Sopenharmony_ci int cnt; 6162306a36Sopenharmony_ci}; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_cistruct test_selector { 6462306a36Sopenharmony_ci struct test_filter_set whitelist; 6562306a36Sopenharmony_ci struct test_filter_set blacklist; 6662306a36Sopenharmony_ci bool *num_set; 6762306a36Sopenharmony_ci int num_set_len; 6862306a36Sopenharmony_ci}; 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_cistruct subtest_state { 7162306a36Sopenharmony_ci char *name; 7262306a36Sopenharmony_ci size_t log_cnt; 7362306a36Sopenharmony_ci char *log_buf; 7462306a36Sopenharmony_ci int error_cnt; 7562306a36Sopenharmony_ci bool skipped; 7662306a36Sopenharmony_ci bool filtered; 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci FILE *stdout; 7962306a36Sopenharmony_ci}; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_cistruct test_state { 8262306a36Sopenharmony_ci bool tested; 8362306a36Sopenharmony_ci bool force_log; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci int error_cnt; 8662306a36Sopenharmony_ci int skip_cnt; 8762306a36Sopenharmony_ci int sub_succ_cnt; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci struct subtest_state *subtest_states; 9062306a36Sopenharmony_ci int subtest_num; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci size_t log_cnt; 9362306a36Sopenharmony_ci char *log_buf; 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci FILE *stdout; 9662306a36Sopenharmony_ci}; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_cistruct test_env { 9962306a36Sopenharmony_ci struct test_selector test_selector; 10062306a36Sopenharmony_ci struct test_selector subtest_selector; 10162306a36Sopenharmony_ci bool verifier_stats; 10262306a36Sopenharmony_ci bool debug; 10362306a36Sopenharmony_ci enum verbosity verbosity; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci bool jit_enabled; 10662306a36Sopenharmony_ci bool has_testmod; 10762306a36Sopenharmony_ci bool get_test_cnt; 10862306a36Sopenharmony_ci bool list_test_names; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci struct prog_test_def *test; /* current running test */ 11162306a36Sopenharmony_ci struct test_state *test_state; /* current running test state */ 11262306a36Sopenharmony_ci struct subtest_state *subtest_state; /* current running subtest state */ 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci FILE *stdout; 11562306a36Sopenharmony_ci FILE *stderr; 11662306a36Sopenharmony_ci int nr_cpus; 11762306a36Sopenharmony_ci FILE *json; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci int succ_cnt; /* successful tests */ 12062306a36Sopenharmony_ci int sub_succ_cnt; /* successful sub-tests */ 12162306a36Sopenharmony_ci int fail_cnt; /* total failed tests + sub-tests */ 12262306a36Sopenharmony_ci int skip_cnt; /* skipped tests */ 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci int saved_netns_fd; 12562306a36Sopenharmony_ci int workers; /* number of worker process */ 12662306a36Sopenharmony_ci int worker_id; /* id number of current worker, main process is -1 */ 12762306a36Sopenharmony_ci pid_t *worker_pids; /* array of worker pids */ 12862306a36Sopenharmony_ci int *worker_socks; /* array of worker socks */ 12962306a36Sopenharmony_ci int *worker_current_test; /* array of current running test for each worker */ 13062306a36Sopenharmony_ci}; 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci#define MAX_LOG_TRUNK_SIZE 8192 13362306a36Sopenharmony_ci#define MAX_SUBTEST_NAME 1024 13462306a36Sopenharmony_cienum msg_type { 13562306a36Sopenharmony_ci MSG_DO_TEST = 0, 13662306a36Sopenharmony_ci MSG_TEST_DONE = 1, 13762306a36Sopenharmony_ci MSG_TEST_LOG = 2, 13862306a36Sopenharmony_ci MSG_SUBTEST_DONE = 3, 13962306a36Sopenharmony_ci MSG_EXIT = 255, 14062306a36Sopenharmony_ci}; 14162306a36Sopenharmony_cistruct msg { 14262306a36Sopenharmony_ci enum msg_type type; 14362306a36Sopenharmony_ci union { 14462306a36Sopenharmony_ci struct { 14562306a36Sopenharmony_ci int num; 14662306a36Sopenharmony_ci } do_test; 14762306a36Sopenharmony_ci struct { 14862306a36Sopenharmony_ci int num; 14962306a36Sopenharmony_ci int sub_succ_cnt; 15062306a36Sopenharmony_ci int error_cnt; 15162306a36Sopenharmony_ci int skip_cnt; 15262306a36Sopenharmony_ci bool have_log; 15362306a36Sopenharmony_ci int subtest_num; 15462306a36Sopenharmony_ci } test_done; 15562306a36Sopenharmony_ci struct { 15662306a36Sopenharmony_ci char log_buf[MAX_LOG_TRUNK_SIZE + 1]; 15762306a36Sopenharmony_ci bool is_last; 15862306a36Sopenharmony_ci } test_log; 15962306a36Sopenharmony_ci struct { 16062306a36Sopenharmony_ci int num; 16162306a36Sopenharmony_ci char name[MAX_SUBTEST_NAME + 1]; 16262306a36Sopenharmony_ci int error_cnt; 16362306a36Sopenharmony_ci bool skipped; 16462306a36Sopenharmony_ci bool filtered; 16562306a36Sopenharmony_ci bool have_log; 16662306a36Sopenharmony_ci } subtest_done; 16762306a36Sopenharmony_ci }; 16862306a36Sopenharmony_ci}; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ciextern struct test_env env; 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_civoid test__force_log(void); 17362306a36Sopenharmony_cibool test__start_subtest(const char *name); 17462306a36Sopenharmony_civoid test__end_subtest(void); 17562306a36Sopenharmony_civoid test__skip(void); 17662306a36Sopenharmony_civoid test__fail(void); 17762306a36Sopenharmony_ciint test__join_cgroup(const char *path); 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci#define PRINT_FAIL(format...) \ 18062306a36Sopenharmony_ci ({ \ 18162306a36Sopenharmony_ci test__fail(); \ 18262306a36Sopenharmony_ci fprintf(stdout, "%s:FAIL:%d ", __func__, __LINE__); \ 18362306a36Sopenharmony_ci fprintf(stdout, ##format); \ 18462306a36Sopenharmony_ci }) 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci#define _CHECK(condition, tag, duration, format...) ({ \ 18762306a36Sopenharmony_ci int __ret = !!(condition); \ 18862306a36Sopenharmony_ci int __save_errno = errno; \ 18962306a36Sopenharmony_ci if (__ret) { \ 19062306a36Sopenharmony_ci test__fail(); \ 19162306a36Sopenharmony_ci fprintf(stdout, "%s:FAIL:%s ", __func__, tag); \ 19262306a36Sopenharmony_ci fprintf(stdout, ##format); \ 19362306a36Sopenharmony_ci } else { \ 19462306a36Sopenharmony_ci fprintf(stdout, "%s:PASS:%s %d nsec\n", \ 19562306a36Sopenharmony_ci __func__, tag, duration); \ 19662306a36Sopenharmony_ci } \ 19762306a36Sopenharmony_ci errno = __save_errno; \ 19862306a36Sopenharmony_ci __ret; \ 19962306a36Sopenharmony_ci}) 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci#define CHECK_FAIL(condition) ({ \ 20262306a36Sopenharmony_ci int __ret = !!(condition); \ 20362306a36Sopenharmony_ci int __save_errno = errno; \ 20462306a36Sopenharmony_ci if (__ret) { \ 20562306a36Sopenharmony_ci test__fail(); \ 20662306a36Sopenharmony_ci fprintf(stdout, "%s:FAIL:%d\n", __func__, __LINE__); \ 20762306a36Sopenharmony_ci } \ 20862306a36Sopenharmony_ci errno = __save_errno; \ 20962306a36Sopenharmony_ci __ret; \ 21062306a36Sopenharmony_ci}) 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci#define CHECK(condition, tag, format...) \ 21362306a36Sopenharmony_ci _CHECK(condition, tag, duration, format) 21462306a36Sopenharmony_ci#define CHECK_ATTR(condition, tag, format...) \ 21562306a36Sopenharmony_ci _CHECK(condition, tag, tattr.duration, format) 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci#define ASSERT_FAIL(fmt, args...) ({ \ 21862306a36Sopenharmony_ci static int duration = 0; \ 21962306a36Sopenharmony_ci CHECK(false, "", fmt"\n", ##args); \ 22062306a36Sopenharmony_ci false; \ 22162306a36Sopenharmony_ci}) 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci#define ASSERT_TRUE(actual, name) ({ \ 22462306a36Sopenharmony_ci static int duration = 0; \ 22562306a36Sopenharmony_ci bool ___ok = (actual); \ 22662306a36Sopenharmony_ci CHECK(!___ok, (name), "unexpected %s: got FALSE\n", (name)); \ 22762306a36Sopenharmony_ci ___ok; \ 22862306a36Sopenharmony_ci}) 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci#define ASSERT_FALSE(actual, name) ({ \ 23162306a36Sopenharmony_ci static int duration = 0; \ 23262306a36Sopenharmony_ci bool ___ok = !(actual); \ 23362306a36Sopenharmony_ci CHECK(!___ok, (name), "unexpected %s: got TRUE\n", (name)); \ 23462306a36Sopenharmony_ci ___ok; \ 23562306a36Sopenharmony_ci}) 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci#define ASSERT_EQ(actual, expected, name) ({ \ 23862306a36Sopenharmony_ci static int duration = 0; \ 23962306a36Sopenharmony_ci typeof(actual) ___act = (actual); \ 24062306a36Sopenharmony_ci typeof(expected) ___exp = (expected); \ 24162306a36Sopenharmony_ci bool ___ok = ___act == ___exp; \ 24262306a36Sopenharmony_ci CHECK(!___ok, (name), \ 24362306a36Sopenharmony_ci "unexpected %s: actual %lld != expected %lld\n", \ 24462306a36Sopenharmony_ci (name), (long long)(___act), (long long)(___exp)); \ 24562306a36Sopenharmony_ci ___ok; \ 24662306a36Sopenharmony_ci}) 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci#define ASSERT_NEQ(actual, expected, name) ({ \ 24962306a36Sopenharmony_ci static int duration = 0; \ 25062306a36Sopenharmony_ci typeof(actual) ___act = (actual); \ 25162306a36Sopenharmony_ci typeof(expected) ___exp = (expected); \ 25262306a36Sopenharmony_ci bool ___ok = ___act != ___exp; \ 25362306a36Sopenharmony_ci CHECK(!___ok, (name), \ 25462306a36Sopenharmony_ci "unexpected %s: actual %lld == expected %lld\n", \ 25562306a36Sopenharmony_ci (name), (long long)(___act), (long long)(___exp)); \ 25662306a36Sopenharmony_ci ___ok; \ 25762306a36Sopenharmony_ci}) 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci#define ASSERT_LT(actual, expected, name) ({ \ 26062306a36Sopenharmony_ci static int duration = 0; \ 26162306a36Sopenharmony_ci typeof(actual) ___act = (actual); \ 26262306a36Sopenharmony_ci typeof(expected) ___exp = (expected); \ 26362306a36Sopenharmony_ci bool ___ok = ___act < ___exp; \ 26462306a36Sopenharmony_ci CHECK(!___ok, (name), \ 26562306a36Sopenharmony_ci "unexpected %s: actual %lld >= expected %lld\n", \ 26662306a36Sopenharmony_ci (name), (long long)(___act), (long long)(___exp)); \ 26762306a36Sopenharmony_ci ___ok; \ 26862306a36Sopenharmony_ci}) 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci#define ASSERT_LE(actual, expected, name) ({ \ 27162306a36Sopenharmony_ci static int duration = 0; \ 27262306a36Sopenharmony_ci typeof(actual) ___act = (actual); \ 27362306a36Sopenharmony_ci typeof(expected) ___exp = (expected); \ 27462306a36Sopenharmony_ci bool ___ok = ___act <= ___exp; \ 27562306a36Sopenharmony_ci CHECK(!___ok, (name), \ 27662306a36Sopenharmony_ci "unexpected %s: actual %lld > expected %lld\n", \ 27762306a36Sopenharmony_ci (name), (long long)(___act), (long long)(___exp)); \ 27862306a36Sopenharmony_ci ___ok; \ 27962306a36Sopenharmony_ci}) 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci#define ASSERT_GT(actual, expected, name) ({ \ 28262306a36Sopenharmony_ci static int duration = 0; \ 28362306a36Sopenharmony_ci typeof(actual) ___act = (actual); \ 28462306a36Sopenharmony_ci typeof(expected) ___exp = (expected); \ 28562306a36Sopenharmony_ci bool ___ok = ___act > ___exp; \ 28662306a36Sopenharmony_ci CHECK(!___ok, (name), \ 28762306a36Sopenharmony_ci "unexpected %s: actual %lld <= expected %lld\n", \ 28862306a36Sopenharmony_ci (name), (long long)(___act), (long long)(___exp)); \ 28962306a36Sopenharmony_ci ___ok; \ 29062306a36Sopenharmony_ci}) 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci#define ASSERT_GE(actual, expected, name) ({ \ 29362306a36Sopenharmony_ci static int duration = 0; \ 29462306a36Sopenharmony_ci typeof(actual) ___act = (actual); \ 29562306a36Sopenharmony_ci typeof(expected) ___exp = (expected); \ 29662306a36Sopenharmony_ci bool ___ok = ___act >= ___exp; \ 29762306a36Sopenharmony_ci CHECK(!___ok, (name), \ 29862306a36Sopenharmony_ci "unexpected %s: actual %lld < expected %lld\n", \ 29962306a36Sopenharmony_ci (name), (long long)(___act), (long long)(___exp)); \ 30062306a36Sopenharmony_ci ___ok; \ 30162306a36Sopenharmony_ci}) 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci#define ASSERT_STREQ(actual, expected, name) ({ \ 30462306a36Sopenharmony_ci static int duration = 0; \ 30562306a36Sopenharmony_ci const char *___act = actual; \ 30662306a36Sopenharmony_ci const char *___exp = expected; \ 30762306a36Sopenharmony_ci bool ___ok = strcmp(___act, ___exp) == 0; \ 30862306a36Sopenharmony_ci CHECK(!___ok, (name), \ 30962306a36Sopenharmony_ci "unexpected %s: actual '%s' != expected '%s'\n", \ 31062306a36Sopenharmony_ci (name), ___act, ___exp); \ 31162306a36Sopenharmony_ci ___ok; \ 31262306a36Sopenharmony_ci}) 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci#define ASSERT_STRNEQ(actual, expected, len, name) ({ \ 31562306a36Sopenharmony_ci static int duration = 0; \ 31662306a36Sopenharmony_ci const char *___act = actual; \ 31762306a36Sopenharmony_ci const char *___exp = expected; \ 31862306a36Sopenharmony_ci int ___len = len; \ 31962306a36Sopenharmony_ci bool ___ok = strncmp(___act, ___exp, ___len) == 0; \ 32062306a36Sopenharmony_ci CHECK(!___ok, (name), \ 32162306a36Sopenharmony_ci "unexpected %s: actual '%.*s' != expected '%.*s'\n", \ 32262306a36Sopenharmony_ci (name), ___len, ___act, ___len, ___exp); \ 32362306a36Sopenharmony_ci ___ok; \ 32462306a36Sopenharmony_ci}) 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci#define ASSERT_HAS_SUBSTR(str, substr, name) ({ \ 32762306a36Sopenharmony_ci static int duration = 0; \ 32862306a36Sopenharmony_ci const char *___str = str; \ 32962306a36Sopenharmony_ci const char *___substr = substr; \ 33062306a36Sopenharmony_ci bool ___ok = strstr(___str, ___substr) != NULL; \ 33162306a36Sopenharmony_ci CHECK(!___ok, (name), \ 33262306a36Sopenharmony_ci "unexpected %s: '%s' is not a substring of '%s'\n", \ 33362306a36Sopenharmony_ci (name), ___substr, ___str); \ 33462306a36Sopenharmony_ci ___ok; \ 33562306a36Sopenharmony_ci}) 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci#define ASSERT_OK(res, name) ({ \ 33862306a36Sopenharmony_ci static int duration = 0; \ 33962306a36Sopenharmony_ci long long ___res = (res); \ 34062306a36Sopenharmony_ci bool ___ok = ___res == 0; \ 34162306a36Sopenharmony_ci CHECK(!___ok, (name), "unexpected error: %lld (errno %d)\n", \ 34262306a36Sopenharmony_ci ___res, errno); \ 34362306a36Sopenharmony_ci ___ok; \ 34462306a36Sopenharmony_ci}) 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci#define ASSERT_ERR(res, name) ({ \ 34762306a36Sopenharmony_ci static int duration = 0; \ 34862306a36Sopenharmony_ci long long ___res = (res); \ 34962306a36Sopenharmony_ci bool ___ok = ___res < 0; \ 35062306a36Sopenharmony_ci CHECK(!___ok, (name), "unexpected success: %lld\n", ___res); \ 35162306a36Sopenharmony_ci ___ok; \ 35262306a36Sopenharmony_ci}) 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci#define ASSERT_NULL(ptr, name) ({ \ 35562306a36Sopenharmony_ci static int duration = 0; \ 35662306a36Sopenharmony_ci const void *___res = (ptr); \ 35762306a36Sopenharmony_ci bool ___ok = !___res; \ 35862306a36Sopenharmony_ci CHECK(!___ok, (name), "unexpected pointer: %p\n", ___res); \ 35962306a36Sopenharmony_ci ___ok; \ 36062306a36Sopenharmony_ci}) 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci#define ASSERT_OK_PTR(ptr, name) ({ \ 36362306a36Sopenharmony_ci static int duration = 0; \ 36462306a36Sopenharmony_ci const void *___res = (ptr); \ 36562306a36Sopenharmony_ci int ___err = libbpf_get_error(___res); \ 36662306a36Sopenharmony_ci bool ___ok = ___err == 0; \ 36762306a36Sopenharmony_ci CHECK(!___ok, (name), "unexpected error: %d\n", ___err); \ 36862306a36Sopenharmony_ci ___ok; \ 36962306a36Sopenharmony_ci}) 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci#define ASSERT_ERR_PTR(ptr, name) ({ \ 37262306a36Sopenharmony_ci static int duration = 0; \ 37362306a36Sopenharmony_ci const void *___res = (ptr); \ 37462306a36Sopenharmony_ci int ___err = libbpf_get_error(___res); \ 37562306a36Sopenharmony_ci bool ___ok = ___err != 0; \ 37662306a36Sopenharmony_ci CHECK(!___ok, (name), "unexpected pointer: %p\n", ___res); \ 37762306a36Sopenharmony_ci ___ok; \ 37862306a36Sopenharmony_ci}) 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci#define SYS(goto_label, fmt, ...) \ 38162306a36Sopenharmony_ci ({ \ 38262306a36Sopenharmony_ci char cmd[1024]; \ 38362306a36Sopenharmony_ci snprintf(cmd, sizeof(cmd), fmt, ##__VA_ARGS__); \ 38462306a36Sopenharmony_ci if (!ASSERT_OK(system(cmd), cmd)) \ 38562306a36Sopenharmony_ci goto goto_label; \ 38662306a36Sopenharmony_ci }) 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci#define SYS_NOFAIL(fmt, ...) \ 38962306a36Sopenharmony_ci ({ \ 39062306a36Sopenharmony_ci char cmd[1024]; \ 39162306a36Sopenharmony_ci snprintf(cmd, sizeof(cmd), fmt, ##__VA_ARGS__); \ 39262306a36Sopenharmony_ci system(cmd); \ 39362306a36Sopenharmony_ci }) 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_cistatic inline __u64 ptr_to_u64(const void *ptr) 39662306a36Sopenharmony_ci{ 39762306a36Sopenharmony_ci return (__u64) (unsigned long) ptr; 39862306a36Sopenharmony_ci} 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_cistatic inline void *u64_to_ptr(__u64 ptr) 40162306a36Sopenharmony_ci{ 40262306a36Sopenharmony_ci return (void *) (unsigned long) ptr; 40362306a36Sopenharmony_ci} 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ciint bpf_find_map(const char *test, struct bpf_object *obj, const char *name); 40662306a36Sopenharmony_ciint compare_map_keys(int map1_fd, int map2_fd); 40762306a36Sopenharmony_ciint compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len); 40862306a36Sopenharmony_ciint trigger_module_test_read(int read_sz); 40962306a36Sopenharmony_ciint trigger_module_test_write(int write_sz); 41062306a36Sopenharmony_ciint write_sysctl(const char *sysctl, const char *value); 41162306a36Sopenharmony_ciint get_bpf_max_tramp_links_from(struct btf *btf); 41262306a36Sopenharmony_ciint get_bpf_max_tramp_links(void); 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci#ifdef __x86_64__ 41562306a36Sopenharmony_ci#define SYS_NANOSLEEP_KPROBE_NAME "__x64_sys_nanosleep" 41662306a36Sopenharmony_ci#elif defined(__s390x__) 41762306a36Sopenharmony_ci#define SYS_NANOSLEEP_KPROBE_NAME "__s390x_sys_nanosleep" 41862306a36Sopenharmony_ci#elif defined(__aarch64__) 41962306a36Sopenharmony_ci#define SYS_NANOSLEEP_KPROBE_NAME "__arm64_sys_nanosleep" 42062306a36Sopenharmony_ci#elif defined(__riscv) 42162306a36Sopenharmony_ci#define SYS_NANOSLEEP_KPROBE_NAME "__riscv_sys_nanosleep" 42262306a36Sopenharmony_ci#else 42362306a36Sopenharmony_ci#define SYS_NANOSLEEP_KPROBE_NAME "sys_nanosleep" 42462306a36Sopenharmony_ci#endif 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci#define BPF_TESTMOD_TEST_FILE "/sys/kernel/bpf_testmod" 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_citypedef int (*pre_execution_cb)(struct bpf_object *obj); 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_cistruct test_loader { 43162306a36Sopenharmony_ci char *log_buf; 43262306a36Sopenharmony_ci size_t log_buf_sz; 43362306a36Sopenharmony_ci size_t next_match_pos; 43462306a36Sopenharmony_ci pre_execution_cb pre_execution_cb; 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_ci struct bpf_object *obj; 43762306a36Sopenharmony_ci}; 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_cistatic inline void test_loader__set_pre_execution_cb(struct test_loader *tester, 44062306a36Sopenharmony_ci pre_execution_cb cb) 44162306a36Sopenharmony_ci{ 44262306a36Sopenharmony_ci tester->pre_execution_cb = cb; 44362306a36Sopenharmony_ci} 44462306a36Sopenharmony_ci 44562306a36Sopenharmony_citypedef const void *(*skel_elf_bytes_fn)(size_t *sz); 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ciextern void test_loader__run_subtests(struct test_loader *tester, 44862306a36Sopenharmony_ci const char *skel_name, 44962306a36Sopenharmony_ci skel_elf_bytes_fn elf_bytes_factory); 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_ciextern void test_loader_fini(struct test_loader *tester); 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_ci#define RUN_TESTS(skel) ({ \ 45462306a36Sopenharmony_ci struct test_loader tester = {}; \ 45562306a36Sopenharmony_ci \ 45662306a36Sopenharmony_ci test_loader__run_subtests(&tester, #skel, skel##__elf_bytes); \ 45762306a36Sopenharmony_ci test_loader_fini(&tester); \ 45862306a36Sopenharmony_ci}) 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci#endif /* __TEST_PROGS_H */ 461