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 <fcntl.h> 10 #include <stdlib.h> 11 #include <signal.h> 12 #include <linux/bpf.h> 13 #include <string.h> 14 #include <linux/perf_event.h> 15 #include <errno.h> 16 #include <assert.h> 17 #include <stdbool.h> 18 #include <sys/resource.h> 19 #include <bpf/bpf.h> 20 #include "bpf_load.h" 21 22 /* This program verifies bpf attachment to tracepoint sys_enter_* and sys_exit_*. 23 * This requires kernel CONFIG_FTRACE_SYSCALLS to be set. 24 */ 25 26 static void usage(const char *cmd) 27 { 28 printf("USAGE: %s [-i num_progs] [-h]\n", cmd); 29 printf(" -i num_progs # number of progs of the test\n"); 30 printf(" -h # help\n"); 31 } 32 33 static void verify_map(int map_id) 34 { 35 __u32 key = 0; 36 __u32 val; 37 38 if (bpf_map_lookup_elem(map_id, &key, &val) != 0) { 39 fprintf(stderr, "map_lookup failed: %s\n", strerror(errno)); 40 return; 41 } 42 if (val == 0) { 43 fprintf(stderr, "failed: map #%d returns value 0\n", map_id); 44 return; 45 } 46 val = 0; 47 if (bpf_map_update_elem(map_id, &key, &val, BPF_ANY) != 0) { 48 fprintf(stderr, "map_update failed: %s\n", strerror(errno)); 49 return; 50 } 51 } 52 53 static int test(char *filename, int num_progs) 54 { 55 int i, fd, map0_fds[num_progs], map1_fds[num_progs]; 56 57 for (i = 0; i < num_progs; i++) { 58 if (load_bpf_file(filename)) { 59 fprintf(stderr, "%s", bpf_log_buf); 60 return 1; 61 } 62 printf("prog #%d: map ids %d %d\n", i, map_fd[0], map_fd[1]); 63 map0_fds[i] = map_fd[0]; 64 map1_fds[i] = map_fd[1]; 65 } 66 67 /* current load_bpf_file has perf_event_open default pid = -1 68 * and cpu = 0, which permits attached bpf execution on 69 * all cpus for all pid's. bpf program execution ignores 70 * cpu affinity. 71 */ 72 /* trigger some "open" operations */ 73 fd = open(filename, O_RDONLY); 74 if (fd < 0) { 75 fprintf(stderr, "open failed: %s\n", strerror(errno)); 76 return 1; 77 } 78 close(fd); 79 80 /* verify the map */ 81 for (i = 0; i < num_progs; i++) { 82 verify_map(map0_fds[i]); 83 verify_map(map1_fds[i]); 84 } 85 86 return 0; 87 } 88 89 int main(int argc, char **argv) 90 { 91 struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; 92 int opt, num_progs = 1; 93 char filename[256]; 94 95 while ((opt = getopt(argc, argv, "i:h")) != -1) { 96 switch (opt) { 97 case 'i': 98 num_progs = atoi(optarg); 99 break; 100 case 'h': 101 default: 102 usage(argv[0]); 103 return 0; 104 } 105 } 106 107 setrlimit(RLIMIT_MEMLOCK, &r); 108 snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); 109 110 return test(filename, num_progs); 111 } 112