]> asedeno.scripts.mit.edu Git - linux.git/blob - tools/testing/selftests/bpf/test_progs.c
selftests/bpf: add test cases for queue and stack maps
[linux.git] / tools / testing / selftests / bpf / test_progs.c
1 /* Copyright (c) 2017 Facebook
2  *
3  * This program is free software; you can redistribute it and/or
4  * modify it under the terms of version 2 of the GNU General Public
5  * License as published by the Free Software Foundation.
6  */
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <errno.h>
10 #include <string.h>
11 #include <assert.h>
12 #include <stdlib.h>
13 #include <time.h>
14
15 #include <linux/types.h>
16 typedef __u16 __sum16;
17 #include <arpa/inet.h>
18 #include <linux/if_ether.h>
19 #include <linux/if_packet.h>
20 #include <linux/ip.h>
21 #include <linux/ipv6.h>
22 #include <linux/tcp.h>
23 #include <linux/filter.h>
24 #include <linux/perf_event.h>
25 #include <linux/unistd.h>
26
27 #include <sys/ioctl.h>
28 #include <sys/wait.h>
29 #include <sys/types.h>
30 #include <fcntl.h>
31
32 #include <linux/bpf.h>
33 #include <linux/err.h>
34 #include <bpf/bpf.h>
35 #include <bpf/libbpf.h>
36
37 #include "test_iptunnel_common.h"
38 #include "bpf_util.h"
39 #include "bpf_endian.h"
40 #include "bpf_rlimit.h"
41 #include "trace_helpers.h"
42
43 static int error_cnt, pass_cnt;
44 static bool jit_enabled;
45
46 #define MAGIC_BYTES 123
47
48 /* ipv4 test vector */
49 static struct {
50         struct ethhdr eth;
51         struct iphdr iph;
52         struct tcphdr tcp;
53 } __packed pkt_v4 = {
54         .eth.h_proto = bpf_htons(ETH_P_IP),
55         .iph.ihl = 5,
56         .iph.protocol = 6,
57         .iph.tot_len = bpf_htons(MAGIC_BYTES),
58         .tcp.urg_ptr = 123,
59 };
60
61 /* ipv6 test vector */
62 static struct {
63         struct ethhdr eth;
64         struct ipv6hdr iph;
65         struct tcphdr tcp;
66 } __packed pkt_v6 = {
67         .eth.h_proto = bpf_htons(ETH_P_IPV6),
68         .iph.nexthdr = 6,
69         .iph.payload_len = bpf_htons(MAGIC_BYTES),
70         .tcp.urg_ptr = 123,
71 };
72
73 #define CHECK(condition, tag, format...) ({                             \
74         int __ret = !!(condition);                                      \
75         if (__ret) {                                                    \
76                 error_cnt++;                                            \
77                 printf("%s:FAIL:%s ", __func__, tag);                   \
78                 printf(format);                                         \
79         } else {                                                        \
80                 pass_cnt++;                                             \
81                 printf("%s:PASS:%s %d nsec\n", __func__, tag, duration);\
82         }                                                               \
83         __ret;                                                          \
84 })
85
86 static int bpf_find_map(const char *test, struct bpf_object *obj,
87                         const char *name)
88 {
89         struct bpf_map *map;
90
91         map = bpf_object__find_map_by_name(obj, name);
92         if (!map) {
93                 printf("%s:FAIL:map '%s' not found\n", test, name);
94                 error_cnt++;
95                 return -1;
96         }
97         return bpf_map__fd(map);
98 }
99
100 static void test_pkt_access(void)
101 {
102         const char *file = "./test_pkt_access.o";
103         struct bpf_object *obj;
104         __u32 duration, retval;
105         int err, prog_fd;
106
107         err = bpf_prog_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd);
108         if (err) {
109                 error_cnt++;
110                 return;
111         }
112
113         err = bpf_prog_test_run(prog_fd, 100000, &pkt_v4, sizeof(pkt_v4),
114                                 NULL, NULL, &retval, &duration);
115         CHECK(err || retval, "ipv4",
116               "err %d errno %d retval %d duration %d\n",
117               err, errno, retval, duration);
118
119         err = bpf_prog_test_run(prog_fd, 100000, &pkt_v6, sizeof(pkt_v6),
120                                 NULL, NULL, &retval, &duration);
121         CHECK(err || retval, "ipv6",
122               "err %d errno %d retval %d duration %d\n",
123               err, errno, retval, duration);
124         bpf_object__close(obj);
125 }
126
127 static void test_xdp(void)
128 {
129         struct vip key4 = {.protocol = 6, .family = AF_INET};
130         struct vip key6 = {.protocol = 6, .family = AF_INET6};
131         struct iptnl_info value4 = {.family = AF_INET};
132         struct iptnl_info value6 = {.family = AF_INET6};
133         const char *file = "./test_xdp.o";
134         struct bpf_object *obj;
135         char buf[128];
136         struct ipv6hdr *iph6 = (void *)buf + sizeof(struct ethhdr);
137         struct iphdr *iph = (void *)buf + sizeof(struct ethhdr);
138         __u32 duration, retval, size;
139         int err, prog_fd, map_fd;
140
141         err = bpf_prog_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd);
142         if (err) {
143                 error_cnt++;
144                 return;
145         }
146
147         map_fd = bpf_find_map(__func__, obj, "vip2tnl");
148         if (map_fd < 0)
149                 goto out;
150         bpf_map_update_elem(map_fd, &key4, &value4, 0);
151         bpf_map_update_elem(map_fd, &key6, &value6, 0);
152
153         err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4),
154                                 buf, &size, &retval, &duration);
155
156         CHECK(err || retval != XDP_TX || size != 74 ||
157               iph->protocol != IPPROTO_IPIP, "ipv4",
158               "err %d errno %d retval %d size %d\n",
159               err, errno, retval, size);
160
161         err = bpf_prog_test_run(prog_fd, 1, &pkt_v6, sizeof(pkt_v6),
162                                 buf, &size, &retval, &duration);
163         CHECK(err || retval != XDP_TX || size != 114 ||
164               iph6->nexthdr != IPPROTO_IPV6, "ipv6",
165               "err %d errno %d retval %d size %d\n",
166               err, errno, retval, size);
167 out:
168         bpf_object__close(obj);
169 }
170
171 static void test_xdp_adjust_tail(void)
172 {
173         const char *file = "./test_adjust_tail.o";
174         struct bpf_object *obj;
175         char buf[128];
176         __u32 duration, retval, size;
177         int err, prog_fd;
178
179         err = bpf_prog_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd);
180         if (err) {
181                 error_cnt++;
182                 return;
183         }
184
185         err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4),
186                                 buf, &size, &retval, &duration);
187
188         CHECK(err || retval != XDP_DROP,
189               "ipv4", "err %d errno %d retval %d size %d\n",
190               err, errno, retval, size);
191
192         err = bpf_prog_test_run(prog_fd, 1, &pkt_v6, sizeof(pkt_v6),
193                                 buf, &size, &retval, &duration);
194         CHECK(err || retval != XDP_TX || size != 54,
195               "ipv6", "err %d errno %d retval %d size %d\n",
196               err, errno, retval, size);
197         bpf_object__close(obj);
198 }
199
200
201
202 #define MAGIC_VAL 0x1234
203 #define NUM_ITER 100000
204 #define VIP_NUM 5
205
206 static void test_l4lb(const char *file)
207 {
208         unsigned int nr_cpus = bpf_num_possible_cpus();
209         struct vip key = {.protocol = 6};
210         struct vip_meta {
211                 __u32 flags;
212                 __u32 vip_num;
213         } value = {.vip_num = VIP_NUM};
214         __u32 stats_key = VIP_NUM;
215         struct vip_stats {
216                 __u64 bytes;
217                 __u64 pkts;
218         } stats[nr_cpus];
219         struct real_definition {
220                 union {
221                         __be32 dst;
222                         __be32 dstv6[4];
223                 };
224                 __u8 flags;
225         } real_def = {.dst = MAGIC_VAL};
226         __u32 ch_key = 11, real_num = 3;
227         __u32 duration, retval, size;
228         int err, i, prog_fd, map_fd;
229         __u64 bytes = 0, pkts = 0;
230         struct bpf_object *obj;
231         char buf[128];
232         u32 *magic = (u32 *)buf;
233
234         err = bpf_prog_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd);
235         if (err) {
236                 error_cnt++;
237                 return;
238         }
239
240         map_fd = bpf_find_map(__func__, obj, "vip_map");
241         if (map_fd < 0)
242                 goto out;
243         bpf_map_update_elem(map_fd, &key, &value, 0);
244
245         map_fd = bpf_find_map(__func__, obj, "ch_rings");
246         if (map_fd < 0)
247                 goto out;
248         bpf_map_update_elem(map_fd, &ch_key, &real_num, 0);
249
250         map_fd = bpf_find_map(__func__, obj, "reals");
251         if (map_fd < 0)
252                 goto out;
253         bpf_map_update_elem(map_fd, &real_num, &real_def, 0);
254
255         err = bpf_prog_test_run(prog_fd, NUM_ITER, &pkt_v4, sizeof(pkt_v4),
256                                 buf, &size, &retval, &duration);
257         CHECK(err || retval != 7/*TC_ACT_REDIRECT*/ || size != 54 ||
258               *magic != MAGIC_VAL, "ipv4",
259               "err %d errno %d retval %d size %d magic %x\n",
260               err, errno, retval, size, *magic);
261
262         err = bpf_prog_test_run(prog_fd, NUM_ITER, &pkt_v6, sizeof(pkt_v6),
263                                 buf, &size, &retval, &duration);
264         CHECK(err || retval != 7/*TC_ACT_REDIRECT*/ || size != 74 ||
265               *magic != MAGIC_VAL, "ipv6",
266               "err %d errno %d retval %d size %d magic %x\n",
267               err, errno, retval, size, *magic);
268
269         map_fd = bpf_find_map(__func__, obj, "stats");
270         if (map_fd < 0)
271                 goto out;
272         bpf_map_lookup_elem(map_fd, &stats_key, stats);
273         for (i = 0; i < nr_cpus; i++) {
274                 bytes += stats[i].bytes;
275                 pkts += stats[i].pkts;
276         }
277         if (bytes != MAGIC_BYTES * NUM_ITER * 2 || pkts != NUM_ITER * 2) {
278                 error_cnt++;
279                 printf("test_l4lb:FAIL:stats %lld %lld\n", bytes, pkts);
280         }
281 out:
282         bpf_object__close(obj);
283 }
284
285 static void test_l4lb_all(void)
286 {
287         const char *file1 = "./test_l4lb.o";
288         const char *file2 = "./test_l4lb_noinline.o";
289
290         test_l4lb(file1);
291         test_l4lb(file2);
292 }
293
294 static void test_xdp_noinline(void)
295 {
296         const char *file = "./test_xdp_noinline.o";
297         unsigned int nr_cpus = bpf_num_possible_cpus();
298         struct vip key = {.protocol = 6};
299         struct vip_meta {
300                 __u32 flags;
301                 __u32 vip_num;
302         } value = {.vip_num = VIP_NUM};
303         __u32 stats_key = VIP_NUM;
304         struct vip_stats {
305                 __u64 bytes;
306                 __u64 pkts;
307         } stats[nr_cpus];
308         struct real_definition {
309                 union {
310                         __be32 dst;
311                         __be32 dstv6[4];
312                 };
313                 __u8 flags;
314         } real_def = {.dst = MAGIC_VAL};
315         __u32 ch_key = 11, real_num = 3;
316         __u32 duration, retval, size;
317         int err, i, prog_fd, map_fd;
318         __u64 bytes = 0, pkts = 0;
319         struct bpf_object *obj;
320         char buf[128];
321         u32 *magic = (u32 *)buf;
322
323         err = bpf_prog_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd);
324         if (err) {
325                 error_cnt++;
326                 return;
327         }
328
329         map_fd = bpf_find_map(__func__, obj, "vip_map");
330         if (map_fd < 0)
331                 goto out;
332         bpf_map_update_elem(map_fd, &key, &value, 0);
333
334         map_fd = bpf_find_map(__func__, obj, "ch_rings");
335         if (map_fd < 0)
336                 goto out;
337         bpf_map_update_elem(map_fd, &ch_key, &real_num, 0);
338
339         map_fd = bpf_find_map(__func__, obj, "reals");
340         if (map_fd < 0)
341                 goto out;
342         bpf_map_update_elem(map_fd, &real_num, &real_def, 0);
343
344         err = bpf_prog_test_run(prog_fd, NUM_ITER, &pkt_v4, sizeof(pkt_v4),
345                                 buf, &size, &retval, &duration);
346         CHECK(err || retval != 1 || size != 54 ||
347               *magic != MAGIC_VAL, "ipv4",
348               "err %d errno %d retval %d size %d magic %x\n",
349               err, errno, retval, size, *magic);
350
351         err = bpf_prog_test_run(prog_fd, NUM_ITER, &pkt_v6, sizeof(pkt_v6),
352                                 buf, &size, &retval, &duration);
353         CHECK(err || retval != 1 || size != 74 ||
354               *magic != MAGIC_VAL, "ipv6",
355               "err %d errno %d retval %d size %d magic %x\n",
356               err, errno, retval, size, *magic);
357
358         map_fd = bpf_find_map(__func__, obj, "stats");
359         if (map_fd < 0)
360                 goto out;
361         bpf_map_lookup_elem(map_fd, &stats_key, stats);
362         for (i = 0; i < nr_cpus; i++) {
363                 bytes += stats[i].bytes;
364                 pkts += stats[i].pkts;
365         }
366         if (bytes != MAGIC_BYTES * NUM_ITER * 2 || pkts != NUM_ITER * 2) {
367                 error_cnt++;
368                 printf("test_xdp_noinline:FAIL:stats %lld %lld\n", bytes, pkts);
369         }
370 out:
371         bpf_object__close(obj);
372 }
373
374 static void test_tcp_estats(void)
375 {
376         const char *file = "./test_tcp_estats.o";
377         int err, prog_fd;
378         struct bpf_object *obj;
379         __u32 duration = 0;
380
381         err = bpf_prog_load(file, BPF_PROG_TYPE_TRACEPOINT, &obj, &prog_fd);
382         CHECK(err, "", "err %d errno %d\n", err, errno);
383         if (err) {
384                 error_cnt++;
385                 return;
386         }
387
388         bpf_object__close(obj);
389 }
390
391 static inline __u64 ptr_to_u64(const void *ptr)
392 {
393         return (__u64) (unsigned long) ptr;
394 }
395
396 static bool is_jit_enabled(void)
397 {
398         const char *jit_sysctl = "/proc/sys/net/core/bpf_jit_enable";
399         bool enabled = false;
400         int sysctl_fd;
401
402         sysctl_fd = open(jit_sysctl, 0, O_RDONLY);
403         if (sysctl_fd != -1) {
404                 char tmpc;
405
406                 if (read(sysctl_fd, &tmpc, sizeof(tmpc)) == 1)
407                         enabled = (tmpc != '0');
408                 close(sysctl_fd);
409         }
410
411         return enabled;
412 }
413
414 static void test_bpf_obj_id(void)
415 {
416         const __u64 array_magic_value = 0xfaceb00c;
417         const __u32 array_key = 0;
418         const int nr_iters = 2;
419         const char *file = "./test_obj_id.o";
420         const char *expected_prog_name = "test_obj_id";
421         const char *expected_map_name = "test_map_id";
422         const __u64 nsec_per_sec = 1000000000;
423
424         struct bpf_object *objs[nr_iters];
425         int prog_fds[nr_iters], map_fds[nr_iters];
426         /* +1 to test for the info_len returned by kernel */
427         struct bpf_prog_info prog_infos[nr_iters + 1];
428         struct bpf_map_info map_infos[nr_iters + 1];
429         /* Each prog only uses one map. +1 to test nr_map_ids
430          * returned by kernel.
431          */
432         __u32 map_ids[nr_iters + 1];
433         char jited_insns[128], xlated_insns[128], zeros[128];
434         __u32 i, next_id, info_len, nr_id_found, duration = 0;
435         struct timespec real_time_ts, boot_time_ts;
436         int err = 0;
437         __u64 array_value;
438         uid_t my_uid = getuid();
439         time_t now, load_time;
440
441         err = bpf_prog_get_fd_by_id(0);
442         CHECK(err >= 0 || errno != ENOENT,
443               "get-fd-by-notexist-prog-id", "err %d errno %d\n", err, errno);
444
445         err = bpf_map_get_fd_by_id(0);
446         CHECK(err >= 0 || errno != ENOENT,
447               "get-fd-by-notexist-map-id", "err %d errno %d\n", err, errno);
448
449         for (i = 0; i < nr_iters; i++)
450                 objs[i] = NULL;
451
452         /* Check bpf_obj_get_info_by_fd() */
453         bzero(zeros, sizeof(zeros));
454         for (i = 0; i < nr_iters; i++) {
455                 now = time(NULL);
456                 err = bpf_prog_load(file, BPF_PROG_TYPE_SOCKET_FILTER,
457                                     &objs[i], &prog_fds[i]);
458                 /* test_obj_id.o is a dumb prog. It should never fail
459                  * to load.
460                  */
461                 if (err)
462                         error_cnt++;
463                 assert(!err);
464
465                 /* Insert a magic value to the map */
466                 map_fds[i] = bpf_find_map(__func__, objs[i], "test_map_id");
467                 assert(map_fds[i] >= 0);
468                 err = bpf_map_update_elem(map_fds[i], &array_key,
469                                           &array_magic_value, 0);
470                 assert(!err);
471
472                 /* Check getting map info */
473                 info_len = sizeof(struct bpf_map_info) * 2;
474                 bzero(&map_infos[i], info_len);
475                 err = bpf_obj_get_info_by_fd(map_fds[i], &map_infos[i],
476                                              &info_len);
477                 if (CHECK(err ||
478                           map_infos[i].type != BPF_MAP_TYPE_ARRAY ||
479                           map_infos[i].key_size != sizeof(__u32) ||
480                           map_infos[i].value_size != sizeof(__u64) ||
481                           map_infos[i].max_entries != 1 ||
482                           map_infos[i].map_flags != 0 ||
483                           info_len != sizeof(struct bpf_map_info) ||
484                           strcmp((char *)map_infos[i].name, expected_map_name),
485                           "get-map-info(fd)",
486                           "err %d errno %d type %d(%d) info_len %u(%Zu) key_size %u value_size %u max_entries %u map_flags %X name %s(%s)\n",
487                           err, errno,
488                           map_infos[i].type, BPF_MAP_TYPE_ARRAY,
489                           info_len, sizeof(struct bpf_map_info),
490                           map_infos[i].key_size,
491                           map_infos[i].value_size,
492                           map_infos[i].max_entries,
493                           map_infos[i].map_flags,
494                           map_infos[i].name, expected_map_name))
495                         goto done;
496
497                 /* Check getting prog info */
498                 info_len = sizeof(struct bpf_prog_info) * 2;
499                 bzero(&prog_infos[i], info_len);
500                 bzero(jited_insns, sizeof(jited_insns));
501                 bzero(xlated_insns, sizeof(xlated_insns));
502                 prog_infos[i].jited_prog_insns = ptr_to_u64(jited_insns);
503                 prog_infos[i].jited_prog_len = sizeof(jited_insns);
504                 prog_infos[i].xlated_prog_insns = ptr_to_u64(xlated_insns);
505                 prog_infos[i].xlated_prog_len = sizeof(xlated_insns);
506                 prog_infos[i].map_ids = ptr_to_u64(map_ids + i);
507                 prog_infos[i].nr_map_ids = 2;
508                 err = clock_gettime(CLOCK_REALTIME, &real_time_ts);
509                 assert(!err);
510                 err = clock_gettime(CLOCK_BOOTTIME, &boot_time_ts);
511                 assert(!err);
512                 err = bpf_obj_get_info_by_fd(prog_fds[i], &prog_infos[i],
513                                              &info_len);
514                 load_time = (real_time_ts.tv_sec - boot_time_ts.tv_sec)
515                         + (prog_infos[i].load_time / nsec_per_sec);
516                 if (CHECK(err ||
517                           prog_infos[i].type != BPF_PROG_TYPE_SOCKET_FILTER ||
518                           info_len != sizeof(struct bpf_prog_info) ||
519                           (jit_enabled && !prog_infos[i].jited_prog_len) ||
520                           (jit_enabled &&
521                            !memcmp(jited_insns, zeros, sizeof(zeros))) ||
522                           !prog_infos[i].xlated_prog_len ||
523                           !memcmp(xlated_insns, zeros, sizeof(zeros)) ||
524                           load_time < now - 60 || load_time > now + 60 ||
525                           prog_infos[i].created_by_uid != my_uid ||
526                           prog_infos[i].nr_map_ids != 1 ||
527                           *(int *)prog_infos[i].map_ids != map_infos[i].id ||
528                           strcmp((char *)prog_infos[i].name, expected_prog_name),
529                           "get-prog-info(fd)",
530                           "err %d errno %d i %d type %d(%d) info_len %u(%Zu) jit_enabled %d jited_prog_len %u xlated_prog_len %u jited_prog %d xlated_prog %d load_time %lu(%lu) uid %u(%u) nr_map_ids %u(%u) map_id %u(%u) name %s(%s)\n",
531                           err, errno, i,
532                           prog_infos[i].type, BPF_PROG_TYPE_SOCKET_FILTER,
533                           info_len, sizeof(struct bpf_prog_info),
534                           jit_enabled,
535                           prog_infos[i].jited_prog_len,
536                           prog_infos[i].xlated_prog_len,
537                           !!memcmp(jited_insns, zeros, sizeof(zeros)),
538                           !!memcmp(xlated_insns, zeros, sizeof(zeros)),
539                           load_time, now,
540                           prog_infos[i].created_by_uid, my_uid,
541                           prog_infos[i].nr_map_ids, 1,
542                           *(int *)prog_infos[i].map_ids, map_infos[i].id,
543                           prog_infos[i].name, expected_prog_name))
544                         goto done;
545         }
546
547         /* Check bpf_prog_get_next_id() */
548         nr_id_found = 0;
549         next_id = 0;
550         while (!bpf_prog_get_next_id(next_id, &next_id)) {
551                 struct bpf_prog_info prog_info = {};
552                 __u32 saved_map_id;
553                 int prog_fd;
554
555                 info_len = sizeof(prog_info);
556
557                 prog_fd = bpf_prog_get_fd_by_id(next_id);
558                 if (prog_fd < 0 && errno == ENOENT)
559                         /* The bpf_prog is in the dead row */
560                         continue;
561                 if (CHECK(prog_fd < 0, "get-prog-fd(next_id)",
562                           "prog_fd %d next_id %d errno %d\n",
563                           prog_fd, next_id, errno))
564                         break;
565
566                 for (i = 0; i < nr_iters; i++)
567                         if (prog_infos[i].id == next_id)
568                                 break;
569
570                 if (i == nr_iters)
571                         continue;
572
573                 nr_id_found++;
574
575                 /* Negative test:
576                  * prog_info.nr_map_ids = 1
577                  * prog_info.map_ids = NULL
578                  */
579                 prog_info.nr_map_ids = 1;
580                 err = bpf_obj_get_info_by_fd(prog_fd, &prog_info, &info_len);
581                 if (CHECK(!err || errno != EFAULT,
582                           "get-prog-fd-bad-nr-map-ids", "err %d errno %d(%d)",
583                           err, errno, EFAULT))
584                         break;
585                 bzero(&prog_info, sizeof(prog_info));
586                 info_len = sizeof(prog_info);
587
588                 saved_map_id = *(int *)(prog_infos[i].map_ids);
589                 prog_info.map_ids = prog_infos[i].map_ids;
590                 prog_info.nr_map_ids = 2;
591                 err = bpf_obj_get_info_by_fd(prog_fd, &prog_info, &info_len);
592                 prog_infos[i].jited_prog_insns = 0;
593                 prog_infos[i].xlated_prog_insns = 0;
594                 CHECK(err || info_len != sizeof(struct bpf_prog_info) ||
595                       memcmp(&prog_info, &prog_infos[i], info_len) ||
596                       *(int *)prog_info.map_ids != saved_map_id,
597                       "get-prog-info(next_id->fd)",
598                       "err %d errno %d info_len %u(%Zu) memcmp %d map_id %u(%u)\n",
599                       err, errno, info_len, sizeof(struct bpf_prog_info),
600                       memcmp(&prog_info, &prog_infos[i], info_len),
601                       *(int *)prog_info.map_ids, saved_map_id);
602                 close(prog_fd);
603         }
604         CHECK(nr_id_found != nr_iters,
605               "check total prog id found by get_next_id",
606               "nr_id_found %u(%u)\n",
607               nr_id_found, nr_iters);
608
609         /* Check bpf_map_get_next_id() */
610         nr_id_found = 0;
611         next_id = 0;
612         while (!bpf_map_get_next_id(next_id, &next_id)) {
613                 struct bpf_map_info map_info = {};
614                 int map_fd;
615
616                 info_len = sizeof(map_info);
617
618                 map_fd = bpf_map_get_fd_by_id(next_id);
619                 if (map_fd < 0 && errno == ENOENT)
620                         /* The bpf_map is in the dead row */
621                         continue;
622                 if (CHECK(map_fd < 0, "get-map-fd(next_id)",
623                           "map_fd %d next_id %u errno %d\n",
624                           map_fd, next_id, errno))
625                         break;
626
627                 for (i = 0; i < nr_iters; i++)
628                         if (map_infos[i].id == next_id)
629                                 break;
630
631                 if (i == nr_iters)
632                         continue;
633
634                 nr_id_found++;
635
636                 err = bpf_map_lookup_elem(map_fd, &array_key, &array_value);
637                 assert(!err);
638
639                 err = bpf_obj_get_info_by_fd(map_fd, &map_info, &info_len);
640                 CHECK(err || info_len != sizeof(struct bpf_map_info) ||
641                       memcmp(&map_info, &map_infos[i], info_len) ||
642                       array_value != array_magic_value,
643                       "check get-map-info(next_id->fd)",
644                       "err %d errno %d info_len %u(%Zu) memcmp %d array_value %llu(%llu)\n",
645                       err, errno, info_len, sizeof(struct bpf_map_info),
646                       memcmp(&map_info, &map_infos[i], info_len),
647                       array_value, array_magic_value);
648
649                 close(map_fd);
650         }
651         CHECK(nr_id_found != nr_iters,
652               "check total map id found by get_next_id",
653               "nr_id_found %u(%u)\n",
654               nr_id_found, nr_iters);
655
656 done:
657         for (i = 0; i < nr_iters; i++)
658                 bpf_object__close(objs[i]);
659 }
660
661 static void test_pkt_md_access(void)
662 {
663         const char *file = "./test_pkt_md_access.o";
664         struct bpf_object *obj;
665         __u32 duration, retval;
666         int err, prog_fd;
667
668         err = bpf_prog_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd);
669         if (err) {
670                 error_cnt++;
671                 return;
672         }
673
674         err = bpf_prog_test_run(prog_fd, 10, &pkt_v4, sizeof(pkt_v4),
675                                 NULL, NULL, &retval, &duration);
676         CHECK(err || retval, "",
677               "err %d errno %d retval %d duration %d\n",
678               err, errno, retval, duration);
679
680         bpf_object__close(obj);
681 }
682
683 static void test_obj_name(void)
684 {
685         struct {
686                 const char *name;
687                 int success;
688                 int expected_errno;
689         } tests[] = {
690                 { "", 1, 0 },
691                 { "_123456789ABCDE", 1, 0 },
692                 { "_123456789ABCDEF", 0, EINVAL },
693                 { "_123456789ABCD\n", 0, EINVAL },
694         };
695         struct bpf_insn prog[] = {
696                 BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),
697                 BPF_EXIT_INSN(),
698         };
699         __u32 duration = 0;
700         int i;
701
702         for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
703                 size_t name_len = strlen(tests[i].name) + 1;
704                 union bpf_attr attr;
705                 size_t ncopy;
706                 int fd;
707
708                 /* test different attr.prog_name during BPF_PROG_LOAD */
709                 ncopy = name_len < sizeof(attr.prog_name) ?
710                         name_len : sizeof(attr.prog_name);
711                 bzero(&attr, sizeof(attr));
712                 attr.prog_type = BPF_PROG_TYPE_SCHED_CLS;
713                 attr.insn_cnt = 2;
714                 attr.insns = ptr_to_u64(prog);
715                 attr.license = ptr_to_u64("");
716                 memcpy(attr.prog_name, tests[i].name, ncopy);
717
718                 fd = syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
719                 CHECK((tests[i].success && fd < 0) ||
720                       (!tests[i].success && fd != -1) ||
721                       (!tests[i].success && errno != tests[i].expected_errno),
722                       "check-bpf-prog-name",
723                       "fd %d(%d) errno %d(%d)\n",
724                        fd, tests[i].success, errno, tests[i].expected_errno);
725
726                 if (fd != -1)
727                         close(fd);
728
729                 /* test different attr.map_name during BPF_MAP_CREATE */
730                 ncopy = name_len < sizeof(attr.map_name) ?
731                         name_len : sizeof(attr.map_name);
732                 bzero(&attr, sizeof(attr));
733                 attr.map_type = BPF_MAP_TYPE_ARRAY;
734                 attr.key_size = 4;
735                 attr.value_size = 4;
736                 attr.max_entries = 1;
737                 attr.map_flags = 0;
738                 memcpy(attr.map_name, tests[i].name, ncopy);
739                 fd = syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr));
740                 CHECK((tests[i].success && fd < 0) ||
741                       (!tests[i].success && fd != -1) ||
742                       (!tests[i].success && errno != tests[i].expected_errno),
743                       "check-bpf-map-name",
744                       "fd %d(%d) errno %d(%d)\n",
745                       fd, tests[i].success, errno, tests[i].expected_errno);
746
747                 if (fd != -1)
748                         close(fd);
749         }
750 }
751
752 static void test_tp_attach_query(void)
753 {
754         const int num_progs = 3;
755         int i, j, bytes, efd, err, prog_fd[num_progs], pmu_fd[num_progs];
756         __u32 duration = 0, info_len, saved_prog_ids[num_progs];
757         const char *file = "./test_tracepoint.o";
758         struct perf_event_query_bpf *query;
759         struct perf_event_attr attr = {};
760         struct bpf_object *obj[num_progs];
761         struct bpf_prog_info prog_info;
762         char buf[256];
763
764         snprintf(buf, sizeof(buf),
765                  "/sys/kernel/debug/tracing/events/sched/sched_switch/id");
766         efd = open(buf, O_RDONLY, 0);
767         if (CHECK(efd < 0, "open", "err %d errno %d\n", efd, errno))
768                 return;
769         bytes = read(efd, buf, sizeof(buf));
770         close(efd);
771         if (CHECK(bytes <= 0 || bytes >= sizeof(buf),
772                   "read", "bytes %d errno %d\n", bytes, errno))
773                 return;
774
775         attr.config = strtol(buf, NULL, 0);
776         attr.type = PERF_TYPE_TRACEPOINT;
777         attr.sample_type = PERF_SAMPLE_RAW | PERF_SAMPLE_CALLCHAIN;
778         attr.sample_period = 1;
779         attr.wakeup_events = 1;
780
781         query = malloc(sizeof(*query) + sizeof(__u32) * num_progs);
782         for (i = 0; i < num_progs; i++) {
783                 err = bpf_prog_load(file, BPF_PROG_TYPE_TRACEPOINT, &obj[i],
784                                     &prog_fd[i]);
785                 if (CHECK(err, "prog_load", "err %d errno %d\n", err, errno))
786                         goto cleanup1;
787
788                 bzero(&prog_info, sizeof(prog_info));
789                 prog_info.jited_prog_len = 0;
790                 prog_info.xlated_prog_len = 0;
791                 prog_info.nr_map_ids = 0;
792                 info_len = sizeof(prog_info);
793                 err = bpf_obj_get_info_by_fd(prog_fd[i], &prog_info, &info_len);
794                 if (CHECK(err, "bpf_obj_get_info_by_fd", "err %d errno %d\n",
795                           err, errno))
796                         goto cleanup1;
797                 saved_prog_ids[i] = prog_info.id;
798
799                 pmu_fd[i] = syscall(__NR_perf_event_open, &attr, -1 /* pid */,
800                                     0 /* cpu 0 */, -1 /* group id */,
801                                     0 /* flags */);
802                 if (CHECK(pmu_fd[i] < 0, "perf_event_open", "err %d errno %d\n",
803                           pmu_fd[i], errno))
804                         goto cleanup2;
805                 err = ioctl(pmu_fd[i], PERF_EVENT_IOC_ENABLE, 0);
806                 if (CHECK(err, "perf_event_ioc_enable", "err %d errno %d\n",
807                           err, errno))
808                         goto cleanup3;
809
810                 if (i == 0) {
811                         /* check NULL prog array query */
812                         query->ids_len = num_progs;
813                         err = ioctl(pmu_fd[i], PERF_EVENT_IOC_QUERY_BPF, query);
814                         if (CHECK(err || query->prog_cnt != 0,
815                                   "perf_event_ioc_query_bpf",
816                                   "err %d errno %d query->prog_cnt %u\n",
817                                   err, errno, query->prog_cnt))
818                                 goto cleanup3;
819                 }
820
821                 err = ioctl(pmu_fd[i], PERF_EVENT_IOC_SET_BPF, prog_fd[i]);
822                 if (CHECK(err, "perf_event_ioc_set_bpf", "err %d errno %d\n",
823                           err, errno))
824                         goto cleanup3;
825
826                 if (i == 1) {
827                         /* try to get # of programs only */
828                         query->ids_len = 0;
829                         err = ioctl(pmu_fd[i], PERF_EVENT_IOC_QUERY_BPF, query);
830                         if (CHECK(err || query->prog_cnt != 2,
831                                   "perf_event_ioc_query_bpf",
832                                   "err %d errno %d query->prog_cnt %u\n",
833                                   err, errno, query->prog_cnt))
834                                 goto cleanup3;
835
836                         /* try a few negative tests */
837                         /* invalid query pointer */
838                         err = ioctl(pmu_fd[i], PERF_EVENT_IOC_QUERY_BPF,
839                                     (struct perf_event_query_bpf *)0x1);
840                         if (CHECK(!err || errno != EFAULT,
841                                   "perf_event_ioc_query_bpf",
842                                   "err %d errno %d\n", err, errno))
843                                 goto cleanup3;
844
845                         /* no enough space */
846                         query->ids_len = 1;
847                         err = ioctl(pmu_fd[i], PERF_EVENT_IOC_QUERY_BPF, query);
848                         if (CHECK(!err || errno != ENOSPC || query->prog_cnt != 2,
849                                   "perf_event_ioc_query_bpf",
850                                   "err %d errno %d query->prog_cnt %u\n",
851                                   err, errno, query->prog_cnt))
852                                 goto cleanup3;
853                 }
854
855                 query->ids_len = num_progs;
856                 err = ioctl(pmu_fd[i], PERF_EVENT_IOC_QUERY_BPF, query);
857                 if (CHECK(err || query->prog_cnt != (i + 1),
858                           "perf_event_ioc_query_bpf",
859                           "err %d errno %d query->prog_cnt %u\n",
860                           err, errno, query->prog_cnt))
861                         goto cleanup3;
862                 for (j = 0; j < i + 1; j++)
863                         if (CHECK(saved_prog_ids[j] != query->ids[j],
864                                   "perf_event_ioc_query_bpf",
865                                   "#%d saved_prog_id %x query prog_id %x\n",
866                                   j, saved_prog_ids[j], query->ids[j]))
867                                 goto cleanup3;
868         }
869
870         i = num_progs - 1;
871         for (; i >= 0; i--) {
872  cleanup3:
873                 ioctl(pmu_fd[i], PERF_EVENT_IOC_DISABLE);
874  cleanup2:
875                 close(pmu_fd[i]);
876  cleanup1:
877                 bpf_object__close(obj[i]);
878         }
879         free(query);
880 }
881
882 static int compare_map_keys(int map1_fd, int map2_fd)
883 {
884         __u32 key, next_key;
885         char val_buf[PERF_MAX_STACK_DEPTH *
886                      sizeof(struct bpf_stack_build_id)];
887         int err;
888
889         err = bpf_map_get_next_key(map1_fd, NULL, &key);
890         if (err)
891                 return err;
892         err = bpf_map_lookup_elem(map2_fd, &key, val_buf);
893         if (err)
894                 return err;
895
896         while (bpf_map_get_next_key(map1_fd, &key, &next_key) == 0) {
897                 err = bpf_map_lookup_elem(map2_fd, &next_key, val_buf);
898                 if (err)
899                         return err;
900
901                 key = next_key;
902         }
903         if (errno != ENOENT)
904                 return -1;
905
906         return 0;
907 }
908
909 static int compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len)
910 {
911         __u32 key, next_key, *cur_key_p, *next_key_p;
912         char *val_buf1, *val_buf2;
913         int i, err = 0;
914
915         val_buf1 = malloc(stack_trace_len);
916         val_buf2 = malloc(stack_trace_len);
917         cur_key_p = NULL;
918         next_key_p = &key;
919         while (bpf_map_get_next_key(smap_fd, cur_key_p, next_key_p) == 0) {
920                 err = bpf_map_lookup_elem(smap_fd, next_key_p, val_buf1);
921                 if (err)
922                         goto out;
923                 err = bpf_map_lookup_elem(amap_fd, next_key_p, val_buf2);
924                 if (err)
925                         goto out;
926                 for (i = 0; i < stack_trace_len; i++) {
927                         if (val_buf1[i] != val_buf2[i]) {
928                                 err = -1;
929                                 goto out;
930                         }
931                 }
932                 key = *next_key_p;
933                 cur_key_p = &key;
934                 next_key_p = &next_key;
935         }
936         if (errno != ENOENT)
937                 err = -1;
938
939 out:
940         free(val_buf1);
941         free(val_buf2);
942         return err;
943 }
944
945 static void test_stacktrace_map()
946 {
947         int control_map_fd, stackid_hmap_fd, stackmap_fd, stack_amap_fd;
948         const char *file = "./test_stacktrace_map.o";
949         int bytes, efd, err, pmu_fd, prog_fd, stack_trace_len;
950         struct perf_event_attr attr = {};
951         __u32 key, val, duration = 0;
952         struct bpf_object *obj;
953         char buf[256];
954
955         err = bpf_prog_load(file, BPF_PROG_TYPE_TRACEPOINT, &obj, &prog_fd);
956         if (CHECK(err, "prog_load", "err %d errno %d\n", err, errno))
957                 return;
958
959         /* Get the ID for the sched/sched_switch tracepoint */
960         snprintf(buf, sizeof(buf),
961                  "/sys/kernel/debug/tracing/events/sched/sched_switch/id");
962         efd = open(buf, O_RDONLY, 0);
963         if (CHECK(efd < 0, "open", "err %d errno %d\n", efd, errno))
964                 goto close_prog;
965
966         bytes = read(efd, buf, sizeof(buf));
967         close(efd);
968         if (bytes <= 0 || bytes >= sizeof(buf))
969                 goto close_prog;
970
971         /* Open the perf event and attach bpf progrram */
972         attr.config = strtol(buf, NULL, 0);
973         attr.type = PERF_TYPE_TRACEPOINT;
974         attr.sample_type = PERF_SAMPLE_RAW | PERF_SAMPLE_CALLCHAIN;
975         attr.sample_period = 1;
976         attr.wakeup_events = 1;
977         pmu_fd = syscall(__NR_perf_event_open, &attr, -1 /* pid */,
978                          0 /* cpu 0 */, -1 /* group id */,
979                          0 /* flags */);
980         if (CHECK(pmu_fd < 0, "perf_event_open", "err %d errno %d\n",
981                   pmu_fd, errno))
982                 goto close_prog;
983
984         err = ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0);
985         if (err)
986                 goto disable_pmu;
987
988         err = ioctl(pmu_fd, PERF_EVENT_IOC_SET_BPF, prog_fd);
989         if (err)
990                 goto disable_pmu;
991
992         /* find map fds */
993         control_map_fd = bpf_find_map(__func__, obj, "control_map");
994         if (control_map_fd < 0)
995                 goto disable_pmu;
996
997         stackid_hmap_fd = bpf_find_map(__func__, obj, "stackid_hmap");
998         if (stackid_hmap_fd < 0)
999                 goto disable_pmu;
1000
1001         stackmap_fd = bpf_find_map(__func__, obj, "stackmap");
1002         if (stackmap_fd < 0)
1003                 goto disable_pmu;
1004
1005         stack_amap_fd = bpf_find_map(__func__, obj, "stack_amap");
1006         if (stack_amap_fd < 0)
1007                 goto disable_pmu;
1008
1009         /* give some time for bpf program run */
1010         sleep(1);
1011
1012         /* disable stack trace collection */
1013         key = 0;
1014         val = 1;
1015         bpf_map_update_elem(control_map_fd, &key, &val, 0);
1016
1017         /* for every element in stackid_hmap, we can find a corresponding one
1018          * in stackmap, and vise versa.
1019          */
1020         err = compare_map_keys(stackid_hmap_fd, stackmap_fd);
1021         if (CHECK(err, "compare_map_keys stackid_hmap vs. stackmap",
1022                   "err %d errno %d\n", err, errno))
1023                 goto disable_pmu_noerr;
1024
1025         err = compare_map_keys(stackmap_fd, stackid_hmap_fd);
1026         if (CHECK(err, "compare_map_keys stackmap vs. stackid_hmap",
1027                   "err %d errno %d\n", err, errno))
1028                 goto disable_pmu_noerr;
1029
1030         stack_trace_len = PERF_MAX_STACK_DEPTH * sizeof(__u64);
1031         err = compare_stack_ips(stackmap_fd, stack_amap_fd, stack_trace_len);
1032         if (CHECK(err, "compare_stack_ips stackmap vs. stack_amap",
1033                   "err %d errno %d\n", err, errno))
1034                 goto disable_pmu_noerr;
1035
1036         goto disable_pmu_noerr;
1037 disable_pmu:
1038         error_cnt++;
1039 disable_pmu_noerr:
1040         ioctl(pmu_fd, PERF_EVENT_IOC_DISABLE);
1041         close(pmu_fd);
1042 close_prog:
1043         bpf_object__close(obj);
1044 }
1045
1046 static void test_stacktrace_map_raw_tp()
1047 {
1048         int control_map_fd, stackid_hmap_fd, stackmap_fd;
1049         const char *file = "./test_stacktrace_map.o";
1050         int efd, err, prog_fd;
1051         __u32 key, val, duration = 0;
1052         struct bpf_object *obj;
1053
1054         err = bpf_prog_load(file, BPF_PROG_TYPE_RAW_TRACEPOINT, &obj, &prog_fd);
1055         if (CHECK(err, "prog_load raw tp", "err %d errno %d\n", err, errno))
1056                 return;
1057
1058         efd = bpf_raw_tracepoint_open("sched_switch", prog_fd);
1059         if (CHECK(efd < 0, "raw_tp_open", "err %d errno %d\n", efd, errno))
1060                 goto close_prog;
1061
1062         /* find map fds */
1063         control_map_fd = bpf_find_map(__func__, obj, "control_map");
1064         if (control_map_fd < 0)
1065                 goto close_prog;
1066
1067         stackid_hmap_fd = bpf_find_map(__func__, obj, "stackid_hmap");
1068         if (stackid_hmap_fd < 0)
1069                 goto close_prog;
1070
1071         stackmap_fd = bpf_find_map(__func__, obj, "stackmap");
1072         if (stackmap_fd < 0)
1073                 goto close_prog;
1074
1075         /* give some time for bpf program run */
1076         sleep(1);
1077
1078         /* disable stack trace collection */
1079         key = 0;
1080         val = 1;
1081         bpf_map_update_elem(control_map_fd, &key, &val, 0);
1082
1083         /* for every element in stackid_hmap, we can find a corresponding one
1084          * in stackmap, and vise versa.
1085          */
1086         err = compare_map_keys(stackid_hmap_fd, stackmap_fd);
1087         if (CHECK(err, "compare_map_keys stackid_hmap vs. stackmap",
1088                   "err %d errno %d\n", err, errno))
1089                 goto close_prog;
1090
1091         err = compare_map_keys(stackmap_fd, stackid_hmap_fd);
1092         if (CHECK(err, "compare_map_keys stackmap vs. stackid_hmap",
1093                   "err %d errno %d\n", err, errno))
1094                 goto close_prog;
1095
1096         goto close_prog_noerr;
1097 close_prog:
1098         error_cnt++;
1099 close_prog_noerr:
1100         bpf_object__close(obj);
1101 }
1102
1103 static int extract_build_id(char *build_id, size_t size)
1104 {
1105         FILE *fp;
1106         char *line = NULL;
1107         size_t len = 0;
1108
1109         fp = popen("readelf -n ./urandom_read | grep 'Build ID'", "r");
1110         if (fp == NULL)
1111                 return -1;
1112
1113         if (getline(&line, &len, fp) == -1)
1114                 goto err;
1115         fclose(fp);
1116
1117         if (len > size)
1118                 len = size;
1119         memcpy(build_id, line, len);
1120         build_id[len] = '\0';
1121         return 0;
1122 err:
1123         fclose(fp);
1124         return -1;
1125 }
1126
1127 static void test_stacktrace_build_id(void)
1128 {
1129         int control_map_fd, stackid_hmap_fd, stackmap_fd, stack_amap_fd;
1130         const char *file = "./test_stacktrace_build_id.o";
1131         int bytes, efd, err, pmu_fd, prog_fd, stack_trace_len;
1132         struct perf_event_attr attr = {};
1133         __u32 key, previous_key, val, duration = 0;
1134         struct bpf_object *obj;
1135         char buf[256];
1136         int i, j;
1137         struct bpf_stack_build_id id_offs[PERF_MAX_STACK_DEPTH];
1138         int build_id_matches = 0;
1139
1140         err = bpf_prog_load(file, BPF_PROG_TYPE_TRACEPOINT, &obj, &prog_fd);
1141         if (CHECK(err, "prog_load", "err %d errno %d\n", err, errno))
1142                 goto out;
1143
1144         /* Get the ID for the sched/sched_switch tracepoint */
1145         snprintf(buf, sizeof(buf),
1146                  "/sys/kernel/debug/tracing/events/random/urandom_read/id");
1147         efd = open(buf, O_RDONLY, 0);
1148         if (CHECK(efd < 0, "open", "err %d errno %d\n", efd, errno))
1149                 goto close_prog;
1150
1151         bytes = read(efd, buf, sizeof(buf));
1152         close(efd);
1153         if (CHECK(bytes <= 0 || bytes >= sizeof(buf),
1154                   "read", "bytes %d errno %d\n", bytes, errno))
1155                 goto close_prog;
1156
1157         /* Open the perf event and attach bpf progrram */
1158         attr.config = strtol(buf, NULL, 0);
1159         attr.type = PERF_TYPE_TRACEPOINT;
1160         attr.sample_type = PERF_SAMPLE_RAW | PERF_SAMPLE_CALLCHAIN;
1161         attr.sample_period = 1;
1162         attr.wakeup_events = 1;
1163         pmu_fd = syscall(__NR_perf_event_open, &attr, -1 /* pid */,
1164                          0 /* cpu 0 */, -1 /* group id */,
1165                          0 /* flags */);
1166         if (CHECK(pmu_fd < 0, "perf_event_open", "err %d errno %d\n",
1167                   pmu_fd, errno))
1168                 goto close_prog;
1169
1170         err = ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0);
1171         if (CHECK(err, "perf_event_ioc_enable", "err %d errno %d\n",
1172                   err, errno))
1173                 goto close_pmu;
1174
1175         err = ioctl(pmu_fd, PERF_EVENT_IOC_SET_BPF, prog_fd);
1176         if (CHECK(err, "perf_event_ioc_set_bpf", "err %d errno %d\n",
1177                   err, errno))
1178                 goto disable_pmu;
1179
1180         /* find map fds */
1181         control_map_fd = bpf_find_map(__func__, obj, "control_map");
1182         if (CHECK(control_map_fd < 0, "bpf_find_map control_map",
1183                   "err %d errno %d\n", err, errno))
1184                 goto disable_pmu;
1185
1186         stackid_hmap_fd = bpf_find_map(__func__, obj, "stackid_hmap");
1187         if (CHECK(stackid_hmap_fd < 0, "bpf_find_map stackid_hmap",
1188                   "err %d errno %d\n", err, errno))
1189                 goto disable_pmu;
1190
1191         stackmap_fd = bpf_find_map(__func__, obj, "stackmap");
1192         if (CHECK(stackmap_fd < 0, "bpf_find_map stackmap", "err %d errno %d\n",
1193                   err, errno))
1194                 goto disable_pmu;
1195
1196         stack_amap_fd = bpf_find_map(__func__, obj, "stack_amap");
1197         if (CHECK(stack_amap_fd < 0, "bpf_find_map stack_amap",
1198                   "err %d errno %d\n", err, errno))
1199                 goto disable_pmu;
1200
1201         assert(system("dd if=/dev/urandom of=/dev/zero count=4 2> /dev/null")
1202                == 0);
1203         assert(system("./urandom_read") == 0);
1204         /* disable stack trace collection */
1205         key = 0;
1206         val = 1;
1207         bpf_map_update_elem(control_map_fd, &key, &val, 0);
1208
1209         /* for every element in stackid_hmap, we can find a corresponding one
1210          * in stackmap, and vise versa.
1211          */
1212         err = compare_map_keys(stackid_hmap_fd, stackmap_fd);
1213         if (CHECK(err, "compare_map_keys stackid_hmap vs. stackmap",
1214                   "err %d errno %d\n", err, errno))
1215                 goto disable_pmu;
1216
1217         err = compare_map_keys(stackmap_fd, stackid_hmap_fd);
1218         if (CHECK(err, "compare_map_keys stackmap vs. stackid_hmap",
1219                   "err %d errno %d\n", err, errno))
1220                 goto disable_pmu;
1221
1222         err = extract_build_id(buf, 256);
1223
1224         if (CHECK(err, "get build_id with readelf",
1225                   "err %d errno %d\n", err, errno))
1226                 goto disable_pmu;
1227
1228         err = bpf_map_get_next_key(stackmap_fd, NULL, &key);
1229         if (CHECK(err, "get_next_key from stackmap",
1230                   "err %d, errno %d\n", err, errno))
1231                 goto disable_pmu;
1232
1233         do {
1234                 char build_id[64];
1235
1236                 err = bpf_map_lookup_elem(stackmap_fd, &key, id_offs);
1237                 if (CHECK(err, "lookup_elem from stackmap",
1238                           "err %d, errno %d\n", err, errno))
1239                         goto disable_pmu;
1240                 for (i = 0; i < PERF_MAX_STACK_DEPTH; ++i)
1241                         if (id_offs[i].status == BPF_STACK_BUILD_ID_VALID &&
1242                             id_offs[i].offset != 0) {
1243                                 for (j = 0; j < 20; ++j)
1244                                         sprintf(build_id + 2 * j, "%02x",
1245                                                 id_offs[i].build_id[j] & 0xff);
1246                                 if (strstr(buf, build_id) != NULL)
1247                                         build_id_matches = 1;
1248                         }
1249                 previous_key = key;
1250         } while (bpf_map_get_next_key(stackmap_fd, &previous_key, &key) == 0);
1251
1252         if (CHECK(build_id_matches < 1, "build id match",
1253                   "Didn't find expected build ID from the map\n"))
1254                 goto disable_pmu;
1255
1256         stack_trace_len = PERF_MAX_STACK_DEPTH
1257                 * sizeof(struct bpf_stack_build_id);
1258         err = compare_stack_ips(stackmap_fd, stack_amap_fd, stack_trace_len);
1259         CHECK(err, "compare_stack_ips stackmap vs. stack_amap",
1260               "err %d errno %d\n", err, errno);
1261
1262 disable_pmu:
1263         ioctl(pmu_fd, PERF_EVENT_IOC_DISABLE);
1264
1265 close_pmu:
1266         close(pmu_fd);
1267
1268 close_prog:
1269         bpf_object__close(obj);
1270
1271 out:
1272         return;
1273 }
1274
1275 static void test_stacktrace_build_id_nmi(void)
1276 {
1277         int control_map_fd, stackid_hmap_fd, stackmap_fd, stack_amap_fd;
1278         const char *file = "./test_stacktrace_build_id.o";
1279         int err, pmu_fd, prog_fd;
1280         struct perf_event_attr attr = {
1281                 .sample_freq = 5000,
1282                 .freq = 1,
1283                 .type = PERF_TYPE_HARDWARE,
1284                 .config = PERF_COUNT_HW_CPU_CYCLES,
1285         };
1286         __u32 key, previous_key, val, duration = 0;
1287         struct bpf_object *obj;
1288         char buf[256];
1289         int i, j;
1290         struct bpf_stack_build_id id_offs[PERF_MAX_STACK_DEPTH];
1291         int build_id_matches = 0;
1292
1293         err = bpf_prog_load(file, BPF_PROG_TYPE_PERF_EVENT, &obj, &prog_fd);
1294         if (CHECK(err, "prog_load", "err %d errno %d\n", err, errno))
1295                 return;
1296
1297         pmu_fd = syscall(__NR_perf_event_open, &attr, -1 /* pid */,
1298                          0 /* cpu 0 */, -1 /* group id */,
1299                          0 /* flags */);
1300         if (CHECK(pmu_fd < 0, "perf_event_open",
1301                   "err %d errno %d. Does the test host support PERF_COUNT_HW_CPU_CYCLES?\n",
1302                   pmu_fd, errno))
1303                 goto close_prog;
1304
1305         err = ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0);
1306         if (CHECK(err, "perf_event_ioc_enable", "err %d errno %d\n",
1307                   err, errno))
1308                 goto close_pmu;
1309
1310         err = ioctl(pmu_fd, PERF_EVENT_IOC_SET_BPF, prog_fd);
1311         if (CHECK(err, "perf_event_ioc_set_bpf", "err %d errno %d\n",
1312                   err, errno))
1313                 goto disable_pmu;
1314
1315         /* find map fds */
1316         control_map_fd = bpf_find_map(__func__, obj, "control_map");
1317         if (CHECK(control_map_fd < 0, "bpf_find_map control_map",
1318                   "err %d errno %d\n", err, errno))
1319                 goto disable_pmu;
1320
1321         stackid_hmap_fd = bpf_find_map(__func__, obj, "stackid_hmap");
1322         if (CHECK(stackid_hmap_fd < 0, "bpf_find_map stackid_hmap",
1323                   "err %d errno %d\n", err, errno))
1324                 goto disable_pmu;
1325
1326         stackmap_fd = bpf_find_map(__func__, obj, "stackmap");
1327         if (CHECK(stackmap_fd < 0, "bpf_find_map stackmap", "err %d errno %d\n",
1328                   err, errno))
1329                 goto disable_pmu;
1330
1331         stack_amap_fd = bpf_find_map(__func__, obj, "stack_amap");
1332         if (CHECK(stack_amap_fd < 0, "bpf_find_map stack_amap",
1333                   "err %d errno %d\n", err, errno))
1334                 goto disable_pmu;
1335
1336         assert(system("dd if=/dev/urandom of=/dev/zero count=4 2> /dev/null")
1337                == 0);
1338         assert(system("taskset 0x1 ./urandom_read 100000") == 0);
1339         /* disable stack trace collection */
1340         key = 0;
1341         val = 1;
1342         bpf_map_update_elem(control_map_fd, &key, &val, 0);
1343
1344         /* for every element in stackid_hmap, we can find a corresponding one
1345          * in stackmap, and vise versa.
1346          */
1347         err = compare_map_keys(stackid_hmap_fd, stackmap_fd);
1348         if (CHECK(err, "compare_map_keys stackid_hmap vs. stackmap",
1349                   "err %d errno %d\n", err, errno))
1350                 goto disable_pmu;
1351
1352         err = compare_map_keys(stackmap_fd, stackid_hmap_fd);
1353         if (CHECK(err, "compare_map_keys stackmap vs. stackid_hmap",
1354                   "err %d errno %d\n", err, errno))
1355                 goto disable_pmu;
1356
1357         err = extract_build_id(buf, 256);
1358
1359         if (CHECK(err, "get build_id with readelf",
1360                   "err %d errno %d\n", err, errno))
1361                 goto disable_pmu;
1362
1363         err = bpf_map_get_next_key(stackmap_fd, NULL, &key);
1364         if (CHECK(err, "get_next_key from stackmap",
1365                   "err %d, errno %d\n", err, errno))
1366                 goto disable_pmu;
1367
1368         do {
1369                 char build_id[64];
1370
1371                 err = bpf_map_lookup_elem(stackmap_fd, &key, id_offs);
1372                 if (CHECK(err, "lookup_elem from stackmap",
1373                           "err %d, errno %d\n", err, errno))
1374                         goto disable_pmu;
1375                 for (i = 0; i < PERF_MAX_STACK_DEPTH; ++i)
1376                         if (id_offs[i].status == BPF_STACK_BUILD_ID_VALID &&
1377                             id_offs[i].offset != 0) {
1378                                 for (j = 0; j < 20; ++j)
1379                                         sprintf(build_id + 2 * j, "%02x",
1380                                                 id_offs[i].build_id[j] & 0xff);
1381                                 if (strstr(buf, build_id) != NULL)
1382                                         build_id_matches = 1;
1383                         }
1384                 previous_key = key;
1385         } while (bpf_map_get_next_key(stackmap_fd, &previous_key, &key) == 0);
1386
1387         if (CHECK(build_id_matches < 1, "build id match",
1388                   "Didn't find expected build ID from the map\n"))
1389                 goto disable_pmu;
1390
1391         /*
1392          * We intentionally skip compare_stack_ips(). This is because we
1393          * only support one in_nmi() ips-to-build_id translation per cpu
1394          * at any time, thus stack_amap here will always fallback to
1395          * BPF_STACK_BUILD_ID_IP;
1396          */
1397
1398 disable_pmu:
1399         ioctl(pmu_fd, PERF_EVENT_IOC_DISABLE);
1400
1401 close_pmu:
1402         close(pmu_fd);
1403
1404 close_prog:
1405         bpf_object__close(obj);
1406 }
1407
1408 #define MAX_CNT_RAWTP   10ull
1409 #define MAX_STACK_RAWTP 100
1410 struct get_stack_trace_t {
1411         int pid;
1412         int kern_stack_size;
1413         int user_stack_size;
1414         int user_stack_buildid_size;
1415         __u64 kern_stack[MAX_STACK_RAWTP];
1416         __u64 user_stack[MAX_STACK_RAWTP];
1417         struct bpf_stack_build_id user_stack_buildid[MAX_STACK_RAWTP];
1418 };
1419
1420 static int get_stack_print_output(void *data, int size)
1421 {
1422         bool good_kern_stack = false, good_user_stack = false;
1423         const char *nonjit_func = "___bpf_prog_run";
1424         struct get_stack_trace_t *e = data;
1425         int i, num_stack;
1426         static __u64 cnt;
1427         struct ksym *ks;
1428
1429         cnt++;
1430
1431         if (size < sizeof(struct get_stack_trace_t)) {
1432                 __u64 *raw_data = data;
1433                 bool found = false;
1434
1435                 num_stack = size / sizeof(__u64);
1436                 /* If jit is enabled, we do not have a good way to
1437                  * verify the sanity of the kernel stack. So we
1438                  * just assume it is good if the stack is not empty.
1439                  * This could be improved in the future.
1440                  */
1441                 if (jit_enabled) {
1442                         found = num_stack > 0;
1443                 } else {
1444                         for (i = 0; i < num_stack; i++) {
1445                                 ks = ksym_search(raw_data[i]);
1446                                 if (strcmp(ks->name, nonjit_func) == 0) {
1447                                         found = true;
1448                                         break;
1449                                 }
1450                         }
1451                 }
1452                 if (found) {
1453                         good_kern_stack = true;
1454                         good_user_stack = true;
1455                 }
1456         } else {
1457                 num_stack = e->kern_stack_size / sizeof(__u64);
1458                 if (jit_enabled) {
1459                         good_kern_stack = num_stack > 0;
1460                 } else {
1461                         for (i = 0; i < num_stack; i++) {
1462                                 ks = ksym_search(e->kern_stack[i]);
1463                                 if (strcmp(ks->name, nonjit_func) == 0) {
1464                                         good_kern_stack = true;
1465                                         break;
1466                                 }
1467                         }
1468                 }
1469                 if (e->user_stack_size > 0 && e->user_stack_buildid_size > 0)
1470                         good_user_stack = true;
1471         }
1472         if (!good_kern_stack || !good_user_stack)
1473                 return LIBBPF_PERF_EVENT_ERROR;
1474
1475         if (cnt == MAX_CNT_RAWTP)
1476                 return LIBBPF_PERF_EVENT_DONE;
1477
1478         return LIBBPF_PERF_EVENT_CONT;
1479 }
1480
1481 static void test_get_stack_raw_tp(void)
1482 {
1483         const char *file = "./test_get_stack_rawtp.o";
1484         int i, efd, err, prog_fd, pmu_fd, perfmap_fd;
1485         struct perf_event_attr attr = {};
1486         struct timespec tv = {0, 10};
1487         __u32 key = 0, duration = 0;
1488         struct bpf_object *obj;
1489
1490         err = bpf_prog_load(file, BPF_PROG_TYPE_RAW_TRACEPOINT, &obj, &prog_fd);
1491         if (CHECK(err, "prog_load raw tp", "err %d errno %d\n", err, errno))
1492                 return;
1493
1494         efd = bpf_raw_tracepoint_open("sys_enter", prog_fd);
1495         if (CHECK(efd < 0, "raw_tp_open", "err %d errno %d\n", efd, errno))
1496                 goto close_prog;
1497
1498         perfmap_fd = bpf_find_map(__func__, obj, "perfmap");
1499         if (CHECK(perfmap_fd < 0, "bpf_find_map", "err %d errno %d\n",
1500                   perfmap_fd, errno))
1501                 goto close_prog;
1502
1503         err = load_kallsyms();
1504         if (CHECK(err < 0, "load_kallsyms", "err %d errno %d\n", err, errno))
1505                 goto close_prog;
1506
1507         attr.sample_type = PERF_SAMPLE_RAW;
1508         attr.type = PERF_TYPE_SOFTWARE;
1509         attr.config = PERF_COUNT_SW_BPF_OUTPUT;
1510         pmu_fd = syscall(__NR_perf_event_open, &attr, getpid()/*pid*/, -1/*cpu*/,
1511                          -1/*group_fd*/, 0);
1512         if (CHECK(pmu_fd < 0, "perf_event_open", "err %d errno %d\n", pmu_fd,
1513                   errno))
1514                 goto close_prog;
1515
1516         err = bpf_map_update_elem(perfmap_fd, &key, &pmu_fd, BPF_ANY);
1517         if (CHECK(err < 0, "bpf_map_update_elem", "err %d errno %d\n", err,
1518                   errno))
1519                 goto close_prog;
1520
1521         err = ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0);
1522         if (CHECK(err < 0, "ioctl PERF_EVENT_IOC_ENABLE", "err %d errno %d\n",
1523                   err, errno))
1524                 goto close_prog;
1525
1526         err = perf_event_mmap(pmu_fd);
1527         if (CHECK(err < 0, "perf_event_mmap", "err %d errno %d\n", err, errno))
1528                 goto close_prog;
1529
1530         /* trigger some syscall action */
1531         for (i = 0; i < MAX_CNT_RAWTP; i++)
1532                 nanosleep(&tv, NULL);
1533
1534         err = perf_event_poller(pmu_fd, get_stack_print_output);
1535         if (CHECK(err < 0, "perf_event_poller", "err %d errno %d\n", err, errno))
1536                 goto close_prog;
1537
1538         goto close_prog_noerr;
1539 close_prog:
1540         error_cnt++;
1541 close_prog_noerr:
1542         bpf_object__close(obj);
1543 }
1544
1545 static void test_task_fd_query_rawtp(void)
1546 {
1547         const char *file = "./test_get_stack_rawtp.o";
1548         __u64 probe_offset, probe_addr;
1549         __u32 len, prog_id, fd_type;
1550         struct bpf_object *obj;
1551         int efd, err, prog_fd;
1552         __u32 duration = 0;
1553         char buf[256];
1554
1555         err = bpf_prog_load(file, BPF_PROG_TYPE_RAW_TRACEPOINT, &obj, &prog_fd);
1556         if (CHECK(err, "prog_load raw tp", "err %d errno %d\n", err, errno))
1557                 return;
1558
1559         efd = bpf_raw_tracepoint_open("sys_enter", prog_fd);
1560         if (CHECK(efd < 0, "raw_tp_open", "err %d errno %d\n", efd, errno))
1561                 goto close_prog;
1562
1563         /* query (getpid(), efd) */
1564         len = sizeof(buf);
1565         err = bpf_task_fd_query(getpid(), efd, 0, buf, &len, &prog_id,
1566                                 &fd_type, &probe_offset, &probe_addr);
1567         if (CHECK(err < 0, "bpf_task_fd_query", "err %d errno %d\n", err,
1568                   errno))
1569                 goto close_prog;
1570
1571         err = fd_type == BPF_FD_TYPE_RAW_TRACEPOINT &&
1572               strcmp(buf, "sys_enter") == 0;
1573         if (CHECK(!err, "check_results", "fd_type %d tp_name %s\n",
1574                   fd_type, buf))
1575                 goto close_prog;
1576
1577         /* test zero len */
1578         len = 0;
1579         err = bpf_task_fd_query(getpid(), efd, 0, buf, &len, &prog_id,
1580                                 &fd_type, &probe_offset, &probe_addr);
1581         if (CHECK(err < 0, "bpf_task_fd_query (len = 0)", "err %d errno %d\n",
1582                   err, errno))
1583                 goto close_prog;
1584         err = fd_type == BPF_FD_TYPE_RAW_TRACEPOINT &&
1585               len == strlen("sys_enter");
1586         if (CHECK(!err, "check_results", "fd_type %d len %u\n", fd_type, len))
1587                 goto close_prog;
1588
1589         /* test empty buffer */
1590         len = sizeof(buf);
1591         err = bpf_task_fd_query(getpid(), efd, 0, 0, &len, &prog_id,
1592                                 &fd_type, &probe_offset, &probe_addr);
1593         if (CHECK(err < 0, "bpf_task_fd_query (buf = 0)", "err %d errno %d\n",
1594                   err, errno))
1595                 goto close_prog;
1596         err = fd_type == BPF_FD_TYPE_RAW_TRACEPOINT &&
1597               len == strlen("sys_enter");
1598         if (CHECK(!err, "check_results", "fd_type %d len %u\n", fd_type, len))
1599                 goto close_prog;
1600
1601         /* test smaller buffer */
1602         len = 3;
1603         err = bpf_task_fd_query(getpid(), efd, 0, buf, &len, &prog_id,
1604                                 &fd_type, &probe_offset, &probe_addr);
1605         if (CHECK(err >= 0 || errno != ENOSPC, "bpf_task_fd_query (len = 3)",
1606                   "err %d errno %d\n", err, errno))
1607                 goto close_prog;
1608         err = fd_type == BPF_FD_TYPE_RAW_TRACEPOINT &&
1609               len == strlen("sys_enter") &&
1610               strcmp(buf, "sy") == 0;
1611         if (CHECK(!err, "check_results", "fd_type %d len %u\n", fd_type, len))
1612                 goto close_prog;
1613
1614         goto close_prog_noerr;
1615 close_prog:
1616         error_cnt++;
1617 close_prog_noerr:
1618         bpf_object__close(obj);
1619 }
1620
1621 static void test_task_fd_query_tp_core(const char *probe_name,
1622                                        const char *tp_name)
1623 {
1624         const char *file = "./test_tracepoint.o";
1625         int err, bytes, efd, prog_fd, pmu_fd;
1626         struct perf_event_attr attr = {};
1627         __u64 probe_offset, probe_addr;
1628         __u32 len, prog_id, fd_type;
1629         struct bpf_object *obj;
1630         __u32 duration = 0;
1631         char buf[256];
1632
1633         err = bpf_prog_load(file, BPF_PROG_TYPE_TRACEPOINT, &obj, &prog_fd);
1634         if (CHECK(err, "bpf_prog_load", "err %d errno %d\n", err, errno))
1635                 goto close_prog;
1636
1637         snprintf(buf, sizeof(buf),
1638                  "/sys/kernel/debug/tracing/events/%s/id", probe_name);
1639         efd = open(buf, O_RDONLY, 0);
1640         if (CHECK(efd < 0, "open", "err %d errno %d\n", efd, errno))
1641                 goto close_prog;
1642         bytes = read(efd, buf, sizeof(buf));
1643         close(efd);
1644         if (CHECK(bytes <= 0 || bytes >= sizeof(buf), "read",
1645                   "bytes %d errno %d\n", bytes, errno))
1646                 goto close_prog;
1647
1648         attr.config = strtol(buf, NULL, 0);
1649         attr.type = PERF_TYPE_TRACEPOINT;
1650         attr.sample_type = PERF_SAMPLE_RAW;
1651         attr.sample_period = 1;
1652         attr.wakeup_events = 1;
1653         pmu_fd = syscall(__NR_perf_event_open, &attr, -1 /* pid */,
1654                          0 /* cpu 0 */, -1 /* group id */,
1655                          0 /* flags */);
1656         if (CHECK(err, "perf_event_open", "err %d errno %d\n", err, errno))
1657                 goto close_pmu;
1658
1659         err = ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0);
1660         if (CHECK(err, "perf_event_ioc_enable", "err %d errno %d\n", err,
1661                   errno))
1662                 goto close_pmu;
1663
1664         err = ioctl(pmu_fd, PERF_EVENT_IOC_SET_BPF, prog_fd);
1665         if (CHECK(err, "perf_event_ioc_set_bpf", "err %d errno %d\n", err,
1666                   errno))
1667                 goto close_pmu;
1668
1669         /* query (getpid(), pmu_fd) */
1670         len = sizeof(buf);
1671         err = bpf_task_fd_query(getpid(), pmu_fd, 0, buf, &len, &prog_id,
1672                                 &fd_type, &probe_offset, &probe_addr);
1673         if (CHECK(err < 0, "bpf_task_fd_query", "err %d errno %d\n", err,
1674                   errno))
1675                 goto close_pmu;
1676
1677         err = (fd_type == BPF_FD_TYPE_TRACEPOINT) && !strcmp(buf, tp_name);
1678         if (CHECK(!err, "check_results", "fd_type %d tp_name %s\n",
1679                   fd_type, buf))
1680                 goto close_pmu;
1681
1682         close(pmu_fd);
1683         goto close_prog_noerr;
1684
1685 close_pmu:
1686         close(pmu_fd);
1687 close_prog:
1688         error_cnt++;
1689 close_prog_noerr:
1690         bpf_object__close(obj);
1691 }
1692
1693 static void test_task_fd_query_tp(void)
1694 {
1695         test_task_fd_query_tp_core("sched/sched_switch",
1696                                    "sched_switch");
1697         test_task_fd_query_tp_core("syscalls/sys_enter_read",
1698                                    "sys_enter_read");
1699 }
1700
1701 static void test_reference_tracking()
1702 {
1703         const char *file = "./test_sk_lookup_kern.o";
1704         struct bpf_object *obj;
1705         struct bpf_program *prog;
1706         __u32 duration;
1707         int err = 0;
1708
1709         obj = bpf_object__open(file);
1710         if (IS_ERR(obj)) {
1711                 error_cnt++;
1712                 return;
1713         }
1714
1715         bpf_object__for_each_program(prog, obj) {
1716                 const char *title;
1717
1718                 /* Ignore .text sections */
1719                 title = bpf_program__title(prog, false);
1720                 if (strstr(title, ".text") != NULL)
1721                         continue;
1722
1723                 bpf_program__set_type(prog, BPF_PROG_TYPE_SCHED_CLS);
1724
1725                 /* Expect verifier failure if test name has 'fail' */
1726                 if (strstr(title, "fail") != NULL) {
1727                         libbpf_set_print(NULL, NULL, NULL);
1728                         err = !bpf_program__load(prog, "GPL", 0);
1729                         libbpf_set_print(printf, printf, NULL);
1730                 } else {
1731                         err = bpf_program__load(prog, "GPL", 0);
1732                 }
1733                 CHECK(err, title, "\n");
1734         }
1735         bpf_object__close(obj);
1736 }
1737
1738 enum {
1739         QUEUE,
1740         STACK,
1741 };
1742
1743 static void test_queue_stack_map(int type)
1744 {
1745         const int MAP_SIZE = 32;
1746         __u32 vals[MAP_SIZE], duration, retval, size, val;
1747         int i, err, prog_fd, map_in_fd, map_out_fd;
1748         char file[32], buf[128];
1749         struct bpf_object *obj;
1750         struct iphdr *iph = (void *)buf + sizeof(struct ethhdr);
1751
1752         /* Fill test values to be used */
1753         for (i = 0; i < MAP_SIZE; i++)
1754                 vals[i] = rand();
1755
1756         if (type == QUEUE)
1757                 strncpy(file, "./test_queue_map.o", sizeof(file));
1758         else if (type == STACK)
1759                 strncpy(file, "./test_stack_map.o", sizeof(file));
1760         else
1761                 return;
1762
1763         err = bpf_prog_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd);
1764         if (err) {
1765                 error_cnt++;
1766                 return;
1767         }
1768
1769         map_in_fd = bpf_find_map(__func__, obj, "map_in");
1770         if (map_in_fd < 0)
1771                 goto out;
1772
1773         map_out_fd = bpf_find_map(__func__, obj, "map_out");
1774         if (map_out_fd < 0)
1775                 goto out;
1776
1777         /* Push 32 elements to the input map */
1778         for (i = 0; i < MAP_SIZE; i++) {
1779                 err = bpf_map_update_elem(map_in_fd, NULL, &vals[i], 0);
1780                 if (err) {
1781                         error_cnt++;
1782                         goto out;
1783                 }
1784         }
1785
1786         /* The eBPF program pushes iph.saddr in the output map,
1787          * pops the input map and saves this value in iph.daddr
1788          */
1789         for (i = 0; i < MAP_SIZE; i++) {
1790                 if (type == QUEUE) {
1791                         val = vals[i];
1792                         pkt_v4.iph.saddr = vals[i] * 5;
1793                 } else if (type == STACK) {
1794                         val = vals[MAP_SIZE - 1 - i];
1795                         pkt_v4.iph.saddr = vals[MAP_SIZE - 1 - i] * 5;
1796                 }
1797
1798                 err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4),
1799                                         buf, &size, &retval, &duration);
1800                 if (err || retval || size != sizeof(pkt_v4) ||
1801                     iph->daddr != val)
1802                         break;
1803         }
1804
1805         CHECK(err || retval || size != sizeof(pkt_v4) || iph->daddr != val,
1806               "bpf_map_pop_elem",
1807               "err %d errno %d retval %d size %d iph->daddr %u\n",
1808               err, errno, retval, size, iph->daddr);
1809
1810         /* Queue is empty, program should return TC_ACT_SHOT */
1811         err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4),
1812                                 buf, &size, &retval, &duration);
1813         CHECK(err || retval != 2 /* TC_ACT_SHOT */|| size != sizeof(pkt_v4),
1814               "check-queue-stack-map-empty",
1815               "err %d errno %d retval %d size %d\n",
1816               err, errno, retval, size);
1817
1818         /* Check that the program pushed elements correctly */
1819         for (i = 0; i < MAP_SIZE; i++) {
1820                 err = bpf_map_lookup_and_delete_elem(map_out_fd, NULL, &val);
1821                 if (err || val != vals[i] * 5)
1822                         break;
1823         }
1824
1825         CHECK(i != MAP_SIZE && (err || val != vals[i] * 5),
1826               "bpf_map_push_elem", "err %d value %u\n", err, val);
1827
1828 out:
1829         pkt_v4.iph.saddr = 0;
1830         bpf_object__close(obj);
1831 }
1832
1833 int main(void)
1834 {
1835         srand(time(NULL));
1836
1837         jit_enabled = is_jit_enabled();
1838
1839         test_pkt_access();
1840         test_xdp();
1841         test_xdp_adjust_tail();
1842         test_l4lb_all();
1843         test_xdp_noinline();
1844         test_tcp_estats();
1845         test_bpf_obj_id();
1846         test_pkt_md_access();
1847         test_obj_name();
1848         test_tp_attach_query();
1849         test_stacktrace_map();
1850         test_stacktrace_build_id();
1851         test_stacktrace_build_id_nmi();
1852         test_stacktrace_map_raw_tp();
1853         test_get_stack_raw_tp();
1854         test_task_fd_query_rawtp();
1855         test_task_fd_query_tp();
1856         test_reference_tracking();
1857         test_queue_stack_map(QUEUE);
1858         test_queue_stack_map(STACK);
1859
1860         printf("Summary: %d PASSED, %d FAILED\n", pass_cnt, error_cnt);
1861         return error_cnt ? EXIT_FAILURE : EXIT_SUCCESS;
1862 }