mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-09-04 20:19:47 +08:00 
			
		
		
		
	selftests/bpf: Convert test_global_funcs test to test_loader framework
Convert 17 test_global_funcs subtests into test_loader framework for easier maintenance and more declarative way to define expected failures/successes. Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Stanislav Fomichev <sdf@google.com> Link: https://lore.kernel.org/bpf/20230216045954.3002473-3-andrii@kernel.org
This commit is contained in:
		
							parent
							
								
									d384dce281
								
							
						
					
					
						commit
						95ebb37617
					
				| @ -1,104 +1,41 @@ | |||||||
| // SPDX-License-Identifier: GPL-2.0
 | // SPDX-License-Identifier: GPL-2.0
 | ||||||
| /* Copyright (c) 2020 Facebook */ | /* Copyright (c) 2020 Facebook */ | ||||||
| #include <test_progs.h> | #include <test_progs.h> | ||||||
| 
 | #include "test_global_func1.skel.h" | ||||||
| const char *err_str; | #include "test_global_func2.skel.h" | ||||||
| bool found; | #include "test_global_func3.skel.h" | ||||||
| 
 | #include "test_global_func4.skel.h" | ||||||
| static int libbpf_debug_print(enum libbpf_print_level level, | #include "test_global_func5.skel.h" | ||||||
| 			      const char *format, va_list args) | #include "test_global_func6.skel.h" | ||||||
| { | #include "test_global_func7.skel.h" | ||||||
| 	char *log_buf; | #include "test_global_func8.skel.h" | ||||||
| 
 | #include "test_global_func9.skel.h" | ||||||
| 	if (level != LIBBPF_WARN || | #include "test_global_func10.skel.h" | ||||||
| 	    strcmp(format, "libbpf: \n%s\n")) { | #include "test_global_func11.skel.h" | ||||||
| 		vprintf(format, args); | #include "test_global_func12.skel.h" | ||||||
| 		return 0; | #include "test_global_func13.skel.h" | ||||||
| 	} | #include "test_global_func14.skel.h" | ||||||
| 
 | #include "test_global_func15.skel.h" | ||||||
| 	log_buf = va_arg(args, char *); | #include "test_global_func16.skel.h" | ||||||
| 	if (!log_buf) | #include "test_global_func17.skel.h" | ||||||
| 		goto out; |  | ||||||
| 	if (err_str && strstr(log_buf, err_str) == 0) |  | ||||||
| 		found = true; |  | ||||||
| out: |  | ||||||
| 	printf(format, log_buf); |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| extern int extra_prog_load_log_flags; |  | ||||||
| 
 |  | ||||||
| static int check_load(const char *file) |  | ||||||
| { |  | ||||||
| 	struct bpf_object *obj = NULL; |  | ||||||
| 	struct bpf_program *prog; |  | ||||||
| 	int err; |  | ||||||
| 
 |  | ||||||
| 	found = false; |  | ||||||
| 
 |  | ||||||
| 	obj = bpf_object__open_file(file, NULL); |  | ||||||
| 	err = libbpf_get_error(obj); |  | ||||||
| 	if (err) |  | ||||||
| 		return err; |  | ||||||
| 
 |  | ||||||
| 	prog = bpf_object__next_program(obj, NULL); |  | ||||||
| 	if (!prog) { |  | ||||||
| 		err = -ENOENT; |  | ||||||
| 		goto err_out; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	bpf_program__set_flags(prog, BPF_F_TEST_RND_HI32); |  | ||||||
| 	bpf_program__set_log_level(prog, extra_prog_load_log_flags); |  | ||||||
| 
 |  | ||||||
| 	err = bpf_object__load(obj); |  | ||||||
| 
 |  | ||||||
| err_out: |  | ||||||
| 	bpf_object__close(obj); |  | ||||||
| 	return err; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| struct test_def { |  | ||||||
| 	const char *file; |  | ||||||
| 	const char *err_str; |  | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| void test_test_global_funcs(void) | void test_test_global_funcs(void) | ||||||
| { | { | ||||||
| 	struct test_def tests[] = { | 	RUN_TESTS(test_global_func1); | ||||||
| 		{ "test_global_func1.bpf.o", "combined stack size of 4 calls is 544" }, | 	RUN_TESTS(test_global_func2); | ||||||
| 		{ "test_global_func2.bpf.o" }, | 	RUN_TESTS(test_global_func3); | ||||||
| 		{ "test_global_func3.bpf.o", "the call stack of 8 frames" }, | 	RUN_TESTS(test_global_func4); | ||||||
| 		{ "test_global_func4.bpf.o" }, | 	RUN_TESTS(test_global_func5); | ||||||
| 		{ "test_global_func5.bpf.o", "expected pointer to ctx, but got PTR" }, | 	RUN_TESTS(test_global_func6); | ||||||
| 		{ "test_global_func6.bpf.o", "modified ctx ptr R2" }, | 	RUN_TESTS(test_global_func7); | ||||||
| 		{ "test_global_func7.bpf.o", "foo() doesn't return scalar" }, | 	RUN_TESTS(test_global_func8); | ||||||
| 		{ "test_global_func8.bpf.o" }, | 	RUN_TESTS(test_global_func9); | ||||||
| 		{ "test_global_func9.bpf.o" }, | 	RUN_TESTS(test_global_func10); | ||||||
| 		{ "test_global_func10.bpf.o", "invalid indirect read from stack" }, | 	RUN_TESTS(test_global_func11); | ||||||
| 		{ "test_global_func11.bpf.o", "Caller passes invalid args into func#1" }, | 	RUN_TESTS(test_global_func12); | ||||||
| 		{ "test_global_func12.bpf.o", "invalid mem access 'mem_or_null'" }, | 	RUN_TESTS(test_global_func13); | ||||||
| 		{ "test_global_func13.bpf.o", "Caller passes invalid args into func#1" }, | 	RUN_TESTS(test_global_func14); | ||||||
| 		{ "test_global_func14.bpf.o", "reference type('FWD S') size cannot be determined" }, | 	RUN_TESTS(test_global_func15); | ||||||
| 		{ "test_global_func15.bpf.o", "At program exit the register R0 has value" }, | 	RUN_TESTS(test_global_func16); | ||||||
| 		{ "test_global_func16.bpf.o", "invalid indirect read from stack" }, | 	RUN_TESTS(test_global_func17); | ||||||
| 		{ "test_global_func17.bpf.o", "Caller passes invalid args into func#1" }, |  | ||||||
| 	}; |  | ||||||
| 	libbpf_print_fn_t old_print_fn = NULL; |  | ||||||
| 	int err, i, duration = 0; |  | ||||||
| 
 |  | ||||||
| 	old_print_fn = libbpf_set_print(libbpf_debug_print); |  | ||||||
| 
 |  | ||||||
| 	for (i = 0; i < ARRAY_SIZE(tests); i++) { |  | ||||||
| 		const struct test_def *test = &tests[i]; |  | ||||||
| 
 |  | ||||||
| 		if (!test__start_subtest(test->file)) |  | ||||||
| 			continue; |  | ||||||
| 
 |  | ||||||
| 		err_str = test->err_str; |  | ||||||
| 		err = check_load(test->file); |  | ||||||
| 		CHECK_FAIL(!!err ^ !!err_str); |  | ||||||
| 		if (err_str) |  | ||||||
| 			CHECK(found, "", "expected string '%s'", err_str); |  | ||||||
| 	} |  | ||||||
| 	libbpf_set_print(old_print_fn); |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -3,10 +3,9 @@ | |||||||
| #include <stddef.h> | #include <stddef.h> | ||||||
| #include <linux/bpf.h> | #include <linux/bpf.h> | ||||||
| #include <bpf/bpf_helpers.h> | #include <bpf/bpf_helpers.h> | ||||||
|  | #include "bpf_misc.h" | ||||||
| 
 | 
 | ||||||
| #ifndef MAX_STACK |  | ||||||
| #define MAX_STACK (512 - 3 * 32 + 8) | #define MAX_STACK (512 - 3 * 32 + 8) | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| static __attribute__ ((noinline)) | static __attribute__ ((noinline)) | ||||||
| int f0(int var, struct __sk_buff *skb) | int f0(int var, struct __sk_buff *skb) | ||||||
| @ -39,7 +38,8 @@ int f3(int val, struct __sk_buff *skb, int var) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SEC("tc") | SEC("tc") | ||||||
| int test_cls(struct __sk_buff *skb) | __failure __msg("combined stack size of 4 calls is 544") | ||||||
|  | int global_func1(struct __sk_buff *skb) | ||||||
| { | { | ||||||
| 	return f0(1, skb) + f1(skb) + f2(2, skb) + f3(3, skb, 4); | 	return f0(1, skb) + f1(skb) + f2(2, skb) + f3(3, skb, 4); | ||||||
| } | } | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ | |||||||
| #include <stddef.h> | #include <stddef.h> | ||||||
| #include <linux/bpf.h> | #include <linux/bpf.h> | ||||||
| #include <bpf/bpf_helpers.h> | #include <bpf/bpf_helpers.h> | ||||||
|  | #include "bpf_misc.h" | ||||||
| 
 | 
 | ||||||
| struct Small { | struct Small { | ||||||
| 	int x; | 	int x; | ||||||
| @ -21,7 +22,8 @@ __noinline int foo(const struct Big *big) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SEC("cgroup_skb/ingress") | SEC("cgroup_skb/ingress") | ||||||
| int test_cls(struct __sk_buff *skb) | __failure __msg("invalid indirect read from stack") | ||||||
|  | int global_func10(struct __sk_buff *skb) | ||||||
| { | { | ||||||
| 	const struct Small small = {.x = skb->len }; | 	const struct Small small = {.x = skb->len }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ | |||||||
| #include <stddef.h> | #include <stddef.h> | ||||||
| #include <linux/bpf.h> | #include <linux/bpf.h> | ||||||
| #include <bpf/bpf_helpers.h> | #include <bpf/bpf_helpers.h> | ||||||
|  | #include "bpf_misc.h" | ||||||
| 
 | 
 | ||||||
| struct S { | struct S { | ||||||
| 	int x; | 	int x; | ||||||
| @ -13,7 +14,8 @@ __noinline int foo(const struct S *s) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SEC("cgroup_skb/ingress") | SEC("cgroup_skb/ingress") | ||||||
| int test_cls(struct __sk_buff *skb) | __failure __msg("Caller passes invalid args into func#1") | ||||||
|  | int global_func11(struct __sk_buff *skb) | ||||||
| { | { | ||||||
| 	return foo((const void *)skb); | 	return foo((const void *)skb); | ||||||
| } | } | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ | |||||||
| #include <stddef.h> | #include <stddef.h> | ||||||
| #include <linux/bpf.h> | #include <linux/bpf.h> | ||||||
| #include <bpf/bpf_helpers.h> | #include <bpf/bpf_helpers.h> | ||||||
|  | #include "bpf_misc.h" | ||||||
| 
 | 
 | ||||||
| struct S { | struct S { | ||||||
| 	int x; | 	int x; | ||||||
| @ -13,7 +14,8 @@ __noinline int foo(const struct S *s) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SEC("cgroup_skb/ingress") | SEC("cgroup_skb/ingress") | ||||||
| int test_cls(struct __sk_buff *skb) | __failure __msg("invalid mem access 'mem_or_null'") | ||||||
|  | int global_func12(struct __sk_buff *skb) | ||||||
| { | { | ||||||
| 	const struct S s = {.x = skb->len }; | 	const struct S s = {.x = skb->len }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ | |||||||
| #include <stddef.h> | #include <stddef.h> | ||||||
| #include <linux/bpf.h> | #include <linux/bpf.h> | ||||||
| #include <bpf/bpf_helpers.h> | #include <bpf/bpf_helpers.h> | ||||||
|  | #include "bpf_misc.h" | ||||||
| 
 | 
 | ||||||
| struct S { | struct S { | ||||||
| 	int x; | 	int x; | ||||||
| @ -16,7 +17,8 @@ __noinline int foo(const struct S *s) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SEC("cgroup_skb/ingress") | SEC("cgroup_skb/ingress") | ||||||
| int test_cls(struct __sk_buff *skb) | __failure __msg("Caller passes invalid args into func#1") | ||||||
|  | int global_func13(struct __sk_buff *skb) | ||||||
| { | { | ||||||
| 	const struct S *s = (const struct S *)(0xbedabeda); | 	const struct S *s = (const struct S *)(0xbedabeda); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ | |||||||
| #include <stddef.h> | #include <stddef.h> | ||||||
| #include <linux/bpf.h> | #include <linux/bpf.h> | ||||||
| #include <bpf/bpf_helpers.h> | #include <bpf/bpf_helpers.h> | ||||||
|  | #include "bpf_misc.h" | ||||||
| 
 | 
 | ||||||
| struct S; | struct S; | ||||||
| 
 | 
 | ||||||
| @ -14,7 +15,8 @@ __noinline int foo(const struct S *s) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SEC("cgroup_skb/ingress") | SEC("cgroup_skb/ingress") | ||||||
| int test_cls(struct __sk_buff *skb) | __failure __msg("reference type('FWD S') size cannot be determined") | ||||||
|  | int global_func14(struct __sk_buff *skb) | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| 	return foo(NULL); | 	return foo(NULL); | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ | |||||||
| #include <stddef.h> | #include <stddef.h> | ||||||
| #include <linux/bpf.h> | #include <linux/bpf.h> | ||||||
| #include <bpf/bpf_helpers.h> | #include <bpf/bpf_helpers.h> | ||||||
|  | #include "bpf_misc.h" | ||||||
| 
 | 
 | ||||||
| __noinline int foo(unsigned int *v) | __noinline int foo(unsigned int *v) | ||||||
| { | { | ||||||
| @ -12,7 +13,8 @@ __noinline int foo(unsigned int *v) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SEC("cgroup_skb/ingress") | SEC("cgroup_skb/ingress") | ||||||
| int test_cls(struct __sk_buff *skb) | __failure __msg("At program exit the register R0 has value") | ||||||
|  | int global_func15(struct __sk_buff *skb) | ||||||
| { | { | ||||||
| 	unsigned int v = 1; | 	unsigned int v = 1; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ | |||||||
| #include <stddef.h> | #include <stddef.h> | ||||||
| #include <linux/bpf.h> | #include <linux/bpf.h> | ||||||
| #include <bpf/bpf_helpers.h> | #include <bpf/bpf_helpers.h> | ||||||
|  | #include "bpf_misc.h" | ||||||
| 
 | 
 | ||||||
| __noinline int foo(int (*arr)[10]) | __noinline int foo(int (*arr)[10]) | ||||||
| { | { | ||||||
| @ -12,7 +13,8 @@ __noinline int foo(int (*arr)[10]) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SEC("cgroup_skb/ingress") | SEC("cgroup_skb/ingress") | ||||||
| int test_cls(struct __sk_buff *skb) | __failure __msg("invalid indirect read from stack") | ||||||
|  | int global_func16(struct __sk_buff *skb) | ||||||
| { | { | ||||||
| 	int array[10]; | 	int array[10]; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| // SPDX-License-Identifier: GPL-2.0-only
 | // SPDX-License-Identifier: GPL-2.0-only
 | ||||||
| #include <vmlinux.h> | #include <vmlinux.h> | ||||||
| #include <bpf/bpf_helpers.h> | #include <bpf/bpf_helpers.h> | ||||||
|  | #include "bpf_misc.h" | ||||||
| 
 | 
 | ||||||
| __noinline int foo(int *p) | __noinline int foo(int *p) | ||||||
| { | { | ||||||
| @ -10,7 +11,8 @@ __noinline int foo(int *p) | |||||||
| const volatile int i; | const volatile int i; | ||||||
| 
 | 
 | ||||||
| SEC("tc") | SEC("tc") | ||||||
| int test_cls(struct __sk_buff *skb) | __failure __msg("Caller passes invalid args into func#1") | ||||||
|  | int global_func17(struct __sk_buff *skb) | ||||||
| { | { | ||||||
| 	return foo((int *)&i); | 	return foo((int *)&i); | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,4 +1,45 @@ | |||||||
| // SPDX-License-Identifier: GPL-2.0-only
 | // SPDX-License-Identifier: GPL-2.0-only
 | ||||||
| /* Copyright (c) 2020 Facebook */ | /* Copyright (c) 2020 Facebook */ | ||||||
|  | #include <stddef.h> | ||||||
|  | #include <linux/bpf.h> | ||||||
|  | #include <bpf/bpf_helpers.h> | ||||||
|  | #include "bpf_misc.h" | ||||||
|  | 
 | ||||||
| #define MAX_STACK (512 - 3 * 32) | #define MAX_STACK (512 - 3 * 32) | ||||||
| #include "test_global_func1.c" | 
 | ||||||
|  | static __attribute__ ((noinline)) | ||||||
|  | int f0(int var, struct __sk_buff *skb) | ||||||
|  | { | ||||||
|  | 	return skb->len; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | __attribute__ ((noinline)) | ||||||
|  | int f1(struct __sk_buff *skb) | ||||||
|  | { | ||||||
|  | 	volatile char buf[MAX_STACK] = {}; | ||||||
|  | 
 | ||||||
|  | 	return f0(0, skb) + skb->len; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int f3(int, struct __sk_buff *skb, int); | ||||||
|  | 
 | ||||||
|  | __attribute__ ((noinline)) | ||||||
|  | int f2(int val, struct __sk_buff *skb) | ||||||
|  | { | ||||||
|  | 	return f1(skb) + f3(val, skb, 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | __attribute__ ((noinline)) | ||||||
|  | int f3(int val, struct __sk_buff *skb, int var) | ||||||
|  | { | ||||||
|  | 	volatile char buf[MAX_STACK] = {}; | ||||||
|  | 
 | ||||||
|  | 	return skb->ifindex * val * var; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SEC("tc") | ||||||
|  | __success | ||||||
|  | int global_func2(struct __sk_buff *skb) | ||||||
|  | { | ||||||
|  | 	return f0(1, skb) + f1(skb) + f2(2, skb) + f3(3, skb, 4); | ||||||
|  | } | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ | |||||||
| #include <stddef.h> | #include <stddef.h> | ||||||
| #include <linux/bpf.h> | #include <linux/bpf.h> | ||||||
| #include <bpf/bpf_helpers.h> | #include <bpf/bpf_helpers.h> | ||||||
|  | #include "bpf_misc.h" | ||||||
| 
 | 
 | ||||||
| __attribute__ ((noinline)) | __attribute__ ((noinline)) | ||||||
| int f1(struct __sk_buff *skb) | int f1(struct __sk_buff *skb) | ||||||
| @ -46,20 +47,15 @@ int f7(struct __sk_buff *skb) | |||||||
| 	return f6(skb); | 	return f6(skb); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifndef NO_FN8 |  | ||||||
| __attribute__ ((noinline)) | __attribute__ ((noinline)) | ||||||
| int f8(struct __sk_buff *skb) | int f8(struct __sk_buff *skb) | ||||||
| { | { | ||||||
| 	return f7(skb); | 	return f7(skb); | ||||||
| } | } | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| SEC("tc") | SEC("tc") | ||||||
| int test_cls(struct __sk_buff *skb) | __failure __msg("the call stack of 8 frames") | ||||||
|  | int global_func3(struct __sk_buff *skb) | ||||||
| { | { | ||||||
| #ifndef NO_FN8 |  | ||||||
| 	return f8(skb); | 	return f8(skb); | ||||||
| #else |  | ||||||
| 	return f7(skb); |  | ||||||
| #endif |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,4 +1,55 @@ | |||||||
| // SPDX-License-Identifier: GPL-2.0-only
 | // SPDX-License-Identifier: GPL-2.0-only
 | ||||||
| /* Copyright (c) 2020 Facebook */ | /* Copyright (c) 2020 Facebook */ | ||||||
| #define NO_FN8 | #include <stddef.h> | ||||||
| #include "test_global_func3.c" | #include <linux/bpf.h> | ||||||
|  | #include <bpf/bpf_helpers.h> | ||||||
|  | #include "bpf_misc.h" | ||||||
|  | 
 | ||||||
|  | __attribute__ ((noinline)) | ||||||
|  | int f1(struct __sk_buff *skb) | ||||||
|  | { | ||||||
|  | 	return skb->len; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | __attribute__ ((noinline)) | ||||||
|  | int f2(int val, struct __sk_buff *skb) | ||||||
|  | { | ||||||
|  | 	return f1(skb) + val; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | __attribute__ ((noinline)) | ||||||
|  | int f3(int val, struct __sk_buff *skb, int var) | ||||||
|  | { | ||||||
|  | 	return f2(var, skb) + val; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | __attribute__ ((noinline)) | ||||||
|  | int f4(struct __sk_buff *skb) | ||||||
|  | { | ||||||
|  | 	return f3(1, skb, 2); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | __attribute__ ((noinline)) | ||||||
|  | int f5(struct __sk_buff *skb) | ||||||
|  | { | ||||||
|  | 	return f4(skb); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | __attribute__ ((noinline)) | ||||||
|  | int f6(struct __sk_buff *skb) | ||||||
|  | { | ||||||
|  | 	return f5(skb); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | __attribute__ ((noinline)) | ||||||
|  | int f7(struct __sk_buff *skb) | ||||||
|  | { | ||||||
|  | 	return f6(skb); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SEC("tc") | ||||||
|  | __success | ||||||
|  | int global_func4(struct __sk_buff *skb) | ||||||
|  | { | ||||||
|  | 	return f7(skb); | ||||||
|  | } | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ | |||||||
| #include <stddef.h> | #include <stddef.h> | ||||||
| #include <linux/bpf.h> | #include <linux/bpf.h> | ||||||
| #include <bpf/bpf_helpers.h> | #include <bpf/bpf_helpers.h> | ||||||
|  | #include "bpf_misc.h" | ||||||
| 
 | 
 | ||||||
| __attribute__ ((noinline)) | __attribute__ ((noinline)) | ||||||
| int f1(struct __sk_buff *skb) | int f1(struct __sk_buff *skb) | ||||||
| @ -25,7 +26,8 @@ int f3(int val, struct __sk_buff *skb) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SEC("tc") | SEC("tc") | ||||||
| int test_cls(struct __sk_buff *skb) | __failure __msg("expected pointer to ctx, but got PTR") | ||||||
|  | int global_func5(struct __sk_buff *skb) | ||||||
| { | { | ||||||
| 	return f1(skb) + f2(2, skb) + f3(3, skb); | 	return f1(skb) + f2(2, skb) + f3(3, skb); | ||||||
| } | } | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ | |||||||
| #include <stddef.h> | #include <stddef.h> | ||||||
| #include <linux/bpf.h> | #include <linux/bpf.h> | ||||||
| #include <bpf/bpf_helpers.h> | #include <bpf/bpf_helpers.h> | ||||||
|  | #include "bpf_misc.h" | ||||||
| 
 | 
 | ||||||
| __attribute__ ((noinline)) | __attribute__ ((noinline)) | ||||||
| int f1(struct __sk_buff *skb) | int f1(struct __sk_buff *skb) | ||||||
| @ -25,7 +26,8 @@ int f3(int val, struct __sk_buff *skb) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SEC("tc") | SEC("tc") | ||||||
| int test_cls(struct __sk_buff *skb) | __failure __msg("modified ctx ptr R2") | ||||||
|  | int global_func6(struct __sk_buff *skb) | ||||||
| { | { | ||||||
| 	return f1(skb) + f2(2, skb) + f3(3, skb); | 	return f1(skb) + f2(2, skb) + f3(3, skb); | ||||||
| } | } | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ | |||||||
| #include <stddef.h> | #include <stddef.h> | ||||||
| #include <linux/bpf.h> | #include <linux/bpf.h> | ||||||
| #include <bpf/bpf_helpers.h> | #include <bpf/bpf_helpers.h> | ||||||
|  | #include "bpf_misc.h" | ||||||
| 
 | 
 | ||||||
| __attribute__ ((noinline)) | __attribute__ ((noinline)) | ||||||
| void foo(struct __sk_buff *skb) | void foo(struct __sk_buff *skb) | ||||||
| @ -11,7 +12,8 @@ void foo(struct __sk_buff *skb) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SEC("tc") | SEC("tc") | ||||||
| int test_cls(struct __sk_buff *skb) | __failure __msg("foo() doesn't return scalar") | ||||||
|  | int global_func7(struct __sk_buff *skb) | ||||||
| { | { | ||||||
| 	foo(skb); | 	foo(skb); | ||||||
| 	return 0; | 	return 0; | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ | |||||||
| #include <stddef.h> | #include <stddef.h> | ||||||
| #include <linux/bpf.h> | #include <linux/bpf.h> | ||||||
| #include <bpf/bpf_helpers.h> | #include <bpf/bpf_helpers.h> | ||||||
|  | #include "bpf_misc.h" | ||||||
| 
 | 
 | ||||||
| __noinline int foo(struct __sk_buff *skb) | __noinline int foo(struct __sk_buff *skb) | ||||||
| { | { | ||||||
| @ -10,7 +11,8 @@ __noinline int foo(struct __sk_buff *skb) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SEC("cgroup_skb/ingress") | SEC("cgroup_skb/ingress") | ||||||
| int test_cls(struct __sk_buff *skb) | __success | ||||||
|  | int global_func8(struct __sk_buff *skb) | ||||||
| { | { | ||||||
| 	if (!foo(skb)) | 	if (!foo(skb)) | ||||||
| 		return 0; | 		return 0; | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ | |||||||
| #include <stddef.h> | #include <stddef.h> | ||||||
| #include <linux/bpf.h> | #include <linux/bpf.h> | ||||||
| #include <bpf/bpf_helpers.h> | #include <bpf/bpf_helpers.h> | ||||||
|  | #include "bpf_misc.h" | ||||||
| 
 | 
 | ||||||
| struct S { | struct S { | ||||||
| 	int x; | 	int x; | ||||||
| @ -74,7 +75,8 @@ __noinline int quuz(int **p) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SEC("cgroup_skb/ingress") | SEC("cgroup_skb/ingress") | ||||||
| int test_cls(struct __sk_buff *skb) | __success | ||||||
|  | int global_func9(struct __sk_buff *skb) | ||||||
| { | { | ||||||
| 	int result = 0; | 	int result = 0; | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Andrii Nakryiko
						Andrii Nakryiko