18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ci#include "util/bpf_map.h" 48c2ecf20Sopenharmony_ci#include <bpf/bpf.h> 58c2ecf20Sopenharmony_ci#include <bpf/libbpf.h> 68c2ecf20Sopenharmony_ci#include <linux/err.h> 78c2ecf20Sopenharmony_ci#include <linux/kernel.h> 88c2ecf20Sopenharmony_ci#include <stdbool.h> 98c2ecf20Sopenharmony_ci#include <stdlib.h> 108c2ecf20Sopenharmony_ci#include <unistd.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_cistatic bool bpf_map_def__is_per_cpu(const struct bpf_map_def *def) 138c2ecf20Sopenharmony_ci{ 148c2ecf20Sopenharmony_ci return def->type == BPF_MAP_TYPE_PERCPU_HASH || 158c2ecf20Sopenharmony_ci def->type == BPF_MAP_TYPE_PERCPU_ARRAY || 168c2ecf20Sopenharmony_ci def->type == BPF_MAP_TYPE_LRU_PERCPU_HASH || 178c2ecf20Sopenharmony_ci def->type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE; 188c2ecf20Sopenharmony_ci} 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_cistatic void *bpf_map_def__alloc_value(const struct bpf_map_def *def) 218c2ecf20Sopenharmony_ci{ 228c2ecf20Sopenharmony_ci if (bpf_map_def__is_per_cpu(def)) 238c2ecf20Sopenharmony_ci return malloc(round_up(def->value_size, 8) * sysconf(_SC_NPROCESSORS_CONF)); 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci return malloc(def->value_size); 268c2ecf20Sopenharmony_ci} 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ciint bpf_map__fprintf(struct bpf_map *map, FILE *fp) 298c2ecf20Sopenharmony_ci{ 308c2ecf20Sopenharmony_ci const struct bpf_map_def *def = bpf_map__def(map); 318c2ecf20Sopenharmony_ci void *prev_key = NULL, *key, *value; 328c2ecf20Sopenharmony_ci int fd = bpf_map__fd(map), err; 338c2ecf20Sopenharmony_ci int printed = 0; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci if (fd < 0) 368c2ecf20Sopenharmony_ci return fd; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci if (IS_ERR(def)) 398c2ecf20Sopenharmony_ci return PTR_ERR(def); 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci err = -ENOMEM; 428c2ecf20Sopenharmony_ci key = malloc(def->key_size); 438c2ecf20Sopenharmony_ci if (key == NULL) 448c2ecf20Sopenharmony_ci goto out; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci value = bpf_map_def__alloc_value(def); 478c2ecf20Sopenharmony_ci if (value == NULL) 488c2ecf20Sopenharmony_ci goto out_free_key; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci while ((err = bpf_map_get_next_key(fd, prev_key, key) == 0)) { 518c2ecf20Sopenharmony_ci int intkey = *(int *)key; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci if (!bpf_map_lookup_elem(fd, key, value)) { 548c2ecf20Sopenharmony_ci bool boolval = *(bool *)value; 558c2ecf20Sopenharmony_ci if (boolval) 568c2ecf20Sopenharmony_ci printed += fprintf(fp, "[%d] = %d,\n", intkey, boolval); 578c2ecf20Sopenharmony_ci } else { 588c2ecf20Sopenharmony_ci printed += fprintf(fp, "[%d] = ERROR,\n", intkey); 598c2ecf20Sopenharmony_ci } 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci prev_key = key; 628c2ecf20Sopenharmony_ci } 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci if (err == ENOENT) 658c2ecf20Sopenharmony_ci err = printed; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci free(value); 688c2ecf20Sopenharmony_ciout_free_key: 698c2ecf20Sopenharmony_ci free(key); 708c2ecf20Sopenharmony_ciout: 718c2ecf20Sopenharmony_ci return err; 728c2ecf20Sopenharmony_ci} 73