1*f74599f7SThomas Graf #include <linux/unistd.h> 2*f74599f7SThomas Graf #include <linux/bpf.h> 3*f74599f7SThomas Graf 4*f74599f7SThomas Graf #include <stdlib.h> 5*f74599f7SThomas Graf #include <stdio.h> 6*f74599f7SThomas Graf #include <unistd.h> 7*f74599f7SThomas Graf #include <string.h> 8*f74599f7SThomas Graf #include <errno.h> 9*f74599f7SThomas Graf #include <arpa/inet.h> 10*f74599f7SThomas Graf 11*f74599f7SThomas Graf #include "libbpf.h" 12*f74599f7SThomas Graf #include "bpf_util.h" 13*f74599f7SThomas Graf 14*f74599f7SThomas Graf #define MAX_INDEX 64 15*f74599f7SThomas Graf #define MAX_STARS 38 16*f74599f7SThomas Graf 17*f74599f7SThomas Graf static void stars(char *str, long val, long max, int width) 18*f74599f7SThomas Graf { 19*f74599f7SThomas Graf int i; 20*f74599f7SThomas Graf 21*f74599f7SThomas Graf for (i = 0; i < (width * val / max) - 1 && i < width - 1; i++) 22*f74599f7SThomas Graf str[i] = '*'; 23*f74599f7SThomas Graf if (val > max) 24*f74599f7SThomas Graf str[i - 1] = '+'; 25*f74599f7SThomas Graf str[i] = '\0'; 26*f74599f7SThomas Graf } 27*f74599f7SThomas Graf 28*f74599f7SThomas Graf int main(int argc, char **argv) 29*f74599f7SThomas Graf { 30*f74599f7SThomas Graf unsigned int nr_cpus = bpf_num_possible_cpus(); 31*f74599f7SThomas Graf const char *map_filename = "/sys/fs/bpf/tc/globals/lwt_len_hist_map"; 32*f74599f7SThomas Graf uint64_t values[nr_cpus], sum, max_value = 0, data[MAX_INDEX] = {}; 33*f74599f7SThomas Graf uint64_t key = 0, next_key, max_key = 0; 34*f74599f7SThomas Graf char starstr[MAX_STARS]; 35*f74599f7SThomas Graf int i, map_fd; 36*f74599f7SThomas Graf 37*f74599f7SThomas Graf map_fd = bpf_obj_get(map_filename); 38*f74599f7SThomas Graf if (map_fd < 0) { 39*f74599f7SThomas Graf fprintf(stderr, "bpf_obj_get(%s): %s(%d)\n", 40*f74599f7SThomas Graf map_filename, strerror(errno), errno); 41*f74599f7SThomas Graf return -1; 42*f74599f7SThomas Graf } 43*f74599f7SThomas Graf 44*f74599f7SThomas Graf while (bpf_get_next_key(map_fd, &key, &next_key) == 0) { 45*f74599f7SThomas Graf if (next_key >= MAX_INDEX) { 46*f74599f7SThomas Graf fprintf(stderr, "Key %lu out of bounds\n", next_key); 47*f74599f7SThomas Graf continue; 48*f74599f7SThomas Graf } 49*f74599f7SThomas Graf 50*f74599f7SThomas Graf bpf_lookup_elem(map_fd, &next_key, values); 51*f74599f7SThomas Graf 52*f74599f7SThomas Graf sum = 0; 53*f74599f7SThomas Graf for (i = 0; i < nr_cpus; i++) 54*f74599f7SThomas Graf sum += values[i]; 55*f74599f7SThomas Graf 56*f74599f7SThomas Graf data[next_key] = sum; 57*f74599f7SThomas Graf if (sum && next_key > max_key) 58*f74599f7SThomas Graf max_key = next_key; 59*f74599f7SThomas Graf 60*f74599f7SThomas Graf if (sum > max_value) 61*f74599f7SThomas Graf max_value = sum; 62*f74599f7SThomas Graf 63*f74599f7SThomas Graf key = next_key; 64*f74599f7SThomas Graf } 65*f74599f7SThomas Graf 66*f74599f7SThomas Graf for (i = 1; i <= max_key + 1; i++) { 67*f74599f7SThomas Graf stars(starstr, data[i - 1], max_value, MAX_STARS); 68*f74599f7SThomas Graf printf("%8ld -> %-8ld : %-8ld |%-*s|\n", 69*f74599f7SThomas Graf (1l << i) >> 1, (1l << i) - 1, data[i - 1], 70*f74599f7SThomas Graf MAX_STARS, starstr); 71*f74599f7SThomas Graf } 72*f74599f7SThomas Graf 73*f74599f7SThomas Graf close(map_fd); 74*f74599f7SThomas Graf 75*f74599f7SThomas Graf return 0; 76*f74599f7SThomas Graf } 77