]>
Commit | Line | Data |
---|---|---|
d6f39601 AS |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Copyright (c) 2019 Facebook */ | |
3 | #include <test_progs.h> | |
4 | ||
8f9081c9 YS |
5 | static void test_fexit_bpf2bpf_common(const char *obj_file, |
6 | const char *target_obj_file, | |
7 | int prog_cnt, | |
1d8a0af5 THJ |
8 | const char **prog_name, |
9 | bool run_prog) | |
d6f39601 | 10 | { |
d6f39601 AS |
11 | struct bpf_object *obj = NULL, *pkt_obj; |
12 | int err, pkt_fd, i; | |
8f9081c9 YS |
13 | struct bpf_link **link = NULL; |
14 | struct bpf_program **prog = NULL; | |
1a6fa106 | 15 | __u32 duration = 0, retval; |
d6f39601 AS |
16 | struct bpf_map *data_map; |
17 | const int zero = 0; | |
8f9081c9 | 18 | u64 *result = NULL; |
d6f39601 | 19 | |
8f9081c9 | 20 | err = bpf_prog_load(target_obj_file, BPF_PROG_TYPE_UNSPEC, |
d6f39601 | 21 | &pkt_obj, &pkt_fd); |
1d8a0af5 THJ |
22 | if (CHECK(err, "tgt_prog_load", "file %s err %d errno %d\n", |
23 | target_obj_file, err, errno)) | |
d6f39601 AS |
24 | return; |
25 | DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, | |
26 | .attach_prog_fd = pkt_fd, | |
27 | ); | |
28 | ||
8f9081c9 YS |
29 | link = calloc(sizeof(struct bpf_link *), prog_cnt); |
30 | prog = calloc(sizeof(struct bpf_program *), prog_cnt); | |
7805fe84 | 31 | result = malloc((prog_cnt + 32 /* spare */) * sizeof(u64)); |
8f9081c9 YS |
32 | if (CHECK(!link || !prog || !result, "alloc_memory", |
33 | "failed to alloc memory")) | |
34 | goto close_prog; | |
35 | ||
36 | obj = bpf_object__open_file(obj_file, &opts); | |
d6f39601 | 37 | if (CHECK(IS_ERR_OR_NULL(obj), "obj_open", |
1d8a0af5 | 38 | "failed to open %s: %ld\n", obj_file, |
d6f39601 AS |
39 | PTR_ERR(obj))) |
40 | goto close_prog; | |
41 | ||
42 | err = bpf_object__load(obj); | |
43 | if (CHECK(err, "obj_load", "err %d\n", err)) | |
44 | goto close_prog; | |
45 | ||
8f9081c9 | 46 | for (i = 0; i < prog_cnt; i++) { |
d6f39601 AS |
47 | prog[i] = bpf_object__find_program_by_title(obj, prog_name[i]); |
48 | if (CHECK(!prog[i], "find_prog", "prog %s not found\n", prog_name[i])) | |
49 | goto close_prog; | |
50 | link[i] = bpf_program__attach_trace(prog[i]); | |
51 | if (CHECK(IS_ERR(link[i]), "attach_trace", "failed to link\n")) | |
52 | goto close_prog; | |
53 | } | |
1d8a0af5 THJ |
54 | |
55 | if (!run_prog) | |
56 | goto close_prog; | |
57 | ||
d6f39601 AS |
58 | data_map = bpf_object__find_map_by_name(obj, "fexit_bp.bss"); |
59 | if (CHECK(!data_map, "find_data_map", "data map not found\n")) | |
60 | goto close_prog; | |
61 | ||
62 | err = bpf_prog_test_run(pkt_fd, 1, &pkt_v6, sizeof(pkt_v6), | |
63 | NULL, NULL, &retval, &duration); | |
64 | CHECK(err || retval, "ipv6", | |
65 | "err %d errno %d retval %d duration %d\n", | |
66 | err, errno, retval, duration); | |
67 | ||
8f9081c9 | 68 | err = bpf_map_lookup_elem(bpf_map__fd(data_map), &zero, result); |
d6f39601 AS |
69 | if (CHECK(err, "get_result", |
70 | "failed to get output data: %d\n", err)) | |
71 | goto close_prog; | |
72 | ||
8f9081c9 | 73 | for (i = 0; i < prog_cnt; i++) |
d6f39601 AS |
74 | if (CHECK(result[i] != 1, "result", "fexit_bpf2bpf failed err %ld\n", |
75 | result[i])) | |
76 | goto close_prog; | |
77 | ||
78 | close_prog: | |
8f9081c9 | 79 | for (i = 0; i < prog_cnt; i++) |
d6f39601 AS |
80 | if (!IS_ERR_OR_NULL(link[i])) |
81 | bpf_link__destroy(link[i]); | |
82 | if (!IS_ERR_OR_NULL(obj)) | |
83 | bpf_object__close(obj); | |
84 | bpf_object__close(pkt_obj); | |
8f9081c9 YS |
85 | free(link); |
86 | free(prog); | |
87 | free(result); | |
88 | } | |
89 | ||
90 | static void test_target_no_callees(void) | |
91 | { | |
92 | const char *prog_name[] = { | |
93 | "fexit/test_pkt_md_access", | |
94 | }; | |
95 | test_fexit_bpf2bpf_common("./fexit_bpf2bpf_simple.o", | |
96 | "./test_pkt_md_access.o", | |
97 | ARRAY_SIZE(prog_name), | |
1d8a0af5 | 98 | prog_name, true); |
8f9081c9 YS |
99 | } |
100 | ||
101 | static void test_target_yes_callees(void) | |
102 | { | |
103 | const char *prog_name[] = { | |
104 | "fexit/test_pkt_access", | |
105 | "fexit/test_pkt_access_subprog1", | |
106 | "fexit/test_pkt_access_subprog2", | |
7608e4db | 107 | "fexit/test_pkt_access_subprog3", |
8f9081c9 YS |
108 | }; |
109 | test_fexit_bpf2bpf_common("./fexit_bpf2bpf.o", | |
110 | "./test_pkt_access.o", | |
111 | ARRAY_SIZE(prog_name), | |
1d8a0af5 | 112 | prog_name, true); |
8f9081c9 YS |
113 | } |
114 | ||
7805fe84 AS |
115 | static void test_func_replace(void) |
116 | { | |
117 | const char *prog_name[] = { | |
118 | "fexit/test_pkt_access", | |
119 | "fexit/test_pkt_access_subprog1", | |
120 | "fexit/test_pkt_access_subprog2", | |
121 | "fexit/test_pkt_access_subprog3", | |
122 | "freplace/get_skb_len", | |
123 | "freplace/get_skb_ifindex", | |
124 | "freplace/get_constant", | |
125 | }; | |
126 | test_fexit_bpf2bpf_common("./fexit_bpf2bpf.o", | |
127 | "./test_pkt_access.o", | |
128 | ARRAY_SIZE(prog_name), | |
1d8a0af5 THJ |
129 | prog_name, true); |
130 | } | |
131 | ||
132 | static void test_func_replace_verify(void) | |
133 | { | |
134 | const char *prog_name[] = { | |
135 | "freplace/do_bind", | |
136 | }; | |
137 | test_fexit_bpf2bpf_common("./freplace_connect4.o", | |
138 | "./connect4_prog.o", | |
139 | ARRAY_SIZE(prog_name), | |
140 | prog_name, false); | |
7805fe84 AS |
141 | } |
142 | ||
8f9081c9 YS |
143 | void test_fexit_bpf2bpf(void) |
144 | { | |
145 | test_target_no_callees(); | |
146 | test_target_yes_callees(); | |
7805fe84 | 147 | test_func_replace(); |
1d8a0af5 | 148 | test_func_replace_verify(); |
d6f39601 | 149 | } |