diff options
Diffstat (limited to 'tools/testing/selftests/bpf/prog_tests')
| -rw-r--r-- | tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c | 44 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/prog_tests/check_mtu.c | 4 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/prog_tests/fexit_sleep.c | 82 | 
3 files changed, 130 insertions, 0 deletions
diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c b/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c index 37c5494a0381..e25917f04602 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c @@ -6,6 +6,7 @@  #include <test_progs.h>  #include "bpf_dctcp.skel.h"  #include "bpf_cubic.skel.h" +#include "bpf_tcp_nogpl.skel.h"  #define min(a, b) ((a) < (b) ? (a) : (b)) @@ -227,10 +228,53 @@ static void test_dctcp(void)  	bpf_dctcp__destroy(dctcp_skel);  } +static char *err_str; +static bool found; + +static int libbpf_debug_print(enum libbpf_print_level level, +			      const char *format, va_list args) +{ +	char *log_buf; + +	if (level != LIBBPF_WARN || +	    strcmp(format, "libbpf: \n%s\n")) { +		vprintf(format, args); +		return 0; +	} + +	log_buf = va_arg(args, char *); +	if (!log_buf) +		goto out; +	if (err_str && strstr(log_buf, err_str) != NULL) +		found = true; +out: +	printf(format, log_buf); +	return 0; +} + +static void test_invalid_license(void) +{ +	libbpf_print_fn_t old_print_fn; +	struct bpf_tcp_nogpl *skel; + +	err_str = "struct ops programs must have a GPL compatible license"; +	found = false; +	old_print_fn = libbpf_set_print(libbpf_debug_print); + +	skel = bpf_tcp_nogpl__open_and_load(); +	ASSERT_NULL(skel, "bpf_tcp_nogpl"); +	ASSERT_EQ(found, true, "expected_err_msg"); + +	bpf_tcp_nogpl__destroy(skel); +	libbpf_set_print(old_print_fn); +} +  void test_bpf_tcp_ca(void)  {  	if (test__start_subtest("dctcp"))  		test_dctcp();  	if (test__start_subtest("cubic"))  		test_cubic(); +	if (test__start_subtest("invalid_license")) +		test_invalid_license();  } diff --git a/tools/testing/selftests/bpf/prog_tests/check_mtu.c b/tools/testing/selftests/bpf/prog_tests/check_mtu.c index 36af1c138faf..b62a39315336 100644 --- a/tools/testing/selftests/bpf/prog_tests/check_mtu.c +++ b/tools/testing/selftests/bpf/prog_tests/check_mtu.c @@ -128,6 +128,8 @@ static void test_check_mtu_xdp(__u32 mtu, __u32 ifindex)  	test_check_mtu_run_xdp(skel, skel->progs.xdp_use_helper, mtu);  	test_check_mtu_run_xdp(skel, skel->progs.xdp_exceed_mtu, mtu);  	test_check_mtu_run_xdp(skel, skel->progs.xdp_minus_delta, mtu); +	test_check_mtu_run_xdp(skel, skel->progs.xdp_input_len, mtu); +	test_check_mtu_run_xdp(skel, skel->progs.xdp_input_len_exceed, mtu);  cleanup:  	test_check_mtu__destroy(skel); @@ -187,6 +189,8 @@ static void test_check_mtu_tc(__u32 mtu, __u32 ifindex)  	test_check_mtu_run_tc(skel, skel->progs.tc_exceed_mtu, mtu);  	test_check_mtu_run_tc(skel, skel->progs.tc_exceed_mtu_da, mtu);  	test_check_mtu_run_tc(skel, skel->progs.tc_minus_delta, mtu); +	test_check_mtu_run_tc(skel, skel->progs.tc_input_len, mtu); +	test_check_mtu_run_tc(skel, skel->progs.tc_input_len_exceed, mtu);  cleanup:  	test_check_mtu__destroy(skel);  } diff --git a/tools/testing/selftests/bpf/prog_tests/fexit_sleep.c b/tools/testing/selftests/bpf/prog_tests/fexit_sleep.c new file mode 100644 index 000000000000..6c4d42a2386f --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/fexit_sleep.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2021 Facebook */ +#define _GNU_SOURCE +#include <sched.h> +#include <test_progs.h> +#include <time.h> +#include <sys/mman.h> +#include <sys/syscall.h> +#include "fexit_sleep.skel.h" + +static int do_sleep(void *skel) +{ +	struct fexit_sleep *fexit_skel = skel; +	struct timespec ts1 = { .tv_nsec = 1 }; +	struct timespec ts2 = { .tv_sec = 10 }; + +	fexit_skel->bss->pid = getpid(); +	(void)syscall(__NR_nanosleep, &ts1, NULL); +	(void)syscall(__NR_nanosleep, &ts2, NULL); +	return 0; +} + +#define STACK_SIZE (1024 * 1024) +static char child_stack[STACK_SIZE]; + +void test_fexit_sleep(void) +{ +	struct fexit_sleep *fexit_skel = NULL; +	int wstatus, duration = 0; +	pid_t cpid; +	int err, fexit_cnt; + +	fexit_skel = fexit_sleep__open_and_load(); +	if (CHECK(!fexit_skel, "fexit_skel_load", "fexit skeleton failed\n")) +		goto cleanup; + +	err = fexit_sleep__attach(fexit_skel); +	if (CHECK(err, "fexit_attach", "fexit attach failed: %d\n", err)) +		goto cleanup; + +	cpid = clone(do_sleep, child_stack + STACK_SIZE, CLONE_FILES | SIGCHLD, fexit_skel); +	if (CHECK(cpid == -1, "clone", strerror(errno))) +		goto cleanup; + +	/* wait until first sys_nanosleep ends and second sys_nanosleep starts */ +	while (READ_ONCE(fexit_skel->bss->fentry_cnt) != 2); +	fexit_cnt = READ_ONCE(fexit_skel->bss->fexit_cnt); +	if (CHECK(fexit_cnt != 1, "fexit_cnt", "%d", fexit_cnt)) +		goto cleanup; + +	/* close progs and detach them. That will trigger two nop5->jmp5 rewrites +	 * in the trampolines to skip nanosleep_fexit prog. +	 * The nanosleep_fentry prog will get detached first. +	 * The nanosleep_fexit prog will get detached second. +	 * Detaching will trigger freeing of both progs JITed images. +	 * There will be two dying bpf_tramp_image-s, but only the initial +	 * bpf_tramp_image (with both _fentry and _fexit progs will be stuck +	 * waiting for percpu_ref_kill to confirm). The other one +	 * will be freed quickly. +	 */ +	close(bpf_program__fd(fexit_skel->progs.nanosleep_fentry)); +	close(bpf_program__fd(fexit_skel->progs.nanosleep_fexit)); +	fexit_sleep__detach(fexit_skel); + +	/* kill the thread to unwind sys_nanosleep stack through the trampoline */ +	kill(cpid, 9); + +	if (CHECK(waitpid(cpid, &wstatus, 0) == -1, "waitpid", strerror(errno))) +		goto cleanup; +	if (CHECK(WEXITSTATUS(wstatus) != 0, "exitstatus", "failed")) +		goto cleanup; + +	/* The bypassed nanosleep_fexit prog shouldn't have executed. +	 * Unlike progs the maps were not freed and directly accessible. +	 */ +	fexit_cnt = READ_ONCE(fexit_skel->bss->fexit_cnt); +	if (CHECK(fexit_cnt != 1, "fexit_cnt", "%d", fexit_cnt)) +		goto cleanup; + +cleanup: +	fexit_sleep__destroy(fexit_skel); +}  |