OSDN Git Service

Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[tomoyo/tomoyo-test1.git] / tools / testing / selftests / bpf / prog_tests / fexit_bpf2bpf.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2019 Facebook */
3 #include <test_progs.h>
4
5 static void test_fexit_bpf2bpf_common(const char *obj_file,
6                                       const char *target_obj_file,
7                                       int prog_cnt,
8                                       const char **prog_name,
9                                       bool run_prog)
10 {
11         struct bpf_object *obj = NULL, *pkt_obj;
12         int err, pkt_fd, i;
13         struct bpf_link **link = NULL;
14         struct bpf_program **prog = NULL;
15         __u32 duration = 0, retval;
16         struct bpf_map *data_map;
17         const int zero = 0;
18         u64 *result = NULL;
19
20         err = bpf_prog_load(target_obj_file, BPF_PROG_TYPE_UNSPEC,
21                             &pkt_obj, &pkt_fd);
22         if (CHECK(err, "tgt_prog_load", "file %s err %d errno %d\n",
23                   target_obj_file, err, errno))
24                 return;
25         DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts,
26                             .attach_prog_fd = pkt_fd,
27                            );
28
29         link = calloc(sizeof(struct bpf_link *), prog_cnt);
30         prog = calloc(sizeof(struct bpf_program *), prog_cnt);
31         result = malloc((prog_cnt + 32 /* spare */) * sizeof(u64));
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);
37         if (CHECK(IS_ERR_OR_NULL(obj), "obj_open",
38                   "failed to open %s: %ld\n", obj_file,
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
46         for (i = 0; i < prog_cnt; i++) {
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         }
54
55         if (!run_prog)
56                 goto close_prog;
57
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
68         err = bpf_map_lookup_elem(bpf_map__fd(data_map), &zero, result);
69         if (CHECK(err, "get_result",
70                   "failed to get output data: %d\n", err))
71                 goto close_prog;
72
73         for (i = 0; i < prog_cnt; i++)
74                 if (CHECK(result[i] != 1, "result", "fexit_bpf2bpf failed err %ld\n",
75                           result[i]))
76                         goto close_prog;
77
78 close_prog:
79         for (i = 0; i < prog_cnt; i++)
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);
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),
98                                   prog_name, true);
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",
107                 "fexit/test_pkt_access_subprog3",
108         };
109         test_fexit_bpf2bpf_common("./fexit_bpf2bpf.o",
110                                   "./test_pkt_access.o",
111                                   ARRAY_SIZE(prog_name),
112                                   prog_name, true);
113 }
114
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),
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);
141 }
142
143 void test_fexit_bpf2bpf(void)
144 {
145         test_target_no_callees();
146         test_target_yes_callees();
147         test_func_replace();
148         test_func_replace_verify();
149 }