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 "test_progs.h" 8 #include "bpf_rlimit.h" 9 10 int error_cnt, pass_cnt; 11 bool jit_enabled; 12 bool verifier_stats = false; 13 14 struct ipv4_packet pkt_v4 = { 15 .eth.h_proto = __bpf_constant_htons(ETH_P_IP), 16 .iph.ihl = 5, 17 .iph.protocol = IPPROTO_TCP, 18 .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES), 19 .tcp.urg_ptr = 123, 20 .tcp.doff = 5, 21 }; 22 23 struct ipv6_packet pkt_v6 = { 24 .eth.h_proto = __bpf_constant_htons(ETH_P_IPV6), 25 .iph.nexthdr = IPPROTO_TCP, 26 .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES), 27 .tcp.urg_ptr = 123, 28 .tcp.doff = 5, 29 }; 30 31 int bpf_find_map(const char *test, struct bpf_object *obj, const char *name) 32 { 33 struct bpf_map *map; 34 35 map = bpf_object__find_map_by_name(obj, name); 36 if (!map) { 37 printf("%s:FAIL:map '%s' not found\n", test, name); 38 error_cnt++; 39 return -1; 40 } 41 return bpf_map__fd(map); 42 } 43 44 static bool is_jit_enabled(void) 45 { 46 const char *jit_sysctl = "/proc/sys/net/core/bpf_jit_enable"; 47 bool enabled = false; 48 int sysctl_fd; 49 50 sysctl_fd = open(jit_sysctl, 0, O_RDONLY); 51 if (sysctl_fd != -1) { 52 char tmpc; 53 54 if (read(sysctl_fd, &tmpc, sizeof(tmpc)) == 1) 55 enabled = (tmpc != '0'); 56 close(sysctl_fd); 57 } 58 59 return enabled; 60 } 61 62 int compare_map_keys(int map1_fd, int map2_fd) 63 { 64 __u32 key, next_key; 65 char val_buf[PERF_MAX_STACK_DEPTH * 66 sizeof(struct bpf_stack_build_id)]; 67 int err; 68 69 err = bpf_map_get_next_key(map1_fd, NULL, &key); 70 if (err) 71 return err; 72 err = bpf_map_lookup_elem(map2_fd, &key, val_buf); 73 if (err) 74 return err; 75 76 while (bpf_map_get_next_key(map1_fd, &key, &next_key) == 0) { 77 err = bpf_map_lookup_elem(map2_fd, &next_key, val_buf); 78 if (err) 79 return err; 80 81 key = next_key; 82 } 83 if (errno != ENOENT) 84 return -1; 85 86 return 0; 87 } 88 89 int compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len) 90 { 91 __u32 key, next_key, *cur_key_p, *next_key_p; 92 char *val_buf1, *val_buf2; 93 int i, err = 0; 94 95 val_buf1 = malloc(stack_trace_len); 96 val_buf2 = malloc(stack_trace_len); 97 cur_key_p = NULL; 98 next_key_p = &key; 99 while (bpf_map_get_next_key(smap_fd, cur_key_p, next_key_p) == 0) { 100 err = bpf_map_lookup_elem(smap_fd, next_key_p, val_buf1); 101 if (err) 102 goto out; 103 err = bpf_map_lookup_elem(amap_fd, next_key_p, val_buf2); 104 if (err) 105 goto out; 106 for (i = 0; i < stack_trace_len; i++) { 107 if (val_buf1[i] != val_buf2[i]) { 108 err = -1; 109 goto out; 110 } 111 } 112 key = *next_key_p; 113 cur_key_p = &key; 114 next_key_p = &next_key; 115 } 116 if (errno != ENOENT) 117 err = -1; 118 119 out: 120 free(val_buf1); 121 free(val_buf2); 122 return err; 123 } 124 125 int extract_build_id(char *build_id, size_t size) 126 { 127 FILE *fp; 128 char *line = NULL; 129 size_t len = 0; 130 131 fp = popen("readelf -n ./urandom_read | grep 'Build ID'", "r"); 132 if (fp == NULL) 133 return -1; 134 135 if (getline(&line, &len, fp) == -1) 136 goto err; 137 fclose(fp); 138 139 if (len > size) 140 len = size; 141 memcpy(build_id, line, len); 142 build_id[len] = '\0'; 143 return 0; 144 err: 145 fclose(fp); 146 return -1; 147 } 148 149 void *spin_lock_thread(void *arg) 150 { 151 __u32 duration, retval; 152 int err, prog_fd = *(u32 *) arg; 153 154 err = bpf_prog_test_run(prog_fd, 10000, &pkt_v4, sizeof(pkt_v4), 155 NULL, NULL, &retval, &duration); 156 CHECK(err || retval, "", 157 "err %d errno %d retval %d duration %d\n", 158 err, errno, retval, duration); 159 pthread_exit(arg); 160 } 161 162 #define DECLARE 163 #include <prog_tests/tests.h> 164 #undef DECLARE 165 166 int main(int ac, char **av) 167 { 168 srand(time(NULL)); 169 170 jit_enabled = is_jit_enabled(); 171 172 if (ac == 2 && strcmp(av[1], "-s") == 0) 173 verifier_stats = true; 174 175 #define CALL 176 #include <prog_tests/tests.h> 177 #undef CALL 178 179 printf("Summary: %d PASSED, %d FAILED\n", pass_cnt, error_cnt); 180 return error_cnt ? EXIT_FAILURE : EXIT_SUCCESS; 181 } 182