-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
selftests/bpf: Add unit tests for global functions
test_global_func[12] - check 512 stack limit. test_global_func[34] - check 8 frame call chain limit. test_global_func5 - check that non-ctx pointer cannot be passed into a function that expects context. test_global_func6 - check that ctx pointer is unmodified. test_global_func7 - check that global function returns scalar. Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Song Liu <songliubraving@fb.com> Link: https://lore.kernel.org/bpf/20200110064124.1760511-7-ast@kernel.org
- Loading branch information
Alexei Starovoitov
authored and
Daniel Borkmann
committed
Jan 10, 2020
1 parent
e528d1c
commit 360301a
Showing
8 changed files
with
280 additions
and
0 deletions.
There are no files selected for viewing
82 changes: 82 additions & 0 deletions
82
tools/testing/selftests/bpf/prog_tests/test_global_funcs.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* Copyright (c) 2020 Facebook */ | ||
#include <test_progs.h> | ||
|
||
const char *err_str; | ||
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 (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_prog_load_attr attr; | ||
struct bpf_object *obj = NULL; | ||
int err, prog_fd; | ||
|
||
memset(&attr, 0, sizeof(struct bpf_prog_load_attr)); | ||
attr.file = file; | ||
attr.prog_type = BPF_PROG_TYPE_UNSPEC; | ||
attr.log_level = extra_prog_load_log_flags; | ||
attr.prog_flags = BPF_F_TEST_RND_HI32; | ||
found = false; | ||
err = bpf_prog_load_xattr(&attr, &obj, &prog_fd); | ||
bpf_object__close(obj); | ||
return err; | ||
} | ||
|
||
struct test_def { | ||
const char *file; | ||
const char *err_str; | ||
}; | ||
|
||
void test_test_global_funcs(void) | ||
{ | ||
struct test_def tests[] = { | ||
{ "test_global_func1.o", "combined stack size of 4 calls is 544" }, | ||
{ "test_global_func2.o" }, | ||
{ "test_global_func3.o" , "the call stack of 8 frames" }, | ||
{ "test_global_func4.o" }, | ||
{ "test_global_func5.o" , "expected pointer to ctx, but got PTR" }, | ||
{ "test_global_func6.o" , "modified ctx ptr R2" }, | ||
{ "test_global_func7.o" , "foo() doesn't return scalar" }, | ||
}; | ||
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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* Copyright (c) 2020 Facebook */ | ||
#include <stddef.h> | ||
#include <linux/bpf.h> | ||
#include "bpf_helpers.h" | ||
|
||
#ifndef MAX_STACK | ||
#define MAX_STACK (512 - 3 * 32 + 8) | ||
#endif | ||
|
||
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("classifier/test") | ||
int test_cls(struct __sk_buff *skb) | ||
{ | ||
return f0(1, skb) + f1(skb) + f2(2, skb) + f3(3, skb, 4); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* Copyright (c) 2020 Facebook */ | ||
#define MAX_STACK (512 - 3 * 32) | ||
#include "test_global_func1.c" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* Copyright (c) 2020 Facebook */ | ||
#include <stddef.h> | ||
#include <linux/bpf.h> | ||
#include "bpf_helpers.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); | ||
} | ||
|
||
#ifndef NO_FN8 | ||
__attribute__ ((noinline)) | ||
int f8(struct __sk_buff *skb) | ||
{ | ||
return f7(skb); | ||
} | ||
#endif | ||
|
||
SEC("classifier/test") | ||
int test_cls(struct __sk_buff *skb) | ||
{ | ||
#ifndef NO_FN8 | ||
return f8(skb); | ||
#else | ||
return f7(skb); | ||
#endif | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* Copyright (c) 2020 Facebook */ | ||
#define NO_FN8 | ||
#include "test_global_func3.c" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* Copyright (c) 2020 Facebook */ | ||
#include <stddef.h> | ||
#include <linux/bpf.h> | ||
#include "bpf_helpers.h" | ||
|
||
__attribute__ ((noinline)) | ||
int f1(struct __sk_buff *skb) | ||
{ | ||
return skb->len; | ||
} | ||
|
||
int f3(int, struct __sk_buff *skb); | ||
|
||
__attribute__ ((noinline)) | ||
int f2(int val, struct __sk_buff *skb) | ||
{ | ||
return f1(skb) + f3(val, (void *)&val); /* type mismatch */ | ||
} | ||
|
||
__attribute__ ((noinline)) | ||
int f3(int val, struct __sk_buff *skb) | ||
{ | ||
return skb->ifindex * val; | ||
} | ||
|
||
SEC("classifier/test") | ||
int test_cls(struct __sk_buff *skb) | ||
{ | ||
return f1(skb) + f2(2, skb) + f3(3, skb); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* Copyright (c) 2020 Facebook */ | ||
#include <stddef.h> | ||
#include <linux/bpf.h> | ||
#include "bpf_helpers.h" | ||
|
||
__attribute__ ((noinline)) | ||
int f1(struct __sk_buff *skb) | ||
{ | ||
return skb->len; | ||
} | ||
|
||
int f3(int, struct __sk_buff *skb); | ||
|
||
__attribute__ ((noinline)) | ||
int f2(int val, struct __sk_buff *skb) | ||
{ | ||
return f1(skb) + f3(val, skb + 1); /* type mismatch */ | ||
} | ||
|
||
__attribute__ ((noinline)) | ||
int f3(int val, struct __sk_buff *skb) | ||
{ | ||
return skb->ifindex * val; | ||
} | ||
|
||
SEC("classifier/test") | ||
int test_cls(struct __sk_buff *skb) | ||
{ | ||
return f1(skb) + f2(2, skb) + f3(3, skb); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* Copyright (c) 2020 Facebook */ | ||
#include <stddef.h> | ||
#include <linux/bpf.h> | ||
#include "bpf_helpers.h" | ||
|
||
__attribute__ ((noinline)) | ||
void foo(struct __sk_buff *skb) | ||
{ | ||
skb->tc_index = 0; | ||
} | ||
|
||
SEC("classifier/test") | ||
int test_cls(struct __sk_buff *skb) | ||
{ | ||
foo(skb); | ||
return 0; | ||
} |