Skip to content

Commit 360301a

Browse files
Alexei Starovoitovborkmann
authored andcommitted
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 <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Acked-by: Song Liu <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent e528d1c commit 360301a

File tree

8 files changed

+280
-0
lines changed

8 files changed

+280
-0
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (c) 2020 Facebook */
3+
#include <test_progs.h>
4+
5+
const char *err_str;
6+
bool found;
7+
8+
static int libbpf_debug_print(enum libbpf_print_level level,
9+
const char *format, va_list args)
10+
{
11+
char *log_buf;
12+
13+
if (level != LIBBPF_WARN ||
14+
strcmp(format, "libbpf: \n%s\n")) {
15+
vprintf(format, args);
16+
return 0;
17+
}
18+
19+
log_buf = va_arg(args, char *);
20+
if (!log_buf)
21+
goto out;
22+
if (strstr(log_buf, err_str) == 0)
23+
found = true;
24+
out:
25+
printf(format, log_buf);
26+
return 0;
27+
}
28+
29+
extern int extra_prog_load_log_flags;
30+
31+
static int check_load(const char *file)
32+
{
33+
struct bpf_prog_load_attr attr;
34+
struct bpf_object *obj = NULL;
35+
int err, prog_fd;
36+
37+
memset(&attr, 0, sizeof(struct bpf_prog_load_attr));
38+
attr.file = file;
39+
attr.prog_type = BPF_PROG_TYPE_UNSPEC;
40+
attr.log_level = extra_prog_load_log_flags;
41+
attr.prog_flags = BPF_F_TEST_RND_HI32;
42+
found = false;
43+
err = bpf_prog_load_xattr(&attr, &obj, &prog_fd);
44+
bpf_object__close(obj);
45+
return err;
46+
}
47+
48+
struct test_def {
49+
const char *file;
50+
const char *err_str;
51+
};
52+
53+
void test_test_global_funcs(void)
54+
{
55+
struct test_def tests[] = {
56+
{ "test_global_func1.o", "combined stack size of 4 calls is 544" },
57+
{ "test_global_func2.o" },
58+
{ "test_global_func3.o" , "the call stack of 8 frames" },
59+
{ "test_global_func4.o" },
60+
{ "test_global_func5.o" , "expected pointer to ctx, but got PTR" },
61+
{ "test_global_func6.o" , "modified ctx ptr R2" },
62+
{ "test_global_func7.o" , "foo() doesn't return scalar" },
63+
};
64+
libbpf_print_fn_t old_print_fn = NULL;
65+
int err, i, duration = 0;
66+
67+
old_print_fn = libbpf_set_print(libbpf_debug_print);
68+
69+
for (i = 0; i < ARRAY_SIZE(tests); i++) {
70+
const struct test_def *test = &tests[i];
71+
72+
if (!test__start_subtest(test->file))
73+
continue;
74+
75+
err_str = test->err_str;
76+
err = check_load(test->file);
77+
CHECK_FAIL(!!err ^ !!err_str);
78+
if (err_str)
79+
CHECK(found, "", "expected string '%s'", err_str);
80+
}
81+
libbpf_set_print(old_print_fn);
82+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/* Copyright (c) 2020 Facebook */
3+
#include <stddef.h>
4+
#include <linux/bpf.h>
5+
#include "bpf_helpers.h"
6+
7+
#ifndef MAX_STACK
8+
#define MAX_STACK (512 - 3 * 32 + 8)
9+
#endif
10+
11+
static __attribute__ ((noinline))
12+
int f0(int var, struct __sk_buff *skb)
13+
{
14+
return skb->len;
15+
}
16+
17+
__attribute__ ((noinline))
18+
int f1(struct __sk_buff *skb)
19+
{
20+
volatile char buf[MAX_STACK] = {};
21+
22+
return f0(0, skb) + skb->len;
23+
}
24+
25+
int f3(int, struct __sk_buff *skb, int);
26+
27+
__attribute__ ((noinline))
28+
int f2(int val, struct __sk_buff *skb)
29+
{
30+
return f1(skb) + f3(val, skb, 1);
31+
}
32+
33+
__attribute__ ((noinline))
34+
int f3(int val, struct __sk_buff *skb, int var)
35+
{
36+
volatile char buf[MAX_STACK] = {};
37+
38+
return skb->ifindex * val * var;
39+
}
40+
41+
SEC("classifier/test")
42+
int test_cls(struct __sk_buff *skb)
43+
{
44+
return f0(1, skb) + f1(skb) + f2(2, skb) + f3(3, skb, 4);
45+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/* Copyright (c) 2020 Facebook */
3+
#define MAX_STACK (512 - 3 * 32)
4+
#include "test_global_func1.c"
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/* Copyright (c) 2020 Facebook */
3+
#include <stddef.h>
4+
#include <linux/bpf.h>
5+
#include "bpf_helpers.h"
6+
7+
__attribute__ ((noinline))
8+
int f1(struct __sk_buff *skb)
9+
{
10+
return skb->len;
11+
}
12+
13+
__attribute__ ((noinline))
14+
int f2(int val, struct __sk_buff *skb)
15+
{
16+
return f1(skb) + val;
17+
}
18+
19+
__attribute__ ((noinline))
20+
int f3(int val, struct __sk_buff *skb, int var)
21+
{
22+
return f2(var, skb) + val;
23+
}
24+
25+
__attribute__ ((noinline))
26+
int f4(struct __sk_buff *skb)
27+
{
28+
return f3(1, skb, 2);
29+
}
30+
31+
__attribute__ ((noinline))
32+
int f5(struct __sk_buff *skb)
33+
{
34+
return f4(skb);
35+
}
36+
37+
__attribute__ ((noinline))
38+
int f6(struct __sk_buff *skb)
39+
{
40+
return f5(skb);
41+
}
42+
43+
__attribute__ ((noinline))
44+
int f7(struct __sk_buff *skb)
45+
{
46+
return f6(skb);
47+
}
48+
49+
#ifndef NO_FN8
50+
__attribute__ ((noinline))
51+
int f8(struct __sk_buff *skb)
52+
{
53+
return f7(skb);
54+
}
55+
#endif
56+
57+
SEC("classifier/test")
58+
int test_cls(struct __sk_buff *skb)
59+
{
60+
#ifndef NO_FN8
61+
return f8(skb);
62+
#else
63+
return f7(skb);
64+
#endif
65+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/* Copyright (c) 2020 Facebook */
3+
#define NO_FN8
4+
#include "test_global_func3.c"
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/* Copyright (c) 2020 Facebook */
3+
#include <stddef.h>
4+
#include <linux/bpf.h>
5+
#include "bpf_helpers.h"
6+
7+
__attribute__ ((noinline))
8+
int f1(struct __sk_buff *skb)
9+
{
10+
return skb->len;
11+
}
12+
13+
int f3(int, struct __sk_buff *skb);
14+
15+
__attribute__ ((noinline))
16+
int f2(int val, struct __sk_buff *skb)
17+
{
18+
return f1(skb) + f3(val, (void *)&val); /* type mismatch */
19+
}
20+
21+
__attribute__ ((noinline))
22+
int f3(int val, struct __sk_buff *skb)
23+
{
24+
return skb->ifindex * val;
25+
}
26+
27+
SEC("classifier/test")
28+
int test_cls(struct __sk_buff *skb)
29+
{
30+
return f1(skb) + f2(2, skb) + f3(3, skb);
31+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/* Copyright (c) 2020 Facebook */
3+
#include <stddef.h>
4+
#include <linux/bpf.h>
5+
#include "bpf_helpers.h"
6+
7+
__attribute__ ((noinline))
8+
int f1(struct __sk_buff *skb)
9+
{
10+
return skb->len;
11+
}
12+
13+
int f3(int, struct __sk_buff *skb);
14+
15+
__attribute__ ((noinline))
16+
int f2(int val, struct __sk_buff *skb)
17+
{
18+
return f1(skb) + f3(val, skb + 1); /* type mismatch */
19+
}
20+
21+
__attribute__ ((noinline))
22+
int f3(int val, struct __sk_buff *skb)
23+
{
24+
return skb->ifindex * val;
25+
}
26+
27+
SEC("classifier/test")
28+
int test_cls(struct __sk_buff *skb)
29+
{
30+
return f1(skb) + f2(2, skb) + f3(3, skb);
31+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/* Copyright (c) 2020 Facebook */
3+
#include <stddef.h>
4+
#include <linux/bpf.h>
5+
#include "bpf_helpers.h"
6+
7+
__attribute__ ((noinline))
8+
void foo(struct __sk_buff *skb)
9+
{
10+
skb->tc_index = 0;
11+
}
12+
13+
SEC("classifier/test")
14+
int test_cls(struct __sk_buff *skb)
15+
{
16+
foo(skb);
17+
return 0;
18+
}

0 commit comments

Comments
 (0)